134 lines
5.7 KiB
Markdown
134 lines
5.7 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
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>`
|