diff --git a/docs/COLLECTOR-INTEGRATION.md b/docs/COLLECTOR-INTEGRATION.md index a11a76b..0fb749d 100644 --- a/docs/COLLECTOR-INTEGRATION.md +++ b/docs/COLLECTOR-INTEGRATION.md @@ -198,7 +198,7 @@ a column. | Payload field | Type | Server behaviour (`apply_collector_payload`) | |---|---|---| | `hostname` (required) | string | Identity. Matches `Computer.hostname` (case-insensitive), then falls back to `Asset.assetnumber`. New asset created if no match. | -| `machinenumber` | string | Business tag -> `Asset.assetnumber`. The placeholder `9999` and empty string are skipped; when skipped a new PC falls back to `assetnumber = hostname`. On an existing PC a real value updates `assetnumber`. | +| `machinenumber` | string | Identifies the MACHINE this PC drives, never the PC. A new PC always takes `assetnumber = hostname`, and an existing PC's `assetnumber` is left alone. The number resolves a machine asset and builds a PC -> machine `controls` relationship; an unknown number warns rather than creating a machine. The placeholder `9999` and empty string link nothing. See "Machine links" below. | | `pctype` | string | `gea-shopfloor-*` imaging type -> `Computer.computertypeid` via the configurable `pctypemap` settings. Unmapped value -> warning, not error. | | `pcsubtype` | string | Accepted but not stored yet -> warning. | | `serialnumber` | string | `Asset.serialnumber`. | @@ -216,6 +216,46 @@ a column. Schema source of truth: `get_collector_schema` in `plugins/computers/plugin.py`. If you change the payload, change it there and re-check this table. +### PC -> machine links, and part markers + +The reported `machinenumber` says which machine the PC drives. It is not the +PC's own identifier, and writing it as one is a defect this contract used to +describe: `assets.assetnumber` is uniquely indexed and the machine already holds +that value, so the insert failed and the bay got a 500 on every report, forever. +A PC takes its hostname as its asset number and keeps it. + +- Link: PC -> machine as `controls`, tagged + `assetrelationships.label = 'collector:machine'`. Only tagged rows are ever + archived by a push, so a link made by hand is never touched. +- Unknown number: warns and links nothing. A machine is never invented, because + a mistyped number would create equipment nobody can account for. +- A second PC reporting a machine another PC holds is a CLAIM, not a handover. + A PC imaged for a machine carries that number before it reaches the floor, so + the PC currently running the machine keeps the link while it is still alive - + reporting within 24 hours (`MACHINE_CLAIM_QUIET_HOURS`) and still `In Use`. + The challenger is recorded as a dormant link, which also marks the claim as + already announced so it does not alert every cycle. +- Handover completes on its own once the incumbent has been quiet past that + window, or immediately when someone moves it off `In Use` - which is the + one-step way to force a swap at the moment it happens. The old link is + archived, never deleted, so "which PC ran this machine in June" stays + answerable. The retired PC's STATUS is deliberately not changed: the collector + cannot tell shelved from broken from re-imaged. +- Alerts for handover and contested claims are gated on the + `computers_machinelink_alerts` setting, which ships OFF. A site may run + several PCs on one machine number legitimately, and there the alerts fire on + correct data. Warnings ride in the collector response either way. + +A PC reporting `pctype = gea-shopfloor-partmarker` is handled differently, +because several markers can serve one machine number and an operation holds any +number of them. Such a PC gets its own Part Marker machine asset +(`-PARTMARKER`), `controls` it, and the marker is filed `partof` the +operation the PC reported. Both links are tagged `collector:partmarker`. The PC +does NOT claim the operation directly: `controls` propagates through `partof`, +so control still follows from controlling the marker, without two markers +contesting a link only one can hold. Backups from a marker PC file against the +marker rather than the operation. + ### PC -> printer relationship sync When a payload carries `defaultprinter` and/or `printers`, the collector syncs