Files
jiang f4318a9b9c feat: refine workbench visuals and map controls
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.
2026-07-28 16:39:36 +08:00

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/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.

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.