Files
flights_web/AGENTS.md
T

177 lines
6.9 KiB
Markdown

# AGENTS.md — Aeroflot.Flights.Web
## Quick Start
```bash
# 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)
```
## Current State
React 18 SSR application built with **Modern.js 2.70.8** (Rspack bundler) and **Module Federation 2.3.3**. The app is a remote frontend component embeddable in the customer's channel apps (Web, PWA).
**Stack:** Modern.js 2.70.8, React 18.2, Rspack, Module Federation 2.3.3, i18next (9 languages), PrimeReact, Leaflet, SignalR, OpenTelemetry, Vitest, Playwright.
**Source:** `src/` (file-based routing under `src/routes/`). Legacy Angular 12 SPA in `ClientApp/` (read-only reference, not deployed).
**Builds:** `pnpm build:standalone` (SSR server at `dist/standalone/`), `pnpm build:remote` (MF remote at `dist/remote/` with `mf-manifest.json`).
**Dev:** `pnpm dev` (Modern.js on :8081), `pnpm dev:full` (proxy on :8080 with API forwarding via curl to bypass WAF).
**Known constraint:** Modern.js 3.x upgrade is blocked by `@module-federation/modern-js` ESM incompatibilities (broken `__filename`/`require` in ESM bundles, missing `api.modifyWebpackConfig` in Rsbuild 2.0). React Router v7 future flags are enabled to suppress deprecation warnings.
## Contractual Requirements
The following are contractual hard constraints for the remote frontend component.
### 1. Tech Stack
- **ModernJS (SSR)** for the frontend framework.
- **Module Federation 2.0**. Any bundler with MF 2.0 support is acceptable: Webpack 5, Rsbuild, Rspack, or Vite.
- Must emit `mf-manifest.json` at `https://<domain>/mf-manifest.json` exposing components and logic. Reference: https://module-federation.io/guide/basic/webpack.html.
- **React 18+**, Concurrent Mode compatible.
- `<Suspense>` support required when async loading is used.
- Component bodies must be side-effect free — **no `fetch` outside `useEffect`**.
- Dynamic imports must use `React.lazy()`.
### 2. Data & Integrations
- Consumes customer REST APIs, JSON payloads only.
- Rendered data must stay consistent with API responses (no stale state leaking into the UI).
### 3. Performance
- Must sustain **100 RPS**.
### 4. Availability & Fault Tolerance
- VMs hosting the component must be geographically distributed.
- 24/7/365 availability; recovery time ≤ 6 hours after infra is restored.
### 5. Security
- Component must be isolated — no attack surface exposed to other components of the host site.
### 6. SEO & Accessibility
- SEO optimization required.
- Render microdata: **JSON-LD** and **OpenGraph**.
- Web analytics integrations: **Yandex.Metrica, CTM, Variocube, Key-Astrom (Dynatrace)**.
### 7. Cross-Platform
- Embeddable in multiple channel apps (Web, PWA).
- Fully responsive ("fluid") layout across all screen sizes.
### 8. Logging & Monitoring
- Frontend log collection in a customer-specified format, shipped to the customer's log aggregation system.
- System event monitoring with export to a metrics aggregator.
### 9. Module Structure
- Must conform to the customer's standard remote frontend module structure for uniform deployment.
### 10. Design
- Implement against customer-provided mockups using the customer's design system.
- Must embed other customer remote components when available.
## Architecture
**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), analytics
- `src/i18n/` — Internationalization (9 languages)
**Entry points:**
- `src/routes/page.tsx` — Root redirect to `/{lang}/onlineboard`
- `src/routes/layout.tsx` — Root layout with global providers
- `src/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
1. **Side-effect-free components** — No `fetch` outside `useEffect`. API calls via `ApiClient` from context.
2. **Dynamic imports** — Use `React.lazy()` for code splitting. Wrap browser-only components (Leaflet) in `ClientOnly`.
3. **SSR safety** — SignalR (`@microsoft/signalr`) is dynamically imported. Never import in SSR bundle (routes/, server/).
4. **Layered architecture** — Enforced by ESLint:
- `features/` → cannot import `routes/` or `mf/`
- `ui/` → cannot import `features/`, `routes/`, `mf/`
- `shared/` → cannot import `features/`, `routes/`, `mf/`, `observability/`
- `observability/` → cannot import `features/`, `routes/`, `mf/`
5. **Restricted imports** (ESLint rules):
- OTel SDK → use `@/observability/metrics/otel` (getMeter/getTracer)
- react-i18next → use `@/i18n/provider`
- localStorage/sessionStorage → use `@/shared/storage`
6. **Environment variables** — Read via `getEnv()` from `@/env/index.ts`. SSR injects `window.__ENV__`.
## Dev Server Details
- **Port 8081** — Modern.js dev server (SSR + HMR)
- **Port 8080** — `pnpm dev:full` proxy 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 with `mf-manifest.json`
- `dist/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`
## Commit Rules
- Never add `Co-Authored-By` lines to commit messages.
- Commit messages in English, concise, focused on "why" not "what".
- Commit autonomously when changes are complete and stable — no need to ask for permission. Group related edits into logical commits. Still ask before pushing, force-pushing, or any destructive git operation.