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.
7.3 KiB
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:
app -> workbench, map/core, shared
workbench -> agent, map/core, shared
agent -> map/core, shared
map/core -> shared
shared -> external packages only
src/appmay import theworkbenchandmap/corepublic APIs plus shared startup configuration.workbenchmay importagent,map/core, andshared.agentmay import genericmap/corepresentation helpers andshared, but it must not importworkbench.map/coremust not know supply layer IDs, SCADA models, workbench state, or Agent workflows.sharedmust not import fromapp,features, ormocks.- Runtime feature code must not import from
appormocks.
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
useXxxfor 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.tsor*.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.tsis 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.
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 --checkand verify referenced paths and commands. - TypeScript logic or component changes: run
pnpm lint,pnpm typecheck, andpnpm test. - Visible UI, responsive, configuration, or map interaction changes: also run
focused
pnpm test:browsercoverage. - 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.