Files
shopdb-flask/docs/PROJECT-MAP.md
cproudlock c8efadefba
Some checks failed
CI / naming (push) Successful in 1m52s
CI / frontend (push) Successful in 2m12s
CI / migrations-mysql (push) Failing after 4m13s
CI / backend (push) Has been cancelled
An HTML article can become a guide
A site adopting this app arrives holding procedures already written: styled
HTML pages that get mailed around, opened off a share, and edited by whoever
still has the file. Those pages are exactly what a guide is for, and retyping
one into the editor is how a good procedure stays on a share forever.

flask guides import-html reads the page and produces blocks. It recognises the
vocabulary those pages actually use - a step box with its own number, an alert
in one of three colours, a code block with a copy button, a checkbox list, a
table with a header row - and maps each to the block that already renders it,
lifting embedded images into guideimages so a document stops carrying its
screenshots as base64. Page furniture goes: the header, the footer, and the
table of contents a guide builds for itself from its own headings.

The conversion is lossy on purpose. Colour, fonts, width and nested layout are
dropped, because storing blocks rather than markup is what makes dark mode,
printing and tickable steps work at all. So an import is always a DRAFT and the
default is a dry run that reports what it would produce and writes nothing.
Blocks go through the same validator the API uses: an import must not be able
to store something the editor could not have produced.

The parser is tolerant, because real articles are not well-formed. An unclosed
<p> is normal HTML and the browser closes it at the next block element; without
the same rule one unclosed tag swallows the rest of the article into a single
paragraph, which is what it did before the test caught it.

Proven end to end against four real articles, including one carrying two PNG
screenshots, read back in a browser.
2026-08-27 11:27:19 -04:00

94 lines
4.3 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.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` |
| guides | `guides0001baseline` |
| knowledgebase | `knowledgebase0001anchor` |
| machines | `machines0002rename` |
| measuringtools | `measuringtools0001baseline` |
| network | `network0003prefix` |
| notifications | `notifications0005boardorder` |
| printedparts | `printedparts0004txnrev` |
| printers | `printers0005observedqueues` |
| slides | `slides0001anchor` |
| tools | `tools0001securesend` |
| usb | `usb0002dropmachineid` |
| warranty | `warranty0002proof` |
## Bundled plugins (16)
| 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 |
| guides | 1.0.0 | >=0.1.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: **1386** (parametrised cases collect higher)
- documented API paths: **305** (`docs/openapi.json`, regenerate with `scripts/gen_openapi.py`)