170 lines
7.4 KiB
Markdown
170 lines
7.4 KiB
Markdown
# Repository Guidelines
|
|
|
|
## Scope
|
|
|
|
This repository contains the Vite and React single-page frontend for the
|
|
Agent-driven supply-network WebGIS. Runtime TypeScript lives under `src/`.
|
|
The application uses React 19, TypeScript, Tailwind CSS, MapLibre GL, deck.gl,
|
|
SWR, Vitest, and Playwright.
|
|
|
|
Keep this project browser-first. Do not add Next.js APIs, `"use client"`
|
|
directives, or general backend-for-frontend routes. Agent reasoning and tool
|
|
execution belong in `next-tjwater-agent`.
|
|
|
|
## Source Layout
|
|
|
|
- `src/app/` owns application startup, providers, and shell composition.
|
|
- `src/features/workbench/` owns supply sources, layers, SCADA overlays,
|
|
scenarios, feature adapters, GeoServer configuration, and workbench
|
|
interactions.
|
|
- `src/features/agent/` owns Agent protocol clients, sessions, typed frontend
|
|
actions, validated UI envelopes, recommendations, and Agent panels.
|
|
- `src/features/map/core/` owns domain-neutral map controls, legends, notices,
|
|
and reusable map presentation primitives.
|
|
- `src/shared/` owns reusable UI, AI presentation elements, runtime
|
|
configuration, and feature-independent utilities.
|
|
- `src/mocks/` owns MSW handlers and fixtures.
|
|
- `src/test/` owns shared Vitest setup and repository-wide invariant tests.
|
|
- `tests/browser/` owns product-level Playwright regressions.
|
|
- `public/` contains static supply-network and SCADA assets plus the
|
|
runtime-config placeholder.
|
|
- `server/` contains the same-origin Edge TTS adapter used by Vite and the
|
|
production container.
|
|
|
|
Do not recreate a catch-all `src/lib/` directory. Put feature-independent
|
|
helpers in `src/shared/`; put supply-network and GeoServer logic in the
|
|
owning `workbench` module.
|
|
|
|
Do not create empty placeholder directories. Add a directory with its first
|
|
source file.
|
|
|
|
## Dependency Direction and Public APIs
|
|
|
|
Keep dependencies moving toward generic code:
|
|
|
|
```text
|
|
app -> workbench, map/core, shared
|
|
workbench -> agent, map/core, shared
|
|
agent -> map/core, shared
|
|
map/core -> shared
|
|
shared -> external packages only
|
|
```
|
|
|
|
- `src/app` may import the `workbench` and `map/core` public APIs plus
|
|
shared startup configuration.
|
|
- `workbench` may import `agent`, `map/core`, and `shared`.
|
|
- `agent` may import generic `map/core` presentation helpers and `shared`,
|
|
but it must not import `workbench`.
|
|
- `map/core` must not know supply layer IDs, SCADA models, workbench state, or
|
|
Agent workflows.
|
|
- `shared` must not import from `app`, `features`, or `mocks`.
|
|
- Runtime feature code must not import from `app` or `mocks`.
|
|
|
|
Use a feature's `index.ts` as its public API for cross-feature imports. Add an
|
|
intentional public export when another feature needs a symbol. Use relative
|
|
imports within the same feature. Do not introduce cross-feature deep imports
|
|
or barrels for private implementation files.
|
|
|
|
## Component and Module Design
|
|
|
|
- Use TypeScript and React function components. Export explicit types at
|
|
feature and adapter boundaries.
|
|
- Use two-space indentation and kebab-case filenames. Use PascalCase for
|
|
components and types, camelCase for functions and values, and `useXxx` for
|
|
hooks.
|
|
- Keep application and page components focused on composition. Extract state,
|
|
effects, network flows, resize behavior, and map orchestration into focused
|
|
hooks, controllers, or child components.
|
|
- Keep MapLibre sources, layers, camera helpers, feature queries, and event
|
|
handling outside presentational components. Map mutations belong in typed
|
|
controllers or map helpers.
|
|
- Keep Agent rendering schema-driven. Validate Agent output before it reaches
|
|
React. Model map actions as typed data that can be previewed, confirmed,
|
|
applied, and rolled back.
|
|
- Keep reusable UI free of supply-network terminology and workflow state. The
|
|
owning feature decides business behavior.
|
|
- Prefer one source of truth. Search for an existing utility, config wrapper,
|
|
style token, or domain type before adding another.
|
|
|
|
## Supply-Domain Boundary
|
|
|
|
This repository models a supply network. Pipes, junctions, valves, reservoirs,
|
|
tanks, pumps, pressure, flow, water age, demand, isolation, and continuity of
|
|
supply belong in `workbench`.
|
|
|
|
Do not introduce drainage-network layer IDs, assets, terminology, export
|
|
filenames, configuration prefixes, fixtures, or operating assumptions.
|
|
Drainage concepts such as conduits, orifices, outfalls, manholes, sewage,
|
|
stormwater, and overflow risk do not belong here.
|
|
|
|
`next-tjwater-drainage-frontend` may be consulted for generic architecture
|
|
patterns only. Never copy its domain constants, source catalogs, map styles,
|
|
icons, mocks, product copy, environment variables, or defaults into this
|
|
repository. The supply-domain invariant test in
|
|
`src/test/supply-domain.test.ts` must remain green.
|
|
|
|
## Runtime and Server Boundaries
|
|
|
|
Browser configuration is injected through `/runtime-config.js` and validated
|
|
in `src/shared/config/env.ts`. Use `TJWATER_*` variables. Do not add
|
|
`DRAINAGE_*`, `VITE_*`, or legacy `NEXT_PUBLIC_*` browser configuration.
|
|
|
|
Browser-safe GeoServer reads may happen directly when CORS is enabled. Agent
|
|
requests go to the configured Agent service. The local `server/` exception is
|
|
limited to the same-origin Edge TTS network adapter; do not turn it into a
|
|
general API layer or add free-form proxy routes.
|
|
|
|
## Tests
|
|
|
|
- Co-locate focused Vitest tests with the module under test using `*.test.ts`
|
|
or `*.test.tsx`.
|
|
- Put repository-wide invariants and shared setup in `src/test/`.
|
|
- Put new product and interaction Playwright tests in `tests/browser/`.
|
|
`src/app/app.e2e.ts` is retained migration coverage, not a location to copy.
|
|
- Name tests after behavior. Cover pure map calculations, adapters, protocol
|
|
validation, and state transitions without requiring a browser when possible.
|
|
- Add focused Playwright coverage for visible behavior, responsive layout,
|
|
runtime configuration, keyboard and pointer interaction, or map integration.
|
|
|
|
## Commands and Verification
|
|
|
|
Use `pnpm` from this repository.
|
|
|
|
```bash
|
|
pnpm dev # start Vite on http://127.0.0.1:5173
|
|
pnpm lint # run ESLint
|
|
pnpm typecheck # run TypeScript without emitting files
|
|
pnpm test # run Vitest
|
|
pnpm test:browser # run Playwright
|
|
pnpm build # typecheck, build the SPA, and bundle the TTS adapter
|
|
```
|
|
|
|
Match verification to the change:
|
|
|
|
- Documentation-only changes: run `git diff --check` and verify referenced
|
|
paths and commands.
|
|
- TypeScript logic or component changes: run `pnpm lint`, `pnpm typecheck`,
|
|
and `pnpm test`.
|
|
- Visible UI, responsive, configuration, or map interaction changes: also run
|
|
focused `pnpm test:browser` coverage.
|
|
- Dependency, Vite, container, runtime integration, or release changes: also
|
|
run `pnpm build`.
|
|
|
|
Do not report a check as passing unless it ran in the current worktree. If a
|
|
required browser or external service is unavailable, report the skipped layer
|
|
and reason.
|
|
|
|
## Security and Repository Hygiene
|
|
|
|
Do not commit secrets, `.env.local`, generated `dist/` or `dist-server/`,
|
|
dependency folders, Playwright artifacts, session dumps, tokens, or logs. Keep
|
|
server-only targets and credentials in untracked environment files.
|
|
|
|
Treat Agent output, UI envelopes, feature identifiers, URLs, and runtime
|
|
configuration as untrusted input. Validate at system boundaries, keep
|
|
credentials out of browser-visible values, and use typed adapters instead of
|
|
free-form command or request construction.
|
|
|
|
Preserve unrelated work in a dirty checkout. Do not clean, reset, move, or
|
|
rewrite user changes while completing a scoped task.
|