Files
shopdb-flask/docs/ROADMAP.md
cproudlock ad9210b84a Write down the tool that was built, not the one that was tabled
Secure Send shipped on 21 August and nothing outside the code caught up. The
roadmap still listed it under Deferred as "tabled", and gave as the reason that
the tools plugin is browser-only by design with get_blueprint and get_models
both empty - which stopped being true in the same day's commits that gave it a
blueprint, a table, a migration chain, a permission and a setting. A reader
following the roadmap would have concluded the feature does not exist.

The generated API docs were fine: api-inventory.json and openapi.json both
carry /api/tools/secrets, so the contract gates did their job. What was missing
was every word written for a person, and that is the half where the security
properties live.

docs/SECURE-SEND.md is the new page. The parts worth having in prose rather
than inferring from the code: that a lost secret is lost to everybody including
an administrator, which is the same property as "a compromised database yields
nothing" seen from the other side; that the 4096-character limit is the entire
server-side enforcement, because a server that cannot read what it holds cannot
have an opinion about content, so raising it turns a password tool into an
unaudited file transfer; that redeeming is a POST because preview prefetch in
chat and mail clients would otherwise spend a one-view secret before the
recipient ever sees it; and that somebody should send a link to themselves
through their own mail or chat client and confirm the key survives after the #
before a real credential goes through it, because a product that rewrites links
can strip the fragment and nothing on this side can help.

securesend_allow_guests was in the database, on a settings page, and in no
document. It is now in CONFIG.md with what it actually does - an unauthenticated
write endpoint, rate limited per address, failing closed - rather than only its
one-line description.

Also corrected along the way: site_base_url was documented as scheme + host
while the code deliberately tolerates a subpath in it, and the bundled plugin
table in PLUGINS.md had no row for tools at all.

Still missing after this: PLUGINS.md has no row for backups either.
2026-08-24 08:37:25 -04:00

6.7 KiB

Roadmap

shopdb-flask is pre-1.0 on both series. Current contract and product versions are in PROJECT-MAP.md, which is generated from the code rather than typed here. This document captures what stands between today and a stable 1.0.0 release. Maintained as scope evolves; supersedes nothing in the ADRs.

Phase status

Phase Status Commit
0 - Lock platform contract, naming, style enforcement DONE d6725c0
1 - pytest baseline, production hardening, pinned requirements DONE 2d1bb83
2 - Plugin contract surface and compliance tests DONE 5fefb53
3 - Manifest-first loader, shopdb.api namespace, auto-register blueprints DONE 6f085a1
4 - Plugin scaffolding (flask plugin new) DONE 8eb9362
5 - Alembic baseline, per-site deploy, ADRs to docs/adr DONE d4e3ac9
6 - Multi-site distribution readiness (settings-driven branding/ServiceNow/floor plan, security closeout, docs + Docker frontend build, release engineering) DONE v0.5.0-v0.7.0

The last big milestone before 1.0 is the legacy-ASP data import plus a production pilot deployment; the framework work below is what remains after that.

What's left before tagging 1.0.0

Must-have

  • Asset model fully wired. Asset.mapx, Asset.mapy columns, AssetRelationship.inheritsposition column, and the relationshiptypepropagations M:N table (RelationshipTypePropagation model; propagation lives on RelationshipType, not AssetRelationship). Models match the locked ADR-001 surface that resolve_asset_position already targets.
  • Equipment data migration script for facilities migrating from legacy ASP shopdb. One-shot script under scripts/migration/. Per ADR-001, only category='Equipment' AND machinenumber IS NOT NULL migrates.
  • Printers retirement. The printers plugin already runs on the asset architecture (blueprint printers_asset_bp); any remaining legacy printer-table cleanup is coordinated with the equipment migration.
  • External plugin UI packaging. The Vue-side hook contract ships (ADR-010: get_settings_cards / get_asset_panels / get_map_overlays / get_asset_presentation) and route gating is backend-driven (ADR-009), but plugin routes/views still live in core frontend/src. Let an external plugin ship its own Vue bundle so adopters can add UI without editing core.

Nice-to-have

  • Full palette theming. brand_primary_color and a few brand colors are settings-driven, but the rest of the CSS palette (surfaces, borders, accents) is still hardcoded in style.css. A complete theming pass would expose the palette as CSS variables a site can override, not just the brand colors.
  • Frontend scaffolding skill (the backend has flask plugin new; the frontend stub is currently manual copy-paste).
  • Marketplace listing site (PLUGINS.md is a one-pager; a proper listing with links to sister-site plugins becomes useful when there are more than three external plugins).
  • Plugin contract surface diff tooling. Today version bumps are manual judgment; a CI check that diffs the contract surface against the previous tag would catch missed bumps. See ADR-002.
  • Calibration cycles, maintenance windows, downtime tracking (domain extensions; would likely live in the machines and measuringtools plugins).

Deferred (out of scope for 1.0)

  • Multi-tenancy (rejected by ADR-004; revisit only if more than five sites adopt and operational overhead becomes painful).
  • Pip-installable plugins (deferred per ADR-003 v2). Filesystem distribution stays the v1 model.
  • Event bus on BasePlugin (removed per ADR-001; add via new ADR if a real use case appears).
  • Frontend rebuild beyond Vue 3 + Pinia + Vite (the existing stack is fine).
  • File sharing by expiring link. The secret half of this shipped as Secure Send in the tools plugin (SECURE-SEND.md); the file half was dropped deliberately and stays out of scope. Dropping it removed the export-control question entirely - a password is not technical data - along with blob storage and the need to authenticate the recipient. What would have to be settled before it comes back, so nobody rediscovers it: a FILE recipient should be logged in too, which costs nothing on an intranet-only server where everyone with the link already has an account; sharing a file wants its own permission separate from sharing a secret, because the risk classes differ; and zero-knowledge encryption is right for a credential but questionable for a controlled document, where "the server cannot say what was in it" is a liability rather than a feature. Export control should confirm internal link sharing in writing before anything here carries drawings or NC programs.

What 1.0.0 means

Tagging 1.0.0 is a commitment that the contract surface is stable for at least the next minor version cycle. Plugin authors at sister sites can pin core_version: ">=1.0.0,<2.0.0" and trust their plugin will not break on framework patches.

Concretely, 1.0.0 ships when:

  1. ADR-001's full contract surface is implemented in code, not just documented (Asset.mapx, RelationshipType.propagatesthroughid, etc.)
  2. The contract test suite covers every documented hook with both happy-path and a "broken plugin" failure-isolation test
  3. At least one external plugin (likely measuringtools from the scaffold canary) has been built end-to-end with no contract changes required mid-build
  4. The deploy runbook (DEPLOY.md) has been validated by an actual fresh-host deploy

Decision log pointers

When a roadmap item gets prioritized, document the why in a new ADR and link from this file. The ADRs are the canonical source for design decisions; this file is the prioritized backlog.

  • ADR-001 - Asset as platform contract
  • ADR-002 - Plugin contract versioning
  • ADR-003 - Plugin distribution model
  • ADR-004 - Deployment topology (per-site)
  • ADR-005 - Equipment vs measuringtools
  • ADR-006 - Collector contract pattern
  • ADR-007 - Product versioning and releases
  • ADR-008 - Plugin migration ownership (per-plugin chains)
  • ADR-009 - Frontend plugin route gating
  • ADR-010 - Frontend plugin hook contract
  • ADR-011 - Machines rename + modeltypes retyping
  • ADR-012 - GE-Enforce manifest ownership