The printer feature rests on one rule: a collector report is OBSERVED state and never ASSIGNED state. If a drifted bay's own state can become what it is told to install, enforcement stops meaning anything, because a bay that installed the wrong printer makes itself right simply by reporting it. _sync_printer_links broke that rule. It ran on every collector PC push and, when the payload carried defaultprinter or printers, wrote defaultprinter and connectedto rows from the report - defaultprinter being one of the two types _reconcile_edges is meant to own alone, from authenticated routes a human calls. It was recorded as dormant. It was not. The collector schema ADVERTISED both keys and the example client in COLLECTOR-INTEGRATION.md set $payload['defaultprinter'], so the documentation was recruiting callers for it - while the same document, under "Observed is not assigned", promised that nothing on this path writes a usesprinter or defaultprinter row. The document contradicted itself and the code followed the wrong half. Nothing in the fleet armed it, because the first-party reporter never sent those fields, but any third-party client written from the docs would have. Retired the function, its _sync_one helper and the now-unused PRINTER_LINK_ORIGIN label, and removed both keys from the schema. IGNORED, NOT REJECTED. Unknown payload keys are not validated, so a client written against the old docs keeps pushing successfully and only its printer keys stop doing anything. The response warns, naming the keys and pointing at POST /api/collector/printers for reporting queues and seed-from-observed for adopting them. Dropping them in silence would leave an integrator believing assignments were still being written, which is a worse failure than the one being fixed. The docs were the larger half of this. The schema table rows are gone, the "PC -> printer relationship sync" section is replaced by a note saying what happens now to anyone still sending the keys, and the example client no longer enumerates Win32_Printer at all - it points at Report-PrintersToShopDB.ps1, which posts to the observed endpoint and posts NOTHING on a failed enumeration, since an empty list would erase the host's rows. test_collector_printers.py pinned the old behaviour, so it now pins the opposite: the keys create no relationships, the push still succeeds and says why, a payload without them stays quiet, a human-made default survives a report naming a different printer, and the schema no longer offers the keys.
4.2 KiB
4.2 KiB
Project map
Derived from the code on every regeneration. If something here is wrong, the code changed and the map was not regenerated - fix it by running the generator, never by editing this file.
Versions
| series | value | governed by |
|---|---|---|
product __version__ |
0.12.0 |
ADR-007 |
plugin contract __contract_version__ |
0.20.0 |
ADR-002 |
They move independently. A contract bump is not a release.
Alembic chains (ADR-008)
Core runs with flask db upgrade; every plugin chain runs
with flask plugin upgrade-all. Both are needed on a deploy.
| chain | head |
|---|---|
| core | 7d34_singular_relationship_types |
| backups | backups0003clearlastseen |
| computers | computers0001anchor |
| employees | employees0002photo |
| geenforce | geenforce0004minlib |
| knowledgebase | knowledgebase0001anchor |
| machines | machines0002rename |
| measuringtools | measuringtools0001baseline |
| network | network0003prefix |
| notifications | notifications0005boardorder |
| printedparts | printedparts0004txnrev |
| printers | printers0005observedqueues |
| slides | slides0001anchor |
| tools | tools0001securesend |
| usb | usb0002dropmachineid |
| warranty | warranty0002proof |
Bundled plugins (15)
| plugin | version | core_version | owns migrations |
|---|---|---|---|
| backups | 1.0.0 | >=0.16.0,<1.0.0 | yes |
| computers | 1.0.0 | >=0.20.0,<1.0.0 | yes |
| employees | 1.0.0 | >=0.1.0,<1.0.0 | yes |
| geenforce | 0.1.0 | >=0.18.0,<1.0.0 | yes |
| knowledgebase | 1.0.0 | >=0.1.0,<1.0.0 | yes |
| machines | 1.0.0 | >=0.20.0,<1.0.0 | yes |
| measuringtools | 1.0.0 | >=0.20.0,<1.0.0 | yes |
| network | 1.0.0 | >=0.20.0,<1.0.0 | yes |
| notifications | 1.0.0 | >=0.1.0,<1.0.0 | yes |
| printedparts | 0.1.0 | >=0.16.0,<1.0.0 | yes |
| printers | 1.0.0 | >=0.20.0,<1.0.0 | yes |
| slides | 2.0.0 | >=0.2.0,<1.0.0 | yes |
| tools | 1.0.0 | >=0.16.0,<1.0.0 | yes |
| usb | 1.0.0 | >=0.1.0,<1.0.0 | yes |
| warranty | 1.0.0 | >=0.2.0,<1.0.0 | yes |
Manifest-less directories under plugins/ are core frontend surface and always ship: applications.
Architecture decisions
| ADR | title | status |
|---|---|---|
| ADR-001-asset-as-platform-contract.md | ADR-001: Asset model is the platform contract | ACCEPTED |
| ADR-002-plugin-versioning.md | ADR-002: Plugin contract versioning | ACCEPTED |
| ADR-003-plugin-distribution.md | ADR-003: Plugin distribution model | ACCEPTED |
| ADR-004-deployment-topology.md | ADR-004: Deployment topology (per-site instances) | ACCEPTED |
| ADR-005-equipment-vs-measuringtools.md | ADR-005: Equipment plugin scope vs measuringtools plugin | ACCEPTED |
| ADR-006-collector-contract.md | ADR-006: Plugin collector contract pattern | ACCEPTED |
| ADR-007-product-versioning-and-releases.md | ADR-007: Product versioning and releases | ACCEPTED |
| ADR-008-plugin-migration-ownership.md | ADR-008: Plugin migration ownership (per-plugin chains from the cutover) | ACCEPTED |
| ADR-009-frontend-plugin-gating.md | ADR-009: Frontend plugin gating | ACCEPTED |
| ADR-010-frontend-plugin-hooks.md | ADR-010: Frontend plugin hook contract | ACCEPTED |
| ADR-011-machines-rename.md | ADR-011: Rename the equipment domain to machines; retype the models catalog with modeltypes | ACCEPTED |
| ADR-012-geenforce-manifest-ownership.md | ADR-012: GE-Enforce manifest ownership in shopdb | ACCEPTED |
| ADR-013-plugin-catalog-and-lean-builds.md | ADR-013: Plugin Catalog, Curated Shelf, and Lean Per-Site Builds | ACCEPTED |
| ADR-014-schema-lean-per-site.md | ADR-014: Schema-lean per-site builds (retire cross-plugin FKs, lift plugin tables) | ACCEPTED |
| ADR-015-site-specific-configuration.md | ADR-015: Where a site's own data is allowed to live | ACCEPTED |
| ADR-016-credential-delivery.md | ADR-016: Credential delivery to the fleet | ACCEPTED (decided; NOT yet implemented - |
| ADR-017-buildings-and-levels.md | ADR-017: Buildings and levels as the map model | ACCEPTED |
Size
- test functions defined: 1233 (parametrised cases collect higher)
- documented API paths: 285 (
docs/openapi.json, regenerate withscripts/gen_openapi.py)