# ShopDB Flask - Claude Code Context ShopDB is a manufacturing floor asset management system built with Flask, Vue 3, and PostgreSQL, deployed across air-gapped GE Aerospace sites. ## Architecture - **Backend**: Flask 3.x with SQLAlchemy 2.x, plugin-based architecture - **Frontend**: Vue 3 with Vite, component-based UI with plugin panels - **Database**: PostgreSQL 15+ with Alembic migrations per plugin - **Deployment**: Docker Compose with gunicorn, air-gapped sites via bundle workflow - **Plugins**: 20+ plugins (computers, endpoints, printers, machines, etc.) ## Critical Constraints ### ADR-015: Site-Specific Configuration Site literals (building names, printer models, machine types) MUST live in: - `shopdb/core/settings/` - Site settings (buildings, roles, etc.) - `shopdb/core/seed/` - Initial data SQL - `scripts/site_imports/` - Import tools for Maximo/WINC data NEVER hardcode site-specific data in plugin code or migrations. ### ADR-008: Plugin Migration Ownership Each plugin owns its migration chain in `plugins/{name}/migrations/versions/`. - Migrations run in dependency order defined in PLUGIN_TABLE_OWNERS - Each plugin's chain must be linear (no branches) - Migrations run automatically on deploy ### Database Naming Convention - **Tables**: lowercase concatenated, no underscores (e.g., `printedpart`, `mappeddrives`) - **Columns**: snake_case (e.g., `serial_number`, `last_seen`) - **Indexes/constraints**: follow PostgreSQL conventions - Enforced by `scripts/check-naming-and-style.sh` pre-commit hook ### Branch and Deployment Model - `wj` -> prod (shop floor at WJ site) - `dev` -> ops (monitoring/pilot sites) - `main` -> nothing (GitHub public mirror only) - Three air gaps: dev PC <-> work PC <-> GitHub - Bundles carry code across gaps (pull-shopdb-bundle.cmd, fetch-wilm-branch.cmd) ### Code Style - Plain ASCII only - no unicode, emojis, or em-dashes - No LLM attribution comments (no "Co-Authored-By: Claude") - Minimal comments - code should be self-documenting - No banned shorthand (e.g., "config" not "cfg", "initialize" not "init") ## Plugin Contract Plugins extend ShopDB via: - `plugin.py` - BasePlugin subclass with manifest, routes, hooks - `models/` - SQLAlchemy models - `api/` - Flask blueprints and routes - `frontend/views/` - Vue components auto-discovered by router - `migrations/versions/` - Alembic migrations Import from `shopdb.api` for stable surfaces: ```python from shopdb.api import db, Asset, Employee, BasePlugin ``` ## Documentation Full documentation in the GitHub wiki at `../shopdb-flask.wiki/`: **Critical ADRs**: - ADR-001: Asset as platform contract - ADR-004: Deployment topology (air-gapped sites) - ADR-006: Collector contract (endpoint agent) - ADR-007: Product versioning and releases - ADR-013: Plugin catalog and lean builds - ADR-016: Credential delivery **References**: - `API-REFERENCE.md` - Core API surface - `PLUGIN-DEVELOPMENT.md` - Plugin authoring guide - `DEPLOYMENT.md` - Deploy runbooks per site - `TESTING.md` - Test patterns and CI ## Development Workflow 1. Feature branches off `dev` or `wj` 2. **Run tests**: `pytest -v` (REQUIRED before claiming completion) 3. **Check naming/style**: `scripts/check-naming-and-style.sh` (REQUIRED before commit) 4. Bundle for other PC or push to GitHub 5. PR to `wj` (for prod) or `dev` (for ops) ## Boundaries & Constraints **DO NOT**: - Edit generated files (frontend/dist/, docs/openapi.json) - Change dependencies (requirements.txt, package.json) without approval - Commit code with unicode/emojis (plain ASCII only) - Hardcode site-specific data (buildings, models, etc.) - use settings/seed - Skip tests or pre-commit hooks - Break plugin migration chains (keep linear, coordinate via PLUGIN_TABLE_OWNERS) **ALWAYS**: - Run `pytest -v` before claiming work complete - Run `scripts/check-naming-and-style.sh` before committing - Use `shopdb.api` imports, not internal paths - Keep database table names lowercase concatenated - Reference ADRs by number when making architectural decisions - Verify bundle/deploy scripts work before pushing to branches ## Testing Patterns - Feature tests in `tests/test_plugins/test_{plugin}_{feature}.py` - Use fixtures from `conftest.py` (app, client, db_session) - Test migrations with `test_plugin_migrations.py` - Frontend specs alongside components: `*.spec.js` ## Common Pitfalls - **Site data in code**: Use settings/seed, not hardcoded values - **Migration conflicts**: Keep plugin chains linear, coordinate with PLUGIN_TABLE_OWNERS - **Unicode**: ASCII only - check logs, comments, commit messages - **Import surface**: Use `shopdb.api`, not internal paths - **Device tokens**: Kiosks require device_token authentication (ADR-016) ## Work PC Role This machine (work PC): - Has GitHub credentials (ge-aero/shopdb-flask) - Carries bundles between dev PC and GitHub - Deploys to prod and ops servers - Mirrors wilm branch from GitHub to gitea For active development, use the dev PC with gitea.