8005356db5
Companion markdown to the comparison-report/visual/report.html with the same coverage matrix and per-page findings. Useful for git-based review without serving the HTML. Also adds AGENTS.md (subagent role definitions for future sessions) and the modernjs-v3-upgrade plan stub from the earlier scoping.
4.0 KiB
4.0 KiB
AGENTS.md — Aeroflot.Flights.Web
Quick Start
# Install dependencies
pnpm install
# Development servers
pnpm dev # Modern.js on :8081
pnpm dev:full # Proxy on :8080 (API forwarding via curl to bypass WAF)
# Build targets
pnpm build:standalone # SSR server at dist/standalone/
pnpm build:remote # MF remote at dist/remote/ (with mf-manifest.json)
pnpm build:both # Both targets
# Quality checks (run in order)
pnpm typecheck
pnpm lint
pnpm test
pnpm test:coverage
pnpm bundle-size # CI gate: total gzip ≤ 2000 kB
pnpm check-coverage # CI gate: line coverage ≥ 65%
# E2E tests
pnpm test:e2e # React app (port 8080)
pnpm test:e2e:angular # Angular app (port 4203)
Architecture
Stack: Modern.js 2.70.8 (Rspack), React 18.2, Module Federation 2.3.3
Source structure:
src/routes/— File-based routing (React Router v7)src/features/— Feature modules (online-board, schedule, flights-map, popular-requests)src/ui/— Reusable UI primitives (never import routes/mf from here)src/shared/— Cross-cutting concerns (API client, SignalR, storage, hooks)src/observability/— Logger, metrics (OTel), analyticssrc/i18n/— Internationalization (9 languages)
Entry points:
src/routes/page.tsx— Root redirect to/{lang}/onlineboardsrc/routes/layout.tsx— Root layout with global providerssrc/routes/[lang]/layout.tsx— Locale-scoped layout with i18n
Module Federation:
- Remote name:
aeroflot_flights - Exposes:
./OnlineBoard,./Schedule,./FlightsMap,./PopularRequests - mf-manifest.json at
https://<domain>/mf-manifest.json
Critical Constraints
-
Side-effect-free components — No
fetchoutsideuseEffect. API calls viaApiClientfrom context. -
Dynamic imports — Use
React.lazy()for code splitting. Wrap browser-only components (Leaflet) inClientOnly. -
SSR safety — SignalR (
@microsoft/signalr) is dynamically imported. Never import in SSR bundle (routes/, server/). -
Layered architecture — Enforced by ESLint:
features/→ cannot importroutes/ormf/ui/→ cannot importfeatures/,routes/,mf/shared/→ cannot importfeatures/,routes/,mf/,observability/observability/→ cannot importfeatures/,routes/,mf/
-
Restricted imports (ESLint rules):
- OTel SDK → use
@/observability/metrics/otel(getMeter/getTracer) - react-i18next → use
@/i18n/provider - localStorage/sessionStorage → use
@/shared/storage
- OTel SDK → use
-
Environment variables — Read via
getEnv()from@/env/index.ts. SSR injectswindow.__ENV__.
Dev Server Details
- Port 8081 — Modern.js dev server (SSR + HMR)
- Port 8080 —
pnpm dev:fullproxy with:/api/*and/flights/*→https://flights.test.aeroflot.ru(via curl to bypass WAF)/*→ Modern.js on 8081
Testing
- Unit tests — Vitest (globals enabled, V8 coverage)
- E2E tests — Playwright (baseURL:
http://localhost:8080) - Angular E2E — Separate config for legacy app (port 4203)
Coverage gates:
- Line coverage ≥ 65%
- Bundle size (gzip) ≤ 2000 kB for remote target
Build Artifacts
dist/standalone/— SSR server (Node entrypoint)dist/remote/— MF remote withmf-manifest.jsondist/remote/static/js/— JS bundles for bundle-size gate
Deployment
- Standalone — Dockerfile.react (Node 24-slim, serves SSR)
- Remote — Dockerfile.remote (nginx serving static files)
- CI/CD:
.github/workflows/ci.yml,.github/workflows/deploy.yml
Known Constraints
- Modern.js 3.x blocked by
@module-federation/modern-jsESM incompatibilities - React Router v7 future flags enabled to suppress deprecation warnings
- Legacy Angular 12 SPA in
ClientApp/(read-only reference)
Commit Rules
- No
Co-Authored-Bylines - English commit messages, focus on "why" not "what"
- Commit autonomously when stable; ask before pushing/force-pushing