# EVOLV - Claude Code Project Guide > **READ FIRST, BEFORE ANY OTHER WORK:** > 1. [`CONTRACTS.md`](./CONTRACTS.md) — front-door map: where every contract, rule, and standard lives, and how to find them. > 2. [`.claude/rules/repo-mem.md`](./.claude/rules/repo-mem.md) — this repo has an MCP server (`repo-mem`) exposing a substrate-trained `repo_search` and a persistent fix-trace store. Use those instead of `grep` for concept queries, and record completed fixes via `repo_record_fix`. ## What This Is Node-RED custom nodes package for wastewater treatment plant automation. Developed by Waterschap Brabantse Delta R&D team. Follows ISA-88 (S88) batch control standard. ## Architecture Each node follows a three-layer pattern: 1. **Node-RED wrapper** (`.js`) - registers the node type, sets up HTTP endpoints 2. **Node adapter** (`src/nodeClass.js`) - bridges Node-RED API with domain logic, handles config loading, tick loops, events 3. **Domain logic** (`src/specificClass.js`) - pure business logic, no Node-RED dependencies ## Key Shared Library: `nodes/generalFunctions/` - `logger` - structured logging (use this, NOT console.log) - `MeasurementContainer` - chainable measurement storage (type/variant/position) - `configManager` - loads JSON configs from `src/configs/` - `MenuManager` - dynamic UI dropdowns - `outputUtils` - formats messages for InfluxDB and process outputs - `childRegistrationUtils` - parent-child node relationships - `coolprop` - thermodynamic property calculations ## Conventions - Nodes register under category `'EVOLV'` in Node-RED - S88 color scheme: Area=#0f52a5, ProcessCell=#0c99d9, Unit=#50a8d9, Equipment=#86bbdd, ControlModule=#a9daee - Config JSON files in `generalFunctions/src/configs/` define defaults, types, enums per node - Tick loop runs at 1000ms intervals for time-based updates - Output ports + 3-tier architecture: see `.claude/rules/node-architecture.md` - **Multi-tab demo flows**: see `.claude/rules/node-red-flow-layout.md` for the tab/link-channel/spacing rule set used by `examples/` - **Output coverage** (every output, every state, every layer): see `.claude/rules/output-coverage.md` — manifest + populated/degraded tests are mandatory for any change that touches Port 0/1/2 keys, function-node fan-outs, telemetry fields, or dashboard widget sources ## Sources of truth (the canonical files) - **Front-door map**: [`CONTRACTS.md`](./CONTRACTS.md) — read first; lists every standard and where it lives - **Platform API shapes** (BaseDomain, BaseNodeAdapter, commands registry, UnitPolicy, …): `.claude/refactor/CONTRACTS.md` - **Code conventions** (file/function size, comments, naming): `.claude/refactor/CONVENTIONS.md` - **Per-node module layout**: `.claude/refactor/MODULE_SPLIT.md` - **Per-node API contract**: `nodes//CONTRACT.md` + `nodes//src/commands/index.js` (source of truth for accepted `msg.topic` values) - **Shared library API**: `nodes/generalFunctions/CONTRACT.md` (exported classes + utilities) - **Live decisions log**: `.claude/refactor/OPEN_QUESTIONS.md` — append, don't invent ## Development Notes - No build step required - pure Node.js - Install: `npm install` in root - Submodule URLs were rewritten from `gitea.centraal.wbd-rd.nl` to `gitea.wbd-rd.nl` for external access - Dependencies: mathjs, generalFunctions (git submodule)