P9 setup: canonical wiki template (visual-first, mermaid-first)
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) <noreply@anthropic.com>
This commit is contained in:
213
.claude/refactor/WIKI_TEMPLATE.md
Normal file
213
.claude/refactor/WIKI_TEMPLATE.md
Normal file
@@ -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
|
||||||
|
# <Node name>
|
||||||
|
|
||||||
|
> 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[<Parent type — e.g. machineGroupControl>] -->|set.demand| this[<This node>]
|
||||||
|
this -->|evt.state-change| parent
|
||||||
|
sensor[<measurement>] -->|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 <classname-by-S88-level>
|
||||||
|
```
|
||||||
|
|
||||||
|
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 `<parent>` + 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 `<Node>.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.
|
||||||
Reference in New Issue
Block a user