Phase 1 — Foundation
Phase 1 builds the complete Modern.js + Module Federation 2.0 foundation for the Aeroflot Flights Web rewrite. Nothing in Phase 1 ships to production users — the output is a working dual-build artifact (standalone SSR + MF 2.0 remote) with all observability, security, and CI pipelines live.
What Phase 1 shipped
Phase 1 consists of 14 sub-plans, each with its own implementation plan under docs/superpowers/plans/:
| ID | Sub-plan | Description |
|---|---|---|
| 1A-1 | Project skeleton | src/ tree, tsconfig, eslint base, zod-validated env config, package.json |
| 1A-2 | MF 2.0 + dual builds | Module Federation 2.0 config, standalone + remote build targets, RemoteLoader, MF spike |
| 1A-3 | ESLint boundaries | Layered dependency rules enforcing shared/ -> features/ -> routes/ direction |
| 1B | CI pipeline | GitHub Actions workflow: typecheck, lint, test, coverage, build, MF manifest validation, security audit |
| 1C | i18n runtime | i18next + ICU MessageFormat, 9 locales, locale resolver, serializer |
| 1D | API client | Fetch-based client with retry, circuit breaker, LRU cache, zod validation |
| 1E | SignalR wrapper | Reconnecting SignalR connection with useLiveFlights hook for real-time board updates |
| 1F-layout | Root layout | Root + locale layouts, error routes, smoke route, ErrorBoundary, HTTP error mapper |
| 1F-seo | SEO primitives | SeoHead component, hreflang builder, JsonLdRenderer for structured data |
| 1G-logger | Logger | Structured JSON-lines transport + console transport, logger provider |
| 1G-metrics | Metrics | OpenTelemetry init (server MeterProvider + TracerProvider), custom metric instruments |
| 1G-analytics | Analytics | Analytics facade with four stub adapters (Yandex.Metrica, CTM, Variocube, Dynatrace) |
| 1H | Security | CSP with per-request nonce, stream-transform nonce injection, HTTP security headers, secure storage |
| 1I | Deploy pipeline | Dockerfile pair, health endpoint, graceful shutdown, deploy workflow, runbook |
Running locally
Prerequisites
- Node.js 24.2.0+ (see
.nvmrc) - pnpm 9+
Commands
# Install dependencies
pnpm install
# Start dev server (standalone SSR mode)
pnpm dev
# Build both targets
pnpm build:both
# Run tests
pnpm test
# Run tests with coverage
pnpm test:coverage
# Lint
pnpm lint
# Typecheck
pnpm typecheck
# Check bundle size
pnpm bundle-size
Build targets
- Standalone (
pnpm build:standalone): Full SSR app with its own server, routes, and HTML shell. Output indist/standalone/. - Remote (
pnpm build:remote): MF 2.0 remote component exposingOnlineBoard,Schedule,FlightsMap,PopularRequests. Output indist/remote/, servesmf-manifest.jsonat root.
Environment variables
All env vars are validated at startup via zod (see src/env/index.ts). Required variables for local dev are set to defaults. For full configuration, see the env schema.
Key variables:
BUILD_TARGET—standaloneorremote(set by build scripts)OTEL_EXPORTER_OTLP_ENDPOINT— OpenTelemetry collector endpoint (optional for dev)LOG_LEVEL—debug,info,warn,error(default:info)
Debugging common failures
SSR fallback
Symptom: Page renders as empty white screen, then client-side hydration kicks in late.
Cause: An error during SSR caused React to fall back to client-only rendering.
Debug:
- Check server logs for SSR errors — they appear as structured JSON lines with
"level":"error". - Common culprits: accessing
window/documentduring SSR, missing env vars, API calls outsideuseEffect. - The
ErrorBoundarycatches render errors and shows a fallback UI. Check the error boundary'scomponentDidCatchoutput in logs.
Missing env vars
Symptom: App crashes at startup with a zod validation error.
Debug:
- Read the error message — it lists exactly which env vars failed validation.
- Check
src/env/index.tsfor the full schema and defaults. - For local dev, most vars have sensible defaults. For deployed environments, ensure all required vars are set in the deployment config.
ESLint boundary violations
Symptom: pnpm lint fails with boundaries/element-types or boundaries/entry-point errors.
Debug:
- The boundary rules enforce a strict layering:
shared/andobservability/cannot import fromfeatures/orroutes/.features/cannot import fromroutes/ormf/.ui/cannot import fromfeatures/. - If you need shared logic, move it to
shared/. If you need a feature-specific component, keep it infeatures/<name>/components/. - Run
pnpm lintwith--debugfor detailed rule information. - See
eslint.config.jsfor the full boundary configuration.
Test flakes
Symptom: Tests pass locally but fail intermittently in CI.
Known flaky patterns:
- Timer-based tests (SignalR reconnection, circuit breaker): These use
vi.useFakeTimers(). Ensurevi.advanceTimersByTime()is called with exact intervals, not approximate. - ESLint integration tests (
tests/eslint/): These spawn real ESLint processes and can be slow (~20s each). They are not flaky but may time out on constrained CI runners. The CI timeout is 20 minutes to accommodate this. - OpenTelemetry tests: The
otel.test.tssuite registers global providers. Each test must clean up after itself to avoid state leakage.
General tips:
- Run
pnpm test -- --reporter=verboseto see timing for each test. - Use
pnpm test -- --bail 1to stop on first failure for faster feedback.
Related documents
- Runbook:
docs/superpowers/phase-1/runbook.md— Operational runbook for incident response, health checks, rollback procedures, and monitoring dashboards. - Cutover plan:
docs/superpowers/plans/2026-04-15-phase-6-cutover.md— Production cutover strategy including canary deploy, traffic shifting, and rollback gates. - Design spec:
docs/superpowers/specs/2026-04-14-aeroflot-flights-react-rewrite-design.md— Full design specification for the Angular-to-React rewrite. - Phase 1 master plan:
docs/superpowers/plans/2026-04-14-phase-1-foundation-master.md— Sub-plan index with dependency graph and contracts.