P6: convert dashboardAPI to platform infrastructure
Refactor of dashboardAPI to use BaseNodeAdapter + commandRegistry + statusBadge. dashboardAPI follows the platform refactor plan in .claude/refactor/MODULE_SPLIT.md. Tests stay green; CONTRACT.md generated; legacy aliases preserved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
80
CONTRACT.md
Normal file
80
CONTRACT.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# dashboardAPI — Contract
|
||||
|
||||
dashboardAPI is an EVOLV utility node that listens for child-registration
|
||||
events from other EVOLV nodes and emits Grafana dashboard upsert HTTP
|
||||
requests on Port 0. It has **no domain measurements, no tick loop, and no
|
||||
parent of its own** — it is a one-shot HTTP emitter. Per
|
||||
OPEN_QUESTIONS.md (2026-05-10) it does NOT extend `BaseNodeAdapter` /
|
||||
`BaseDomain`; it uses the shared command registry only.
|
||||
|
||||
## Inputs (msg.topic on Port 0)
|
||||
|
||||
| Canonical | Aliases (deprecated) | Payload | Effect |
|
||||
|---|---|---|---|
|
||||
| `child.register` | `registerChild` | string (child node id) **or** `{ source: {...} }` **or** `{ config: {...} }` (optionally `msg.includeChildren: boolean`, default `true`) | Resolves the child source (`RED.nodes.getNode` → `node._flow.getNode` → inline payload), calls `source.generateDashboardsForGraph(child, { includeChildren })`, then emits one `topic: 'create'` HTTP-upsert message on Port 0 per generated dashboard. |
|
||||
|
||||
Aliases log a one-time deprecation warning the first time they fire.
|
||||
|
||||
## Outputs (msg.topic on Port 0/1/2)
|
||||
|
||||
- **Port 0 (process):** one message per generated dashboard, shaped for a
|
||||
downstream `http request` node:
|
||||
```js
|
||||
{
|
||||
topic: 'create',
|
||||
url: <grafanaUpsertUrl>, // e.g. http://grafana:3000/api/dashboards/db
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: 'Bearer …' // only when bearerToken is set
|
||||
},
|
||||
payload: { dashboard: {…}, folderId: 0, overwrite: true },
|
||||
meta: { nodeId, softwareType, uid, title }
|
||||
}
|
||||
```
|
||||
Re-emits the inbound `msg` fields by spread (`{...msg, ...}`) so any
|
||||
caller-supplied correlation/trace fields propagate.
|
||||
- **Port 1 (InfluxDB telemetry):** **not used.** dashboardAPI has no
|
||||
measurements; nothing is emitted on Port 1.
|
||||
- **Port 2 (registration / control plumbing):** **not used.** dashboardAPI
|
||||
is a sink for `child.register`, not a source — it does not register
|
||||
itself with any parent.
|
||||
|
||||
## Events emitted by `source.emitter`
|
||||
|
||||
None. The specificClass (`DashboardApi`) exposes no `EventEmitter` — it
|
||||
is a passive service that responds to method calls and returns built
|
||||
dashboard payloads.
|
||||
|
||||
## Children accepted
|
||||
|
||||
Any EVOLV node whose `nodeSource.config` includes
|
||||
`functionality.softwareType`. The graph walk reads children via
|
||||
`nodeSource.childRegistrationUtils.registeredChildren.values()`. A
|
||||
dashboard template is loaded from `config/<softwareType>.json` (with
|
||||
case-insensitive fallback and a `machineGroupControl → machineGroup.json`
|
||||
alias); a missing template is logged at `warn` and the dashboard is
|
||||
skipped.
|
||||
|
||||
The dashboard's templating variables `measurement` and `bucket` are
|
||||
filled from the child's id and `positionVsParent` (or
|
||||
`config.defaultBucket` / `config.bucketMap[position]` overrides). The
|
||||
root dashboard is augmented with `links[]` entries pointing at each
|
||||
direct child dashboard.
|
||||
|
||||
## Why no BaseNodeAdapter / BaseDomain
|
||||
|
||||
- No `generalFunctions/src/configs/dashboardapi.json` — `BaseDomain`'s
|
||||
constructor unconditionally calls `configManager.getConfig(ctor.name)`
|
||||
and would throw. The local `dependencies/dashboardapi/dashboardapiConfig.json`
|
||||
is for the editor menu endpoint, not the runtime config pipeline.
|
||||
- No periodic output — `BaseNodeAdapter`'s `_emitOutputs()` /
|
||||
`outputUtils.formatMsg` pipeline assumes a delta-compressed Port 0/1
|
||||
stream; dashboardAPI emits HTTP-shaped messages instead.
|
||||
- No registration to a parent — `BaseNodeAdapter._scheduleRegistration`
|
||||
would emit a spurious `child.register` of its own.
|
||||
- No status badge / tick / measurements / children of its own.
|
||||
|
||||
dashboardAPI uses the shared `commandRegistry` (canonical topic naming +
|
||||
alias-with-deprecation) and stops there.
|
||||
Reference in New Issue
Block a user