Files
shopdb-flask/plugins/printedparts
cproudlock aa4bfcd41c
Some checks failed
CI / backend (push) Successful in 1m44s
CI / naming (push) Successful in 2s
CI / frontend (push) Successful in 8s
CI / migrations-mysql (push) Failing after 7s
printedparts stage 15: print-file revision history + role-based alerts
printeditemfiles lands as the plugin's first incremental migration
(0002 on the plugin chain - the ADR-008 payoff). Revisions are
append-only per item: upload assigns the next number, records the
uploader from the JWT, enforces an extension allowlist and a 100 MB
cap; download serves the original filename; a permission-gated delete
covers wrong-file mistakes. The detail page gains the revision table
with a current badge. Unique storedfilename is sized 191 so the index
fits MySQL's 767-byte prefix - the per-plugin chain does not apply the
core env's ROW_FORMAT hook.

Alert recipients gain roles: Role joins the 0.13.0 surface, a role
picker on the settings page, and every active member of the selected
roles is folded into the deduped recipient list.
2026-07-17 08:47:41 -04:00
..

Printedparts plugin

3D-printed parts inventory + kiosk checkout

This plugin was generated by flask plugin new printedparts. It satisfies the framework contract out of the box. Replace the example model and routes with your domain.

What's here

  • plugin.py - the PrintedpartsPlugin class extending BasePlugin. Edit init_app for custom setup, on_install to seed reference data.
  • models/printedparts.py - example Asset extension table. Replace examplefield with your domain fields.
  • api/routes.py - example list and detail endpoints. Add CRUD as needed.
  • schemas/__init__.py - marshmallow schema stub for request/response validation.
  • tests/test_plugin.py - smoke tests asserting contract compliance.
  • manifest.json - plugin metadata. Bump version on changes; keep core_version range broad.

Common edits

You want to... Do this
Add a hook (search, navigation, dashboard widget) Override the method in PrintedpartsPlugin. See docs/PLUGIN-HOOKS.md.
Accept external collector data Override get_collector_schema() to return a JSON Schema. See ADR-006.
Add another model Create models/<other>.py, export it in models/__init__.py, return it in get_models().
Add a CLI command Override get_cli_commands() returning a list of Click commands.

Frontend

Vue components for this plugin live under frontend/src/views/printedparts/ (per project convention). Backend scaffolding does not generate frontend yet; copy from an existing plugin's view files (e.g., frontend/src/views/network/) as a starting point.

Install and run

flask plugin install printedparts
flask db migrate -m "Add printedparts plugin tables"
flask db upgrade
pytest plugins/printedparts/tests/

References

  • docs/PLUGIN-HOOKS.md - canonical hook reference
  • docs/PLUGIN-QUICKSTART.md - 30-minute walkthrough
  • migrations/adr/ADR-001-asset-as-platform-contract.md - the platform contract
  • migrations/adr/ADR-002-plugin-versioning.md - versioning rules

Why the kiosk take endpoint is unauthenticated

POST /api/printedparts/kiosk/take is the product's first open WRITE (every other kiosk endpoint is a read). Accepted deliberately, against the criteria in docs/proposals/printedparts-plugin.md:

  1. Decrement-only: it can reduce stock of an active item, nothing else.
  2. Fully attributed: it refuses to act without a badge that resolves under the site policy; every action lands in the ledger with SSO + name + time.
  3. Bounded blast radius: worst case is stock counts driven low - visible in the ledger and reversible with an adjust.
  4. Physically rate-limited: it serves a touch screen on the shop floor; nothing enumerable, nothing worth scraping.

Any future open-write endpoint must clear the same bar.