Files

5.7 KiB

AGENTS.md - Aeroflot.Flights.Web

Read First

React 18 SSR app on Modern.js 2.70.8 with Rspack and Module Federation 2.3.3. It is deployed both as a standalone SSR app and as a remote frontend component for customer Web/PWA hosts.

Work in src/. Treat ClientApp/ as legacy Angular 12 reference only unless the user explicitly asks otherwise.

Prefer small, local changes that match the existing architecture. Do not widen dependencies across layers, and do not introduce browser-only imports into SSR paths.

Commands

pnpm install

pnpm dev          # Modern.js on :8081
pnpm dev:full     # Proxy on :8080; forwards API via curl

pnpm typecheck
pnpm lint
pnpm test
pnpm test:coverage
pnpm bundle-size      # remote gzip budget: <= 2000 kB
pnpm check-coverage   # line coverage gate: >= 65%

pnpm build:standalone # dist/standalone/
pnpm build:remote     # dist/remote/ with mf-manifest.json
pnpm build:both

pnpm test:e2e         # React app, baseURL http://localhost:8080
pnpm test:e2e:angular # Legacy Angular app, port 4203

Critical Rules

  • Components must be side-effect free: no fetch outside useEffect; use the API client from context.
  • Use React.lazy() for dynamic imports. Wrap browser-only UI such as Leaflet in ClientOnly.
  • SignalR must stay out of SSR bundles; import @microsoft/signalr dynamically only.
  • Read env through getEnv() from @/env/index.ts; SSR injects window.__ENV__.
  • Keep rendered state consistent with API responses; avoid stale state leaking into UI.
  • Preserve SEO/accessibility requirements, including JSON-LD and OpenGraph where relevant.
  • Keep layouts fluid and responsive across screen sizes.

Agent Runtime Safety

  • If a task asks for Pi Crew, use the Pi Crew team tool or the project slash prompt; do not silently continue as a normal parent Pi implementation session.
  • Do not call unavailable abstract tools such as glob; use rg --files, rg -n, find, sed, nl, and git grep.
  • Never repeat the same failed tool call or shell command more than once. Treat identical command, identical exit code, and identical/no output as a loop signal.
  • If a command exits non-zero with no useful output, do not retry it unchanged. Inspect source/tests or change the hypothesis first.
  • If a focused test fails, use the failure location to inspect and fix code/tests; do not repeatedly grep test output for unrelated terms.
  • After two failed verification attempts without a code or test change, stop and report the blocker, current hypothesis, and next concrete fix.
  • If five consecutive tool calls add no new information, stop and summarize what is known instead of continuing.

Architecture

Top-level source areas:

  • src/routes/ - file-based routing and layouts.
  • src/features/ - feature modules: online board, schedule, flights map, popular requests.
  • src/ui/ - shared UI primitives only.
  • src/shared/ - API client, storage, hooks, SignalR helpers.
  • src/observability/ - logging, metrics, analytics.
  • src/i18n/ - i18n provider and translations.

Entry points:

  • src/routes/page.tsx redirects to /{lang}/onlineboard.
  • src/routes/layout.tsx owns global providers.
  • src/routes/[lang]/layout.tsx owns locale-scoped i18n.

Module Federation:

  • Remote name: aeroflot_flights.
  • Exposes: ./OnlineBoard, ./Schedule, ./FlightsMap, ./PopularRequests.
  • Remote build must emit dist/remote/mf-manifest.json, served as /mf-manifest.json.

Layer Boundaries

ESLint enforces these boundaries:

  • features/ must not import routes/ or mf/.
  • ui/ must not import features/, routes/, or mf/.
  • shared/ must not import features/, routes/, mf/, or observability/.
  • observability/ must not import features/, routes/, or mf/.

Restricted imports:

  • Use @/observability/metrics/otel instead of importing OTel SDKs directly.
  • Use @/i18n/provider instead of importing react-i18next directly.
  • Use @/shared/storage instead of direct localStorage or sessionStorage.

Progressive Detail

Reach for the sections below only when the task needs them.

Contractual Requirements

  • Modern.js SSR, React 18+, Module Federation 2.0 compatible output.
  • mf-manifest.json must expose components and logic at https://<domain>/mf-manifest.json.
  • Customer REST APIs use JSON payloads only.
  • Target capacity: 100 RPS.
  • Remote component must remain isolated from host components.
  • Required analytics/monitoring integrations include Yandex.Metrica, CTM, Variocube, and Key-Astrom/Dynatrace.
  • Frontend logs and system events must be exportable to customer aggregators.
  • Implementation must follow customer mockups, design system, and standard remote module structure.

Dev Server

  • pnpm dev serves Modern.js SSR/HMR on port 8081.
  • pnpm dev:full serves port 8080 and proxies:
    • /api/* and /flights/* to https://flights.test.aeroflot.ru via curl.
    • all other paths to Modern.js on 8081.

Build And Deploy

  • dist/standalone/ is the Node SSR server, deployed with Dockerfile.react.
  • dist/remote/ is the static MF remote, deployed with Dockerfile.remote.
  • CI/CD lives in .github/workflows/ci.yml and .github/workflows/deploy.yml.

Current Constraints

  • Modern.js 3.x upgrade is currently blocked by @module-federation/modern-js ESM incompatibilities.
  • React Router v7 future flags are enabled to suppress deprecation warnings.

Git And CI

  • Do not add Co-Authored-By lines.
  • Commit messages must be English, concise, and focused on why.
  • Commit completed stable work autonomously. Ask before pushing, force-pushing, or destructive git operations.
  • Use Gitea tea for workflow runs:
    • tea run list --limit 5
    • tea run view <run-id>
    • tea run rerun <run-id>