# ShopDB Flask Project Modern rewrite of the classic-ASP shopdb. Built as a framework so sister GE Aerospace sites can adopt it. Plugin system is the product. ## Database - **Active database:** `shopdb_flask` (MySQL, asset-based schema) - **Legacy database:** `shopdb` (Classic ASP schema, used only for one-time data import via `scripts/import_from_mysql.py`) - **Connection:** `.env` file. See `.env.example`. Architecture decisions live in `migrations/adr/`. Read those before making schema or contract changes. - ADR-001: Asset model is the platform contract (Machine retires) - ACCEPTED - ADR-002: Plugin contract versioning (semver) - ACCEPTED - ADR-003: Plugin distribution model (in-tree bundled + filesystem-based external) - ACCEPTED - ADR-004: Deployment topology (per-site instances, not multi-tenant) - ACCEPTED - ADR-005: Equipment vs measuringtools plugin scope - ACCEPTED - ADR-006: Plugin collector contract pattern - ACCEPTED ## Coding convention `CONTRIBUTING.md` defines naming rules (DB tables, columns, Python, JS, Vue, API). Pre-commit hook at `scripts/check-naming-and-style.sh` enforces them. Read `CONTRIBUTING.md` before naming any new identifier. ## Current state (as of 2026-05-08) ### Wired in - App factory pattern, Flask 3 + SQLAlchemy + Flask-Migrate + JWT + Marshmallow + CORS + Caching - 6 plugins: computers, equipment, network, notifications, printers, usb - Plugin contract: `BasePlugin` ABC, `PluginMeta`, registry, dependency-aware loader - JWT auth with refresh tokens, audit logging, system settings, user management - Frontend: Vue 3 + Pinia + Vite, dynamic plugin routing, dark mode default - Search across all plugins via `get_searchable_fields` hook - Asset relationships (cross-plugin) ### In progress / partial - **Dual model coexistence**: legacy `Machine` and new `Asset` both live. ADR-001 settles direction (Asset wins). Migration plan is the next concrete deliverable. - **Plugin verification**: 6 plugins follow `BasePlugin` interface but no contract test asserts compliance. Skill `enforcing-plugin-contract` and the contract test suite are pending. - **Tests**: hollow. `tests/conftest.py` exists but uses Flask-SQLAlchemy 2.x patterns that error on 3.x. No actual test files. Skill `pinning-flask-behavior` covers the rebuild. ### Pending - Alembic versions directory exists (`migrations/versions/`) but is empty. No migrations have been generated yet. Run `flask db init` is partial; need `flask db migrate` to capture current schema. - Plugin scaffold CLI (`flask plugin new `) - Plugin author docs (`docs/PLUGIN-QUICKSTART.md`, `docs/PLUGIN-REFERENCE.md`) - Per-site deploy story (`Dockerfile`, `docs/DEPLOY.md`) - Frontend hook contract (asset-detail, map markers, search results) ## Quick start ```bash # Start dev environment ~/start-dev-env.sh # Activate venv and install deps cd /home/camp/projects/shopdb-flask source venv/bin/activate pip install -r requirements.txt # Configure environment cp .env.example .env # Edit .env with DB credentials, JWT secrets # Create / update database tables flask db-utils create-all # Seed reference data flask seed reference-data # Restart services pm2 restart shopdb-flask-api shopdb-flask-ui ``` ## Service URLs - Flask API: http://localhost:5001 - Flask UI: http://localhost:5173 - Legacy ASP (data source for one-time import): http://192.168.122.151:8080 ## Plugin structure ``` plugins/ / __init__.py plugin.py # BasePlugin implementation manifest.json # Plugin metadata (name, version, dependencies, api_prefix) models/ __init__.py # Export all models .py # SQLAlchemy models api/ __init__.py routes.py # Flask Blueprint services/ # Optional, business logic schemas/ # Optional, marshmallow schemas migrations/ # Optional, plugin-specific Alembic migrations ``` Each plugin must have: - `models/__init__.py` exports all models - `plugin.py` extends `BasePlugin` - `manifest.json` with metadata (single source of truth per ADR-002) - No direct imports from core code (use the contract surface defined in ADR-001) ## Key files - `shopdb/__init__.py` - app factory, blueprint registration - `shopdb/plugins/base.py` - BasePlugin ABC, PluginMeta dataclass - `shopdb/plugins/loader.py` - filesystem discovery, dependency-aware loading - `shopdb/core/api/assets.py` - example of optional plugin imports - `frontend/src/router/index.js` - frontend routing - `frontend/src/components/AppSidebar.vue` - navigation menu - `migrations/adr/` - architecture decision records ## Migration notes - `migrations/DATA_MIGRATION_GUIDE.md` - one-time import from legacy ASP shopdb - `migrations/MIGRATE_USB_DEVICES_FROM_EQUIPMENT.md` - USB device migration from equipment table - `migrations/FIX_LOCATIONONLY_EQUIPMENT_TYPES.md` - LocationOnly equipment type fix - `migrations/PRODUCTION_MIGRATION_GUIDE.md` - production import methods - `migrations/rename_underscore_columns.sql` - one-time rename of snake_case columns to lowercase concatenated (per CONTRIBUTING.md) - `migrations/versions/` - Alembic versions (currently empty)