Unify the Agent history extension with the header acrylic surface, preserve the full conversation body, and consolidate shared control and status styling. Restore map flow and SCADA controller behavior, remove obsolete rendering paths, and extend regression coverage. Button press coverage now releases outside the target so state assertions cannot accidentally toggle the control.
170 lines
7.3 KiB
Markdown
170 lines
7.3 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, 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.
|