From ce07cc564fcc78d4145c297158f83cc723ff558f Mon Sep 17 00:00:00 2001 From: znetsixe Date: Sun, 10 May 2026 22:27:08 +0200 Subject: [PATCH] P9 setup: canonical wiki template (visual-first, mermaid-first) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Defines the 9-section template every node's wiki page follows: 1. Position in the platform (mermaid flowchart, S88-coloured) 2. Capability matrix (≤ 10 rows) 3. Topic contract (auto-generated from src/commands/index.js) 4. Lifecycle (mermaid sequenceDiagram) 5. Configuration (mermaid flowchart + form-to-config table) 6. Examples (basic/integration/dashboard tiers) 7. State chart (stateDiagram-v2, only for stateful nodes) 8. When you would NOT use this node 9. Known limitations / current issues Hard rules: diagrams before prose, ≤ 60 words of unbroken prose anywhere, topic contract auto-generated (no hand-written drift). Per-node application is the next step (P9.3-P9.6 in TASKS.md). Co-Authored-By: Claude Opus 4.7 (1M context) --- .claude/refactor/WIKI_TEMPLATE.md | 213 ++++++++++++++++++++++++++++++ 1 file changed, 213 insertions(+) create mode 100644 .claude/refactor/WIKI_TEMPLATE.md diff --git a/.claude/refactor/WIKI_TEMPLATE.md b/.claude/refactor/WIKI_TEMPLATE.md new file mode 100644 index 0000000..89e4e20 --- /dev/null +++ b/.claude/refactor/WIKI_TEMPLATE.md @@ -0,0 +1,213 @@ +# Wiki page template — every node uses this shape + +This is the canonical structure for every node's gitea wiki landing +page. Visual-first, scannable, ≤ 60 words of unbroken prose anywhere. + +## Why this shape + +The platform now has 12 nodes with the same architectural skeleton +(BaseDomain + BaseNodeAdapter + ChildRouter + commands registry). +The wiki should mirror that uniformity: a reader can flip between +nodes and find the same sections in the same order. + +Mermaid blocks lead. Tables annotate. Prose only fills gaps. + +## Template — copy this whole file as the seed for each node's wiki + +```markdown +# + +> One-paragraph "what is this node". Cap 60 words. Plain English. +> Example: "rotatingMachine models a single pump or compressor — +> takes pressure measurements and predicts flow + power from supplier +> curves. State machine drives startup/shutdown sequences." + +## 1. Position in the platform + +```mermaid +flowchart LR + parent[] -->|set.demand| this[] + this -->|evt.state-change| parent + sensor[] -->|data.flow| this + this -->|child.register| parent + classDef proc fill:#0c99d9,color:#fff + classDef unit fill:#50a8d9 + classDef equip fill:#86bbdd + classDef ctrl fill:#a9daee + class this +``` + +The Mermaid block shows the typical neighbours and the data direction. +Pick the right `classDef` for the S88 level (Process Cell / Unit / +Equipment / Control Module). Match the colour codes from +`.claude/rules/node-red-flow-layout.md`. + +## 2. Capability matrix + +| Capability | Status | Notes | +|---|---|---| +| Predicts flow from pressure | ✅ | | +| Receives manual setpoint | ✅ | Topic `set.setpoint` | +| Auto-start on demand from parent | ✅ | | +| Self-calibrating | ❌ | Calibration is operator-triggered (`cmd.calibrate`) | +| Supports multi-parent registration | ⚠️ | Possible but not fully tested — see CONTRACT.md notes | + +Keep this table to ≤ 10 rows. For longer feature inventories, link out. + +## 3. Topic contract + +> Auto-generated from `src/commands/index.js`. Do NOT hand-edit. +> Re-run `npm run wiki:contract` after any change to commands. + +| Canonical topic | Aliases | Payload | Effect | +|---|---|---|---| +| `set.mode` | `setMode` | `string` (`auto` \| `manual` \| `maintenance`) | Switches operating mode. | +| `cmd.startup` | `execSequence` (with `payload.action='startup'`) | `{source: string}` | Triggers startup sequence (state machine). | +| ... | ... | ... | ... | + +## 4. Lifecycle — what one tick (or event) does + +```mermaid +sequenceDiagram + participant parent + participant node as this node + participant sensor as measurement child + participant out as Port-0 output + + sensor->>node: data.flow (12 m³/h, downstream) + node->>node: route → measurementHandlers + node->>node: drift assess → predictionHealth update + node->>node: getOutput composes snapshot + node->>out: msg{topic, payload, [process|influx]} + parent->>node: set.demand (15 m³/h) + node->>node: control.dispatch + node->>parent: child.register (handshake) +``` + +Keep the diagram to one screen. If you have multiple distinct flows +(idle vs running vs error), pick the most common one and link out +to the others. + +## 5. Configuration — editor form & where each field lands + +```mermaid +flowchart TB + subgraph editor["Node-RED editor form"] + f1[Mode] + f2[Demand] + f3[Threshold percent] + end + subgraph config["Domain config"] + c1[control.mode] + c2[control.targets.demand] + c3[safety.thresholdPercent] + end + f1 --> c1 + f2 --> c2 + f3 --> c3 +``` + +| Form field | Config key | Default | Range | +|---|---|---|---| +| Mode | `control.mode` | `auto` | enum | +| Demand | `control.targets.demand` | `0` | ≥ 0 | +| Threshold % | `safety.thresholdPercent` | `95` | 0–100 | + +## 6. Examples + +| Tier | File | What it shows | +|---|---|---| +| Basic | `examples/01-Basic.json` | Inject + dashboard, no parent | +| Integration | `examples/02-Integration.json` | Wired to `` + 1 measurement child | +| Dashboard | `examples/03-Dashboard.json` | Live FlowFuse charts of flow / power / state | + +Include one screenshot per tier where helpful — keep them under 200 KB +each. Link to a runnable docker compose snippet under `examples/README.md`. + +## 7. State chart (only for stateful nodes) + +```mermaid +stateDiagram-v2 + [*] --> off + off --> idle: cmd.startup + idle --> warmingup: setpoint > 0 + warmingup --> operational: warmup_time elapsed + operational --> coolingdown: cmd.shutdown + coolingdown --> off: cooldown_time elapsed + operational --> emergencystop: cmd.estop + emergencystop --> off: cmd.reset +``` + +Skip this section for stateless / pure-aggregator nodes (e.g. measurement, +dashboardAPI). + +## 8. When you would NOT use this node + +- "Use rotatingMachine for a SINGLE pump. For groups of 2+ pumps with + load sharing, use machineGroupControl as the parent." +- "Use measurement only for sensor signal conditioning. For setpoint + injection, use the dashboard or a parent's command topic." + +Two or three bullets, each one sentence. Forces explicit non-goals. + +## 9. Known limitations / current issues + +| # | Issue | Tracked in | +|---|---|---| +| 1 | Drift confidence drops to 0 when pressure is missing for > 30 s | `OPEN_QUESTIONS.md` 2026-05-10 | +| 2 | Multi-parent teardown ordering | `OPEN_QUESTIONS.md` 2026-05-10 | + +Link to repo issues when they exist. Keep this table living — it's the +contract with the user about what "works". +``` + +## Hard rules for editors + +1. The Mermaid platform-position block is **section 1**, before any + prose. Diagrams first. +2. Each section opens with a diagram or table; prose annotates the + visual, not the other way round. +3. No more than **60 words of unbroken prose** anywhere on a page. +4. The topic contract is **auto-generated** from `src/commands/index.js`. + Don't hand-write it. +5. Use `flowchart LR` for node connections, `sequenceDiagram` for + tick-to-output flow, `stateDiagram-v2` for state machines. +6. Skip `classDiagram` (we don't expose classes to users) and `gantt` + (no schedules in node docs). + +## Auto-generation notes (Phase 9 follow-up) + +The "Topic contract" table in section 3 should be generated by a small +`npm run wiki:contract` script, per node. Implementation: + +```js +// scripts/generate-contract.js +const commands = require('../src/commands'); +const rows = commands.map((c) => ({ + topic: c.topic, + aliases: (c.aliases || []).join(', ') || '—', + payload: describeSchema(c.payloadSchema), + effect: c.description || '— (handler-only)', +})); +console.log(toMarkdownTable(rows)); +``` + +`describeSchema` walks the lightweight schema (`{type, properties}`) +and produces a one-line readable form. Wire each node's `package.json`: + +```json +"scripts": { + "wiki:contract": "node scripts/generate-contract.js > wiki/_partial-topics.md" +} +``` + +Then a thin wiki page `.md` includes `_partial-topics.md` (or +the section is regenerated in-place between markers). + +## What lives in the gitea wiki vs the repo + +- `wiki/` directory in the repo (where present): canonical, version- + controlled. +- gitea wiki UI: cosmetic mirror — re-rendered from `wiki/` on push. +- Auto-generated partials (`_partial-*.md`): committed under `wiki/` + but generated; never hand-edited.