Addresses findings from a 6-lens review against the project skills
(defining-asset-contract, enforcing-plugin-contract, hardening-flask-config,
integrating-plugin-hooks, pinning-flask-behavior, simplifying-python).
Security (hardening-flask-config):
- Load per-plugin COLLECTOR_API_KEY_<PLUGIN> from env in create_app. from_object
only copies class attributes, so per-plugin keys (ADR-006) were dead in real
deploys and silently fell back to the shared key.
- EMPLOYEE_DB_USER/PASSWORD no longer default to root/rootpassword (no safe
default for a secret; unset fails loud). Documented in .env.example + DEPLOY.md.
- COLLECTOR_API_KEY + per-plugin + EMPLOYEE_DB_* added to .env.example/DEPLOY.md.
Hook isolation (integrating-plugin-hooks):
- collector _collector_plugins and dashboard get_navigation now re-raise in
dev/test and log+isolate in prod, instead of silently swallowing a broken
plugin hook.
Plugin loader (enforcing-plugin-contract):
- enable_plugin/install_plugin read dependencies+version from the manifest
instead of instantiating the plugin class.
- _register_plugin_components rejects a second plugin claiming an already-used
api_prefix (reset per app in init_app).
Tests (pinning-flask-behavior):
- test_identifiers.py: gauge/maintenance round-trip on computer/printer/network
create+update; per-type seed yields the 12 identifier keys.
- contract tests for apply_collector_payload presence + schema-declarers-implement.
- security tests for per-plugin key env loading + no employee-db password default.
Docs/contract sync (defining-asset-contract):
- PLUGIN-HOOKS.md documents apply_collector_payload; stale 0.2.0 -> 0.3.0.
- ADR-006 documents apply_collector_payload + single-dispatch rationale.
- ADR-001 enumerates the expanded shopdb.api import surface.
Simplify (simplifying-python):
- De-duplicate the 21-entry settings defaults: shared build_default_settings()
used by both the /settings/seed route and the CLI (were drifting copies).
- Remove dead AssetStatus import + redundant AssetType local import in computers
plugin; comment the statusid=1 collector default.
153 tests pass (was 145), naming/style green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The nav endpoint now skips disabled plugins (checks the registry), so disabling
a plugin removes it from the menu right away without a restart. Its API routes
remain registered until the next restart (Flask cannot unregister a blueprint
at runtime), but users no longer see links to it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Dashboard counts assets by type/status (Asset/AssetType/AssetStatus); adds
a printer count to the totals.
- Software-compliance and pc-relationships reports query Computer /
ComputerInstalledApp / assetrelationships instead of Machine.
Removes the dashboard + reports read dependency on the Machine model. (The
software-compliance report has a separate pre-existing bug: Application has no
isrequired field, so it errors before the query runs - unrelated to this change.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Fix equipment badge barcode not rendering (loading race condition)
- Fix printer QR code not rendering on initial load (same race condition)
- Add model image to equipment badge via imageurl from Model table
- Fix white-on-white machine number text on badge, tighten barcode spacing
- Add PaginationBar component used across all list pages
- Split monolithic router into per-plugin route modules
- Fix 25 GET API endpoints returning 401 (jwt_required -> optional=True)
- Align list page columns across Equipment, PCs, and Network pages
- Add print views: EquipmentBadge, PrinterQRSingle, PrinterQRBatch, USBLabelBatch
- Add PC Relationships report, migration docs, and CLAUDE.md project guide
- Various plugin model, API, and frontend refinements
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Flask backend with Vue 3 frontend for shop floor machine management.
Includes database schema export for MySQL shopdb_flask database.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>