Add the printedparts plugin: 3D-printed parts storefront and kiosk
Catalog with photos and append-only print-file revisions, a stock ledger attributing every take/restock/adjust to a badge-resolved employee, a touch kiosk (scan bin, scan badge, keypad quantity) with a deliberately open decrement-only take endpoint, 1x0.5in CODE128 bin labels, low-stock email alerts to selected users, roles, or addresses, and stock/consumption/by-person reports with a cache-vs-ledger reconcile. Ships disabled; enable per site. Contract 0.13.0 adds the mailer and the User/Role models to the plugin surface.
This commit is contained in:
59
plugins/printedparts/README.md
Normal file
59
plugins/printedparts/README.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# 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 the PLUGIN-HOOKS wiki page. |
|
||||
| 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
|
||||
|
||||
```bash
|
||||
flask plugin install printedparts
|
||||
flask db migrate -m "Add printedparts plugin tables"
|
||||
flask db upgrade
|
||||
pytest plugins/printedparts/tests/
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- the PLUGIN-HOOKS wiki page - canonical hook reference
|
||||
- the PLUGIN-QUICKSTART wiki page - 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.
|
||||
Reference in New Issue
Block a user