Files
shopdb-flask/plugins/printedparts
cproudlock 6ed3da1b64
Some checks failed
CI / backend (push) Failing after 1m43s
CI / naming (push) Successful in 2s
CI / frontend (push) Successful in 8s
CI / migrations-mysql (push) Failing after 8s
printedparts stage 7: the kiosk - scan bin, scan badge, keypad, take
Two open endpoints: an item lookup by scanned code and the take POST -
the product's first unauthenticated write, held to the decision
record's bar (decrement-only, badge-attributed server-side, bounded,
physically rate-limited; justification in the plugin README). The
/parts-kiosk route is a full-screen no-auth view beside /shopfloor: a
hidden always-focused input consumes keyboard-wedge scans for
whichever step is active, TouchKeypad (net-new 3x4 grid) takes the
quantity, and a success screen resets after a few seconds. Manual
type-in fallbacks cover damaged labels. Kiosk test proves open access,
the over-take guard, the badge policy, and cache==ledger afterward.
2026-07-17 07:49:13 -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.