The map was one picture of one floor. A second floor was added, the blueprint changed size, and machines moved, so a position now records WHICH DRAWING its coordinates belong to. Buildings and levels (ADR-017). Each level owns its blueprint per theme and its own native pixel size; assets.mapx/mapy are pixels of assets.levelid, not of the site. A position whose level is unknown renders "level unknown" and is never drawn on the default level, because a marker on the wrong floor plan looks entirely correct while pointing at the wrong place. Repositioning in bulk: filter by unplaced, needs-review or level, search, place, confirm. Landmark recalibration solves the transform PER AXIS from landmark pairs and never from image dimensions - the canvas grew taller without rescaling, so a dimension-derived scale would stretch Y by 1.57 and be wrong everywhere. It defaults to a dry run, reports what would land off the drawing, snapshots before applying, and clears mapverifiedat because a transform is a guess awaiting review. Snapshots restore, including the level and the review state, and a restore snapshots first so an undo is undoable. Search: gaugelabreference was matched only for measuring tools and maintenancereference was matched nowhere at all, for any asset type, while Settings happily offers both identifiers on machines and PCs. A tag an operator is told to record has to be findable or it is a write-only field. USB devices and printed items were unreachable from search entirely - neither is an asset, so the generic asset search could not see them and no searcher existed; they now match on serial, asset tag, label, bin code and gage-lab tag, honouring isactive, with Settings toggles and result labels to match. The retired-application rule was half a rule: GET /api/knowledgebase hid articles whose topic application is retired while global search still returned them and printed the retired application as the subject. A filter is only real if every path that reaches the row applies it. Contract to 0.20.0 (additive): Asset gained levelid and mapverifiedat, Location gained levelid, and resolve_asset_position returns the levelid belonging to whichever source supplied the coordinates. The five plugins that write a map position are re-pinned. The install-list text format gained levelid as a NINTH field, appended, because the shipped Pascal installer reads fields 0-7 by index. That installer still compiles in one drawing's dimensions and bundles one blueprint, so its map is accurate for the default level only; /api/maplevels is deliberately unauthenticated so it can read both at runtime once rebuilt. Recorded in PRINTER-INSTALLER.md section 6 along with the other known gaps. Migration 7d33 converts an existing single-map site into one building and one default level carrying the old map_* settings, then assigns every placed asset and location to it. Nothing moves on screen. Old settings rows are kept so a rollback still finds them. Verified end to end on MySQL 5.6 from a production-shaped database.
91 lines
4.2 KiB
Markdown
91 lines
4.2 KiB
Markdown
<!-- GENERATED by scripts/gen_project_map.py - do not edit by hand.
|
|
Regenerate with: venv/bin/python scripts/gen_project_map.py -->
|
|
|
|
# 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.10.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 | `7d33_buildings_and_levels` |
|
|
| backups | `backups0003clearlastseen` |
|
|
| computers | `computers0001anchor` |
|
|
| employees | `employees0002photo` |
|
|
| geenforce | `geenforce0004minlib` |
|
|
| knowledgebase | `knowledgebase0001anchor` |
|
|
| machines | `machines0002rename` |
|
|
| measuringtools | `measuringtools0001baseline` |
|
|
| network | `network0003prefix` |
|
|
| notifications | `notifications0005boardorder` |
|
|
| printedparts | `printedparts0004txnrev` |
|
|
| printers | `printers0002supplyalerts` |
|
|
| slides | `slides0001anchor` |
|
|
| 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 | no |
|
|
| 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: **1084** (parametrised cases collect higher)
|
|
- documented API paths: **276** (`docs/openapi.json`, regenerate with `scripts/gen_openapi.py`)
|
|
|