# ShopDB Flask Project Modern rewrite of the classic-ASP shopdb. Built as a framework so sister GE Aerospace sites can adopt it. The plugin system is the product. **This site is not the only site.** Anything that names West Jefferson - a hostname, a share path, a subnet, a machine-number format, a label prefix - is a defect unless it is a setting with a neutral default, a site-namespaced directory, or seed data. That is ADR-015, and it is the rule most often broken in the places tooling cannot see: PowerShell, the installer, JSON, the imaging share. ## Facts that move live in the map `docs/PROJECT-MAP.md` is GENERATED. It carries the product and contract versions, the plugin inventory, every Alembic chain head, the ADR index with status, and the size of the codebase. Read it instead of asking; regenerate it rather than correcting it by hand: ```bash venv/bin/python scripts/gen_project_map.py # write venv/bin/python scripts/gen_project_map.py --check # CI form ``` Hand-written version numbers in this file were wrong by two contract releases and 400 tests before the map existed. Nothing that the generator can derive should be typed here again. ## Where to look | question | read | |---|---| | what a name may be called | `CONTRIBUTING.md` | | why the architecture is like that | `docs/adr/` (index in the map) | | what a plugin may touch | `docs/PLUGIN-HOOKS.md` | | what the collector sends | `docs/COLLECTOR-INTEGRATION.md`, ADR-006 | | how a site is deployed | `docs/INSTALL-WINDOWS.md`, `docs/OPERATE-WINDOWS.md` | | how code reaches GitHub | `tools/export-github.sh` | ## Standards are gates, not prose Compliance is checked, not remembered. Run these rather than re-reading the rules: ```bash bash scripts/check-naming-and-style.sh # naming, style, site literals (ADR-015) venv/bin/python -m pytest -q # includes the docs publishability gate venv/bin/python -m pytest tests/test_plugin_migrations.py # chain heads registry venv/bin/python scripts/gen_project_map.py --check ``` A new plugin table means updating `PLUGIN_TABLE_OWNERS` and `EXPECTED_HEAD_REVISION` in `tests/test_plugin_migrations.py`. ## Database - **Active:** `shopdb_flask` (MySQL, asset-based schema) - **Legacy:** `shopdb` (classic ASP schema; one-time import only) - **Connection:** `.env`, see `.env.example` Core migrations run with `flask db upgrade`; every plugin owns its own chain (ADR-008) and runs with `flask plugin upgrade-all`. **A deploy needs both** - skipping the second is how a new column reaches production as a 1054 error. Tests run on SQLite, production is MySQL. Dialect drift is not caught by the suite: `ORDER BY ... NULLS LAST` parses on SQLite and is rejected by MySQL. Sort in Python when in doubt. ## Coding convention `CONTRIBUTING.md` is authoritative: lowercase concatenated DB columns, snake_case pure-code identifiers, a closed acronym list, banned shorthand. The pre-commit hook `scripts/check-naming-and-style.sh` enforces what it can. ## Plugin structure ``` plugins// manifest.json # metadata, single source of truth (ADR-002) plugin.py # BasePlugin implementation models/ # __init__.py exports every model api/routes.py # Flask blueprint migrations/ # this plugin's own Alembic chain services/ schemas/ frontend/ client/ # as needed ``` No plugin imports core directly - everything goes through the `shopdb.api` contract surface. A manifest-less directory under `plugins/` is core frontend surface and always ships. ## Key files - `shopdb/__init__.py` - app factory, version constants - `shopdb/plugins/base.py` - BasePlugin, PluginMeta - `shopdb/plugins/loader.py` - discovery and dependency-aware loading - `shopdb/plugins/alembic_template.py` - the env every plugin chain runs through - `frontend/src/router/index.js`, `frontend/src/components/AppSidebar.vue` - `tools/export-github.sh` - scrub and publication gate ## State Refactor phases 0-5 landed; phase 6 (multi-site distribution readiness) largely complete. The last milestone before 1.0 is unchanged and still open: the legacy-data import plus a production pilot (`scripts/site_imports/wjf/` is the reference loader, validated end to end). Pre-1.0 framework. Sister sites pin tight `core_version` ranges until the contract reaches 1.0. ### Deferred - Equipment data migration (legacy ASP -> assets). Per ADR-001 only `category='Equipment' AND machinenumber IS NOT NULL` migrates. - Printers retirement: legacy `PrinterData` model, coordinated with the above. ## Quick start ```bash source venv/bin/activate pip install -r requirements.txt cp .env.example .env # DB credentials, JWT secrets flask db upgrade # core chain flask plugin upgrade-all # every plugin chain flask seed permissions && flask seed settings && flask seed reference-data pm2 restart shopdb-flask-api shopdb-flask-ui ``` Dev API on :5001, dev UI on :5173. `venv/bin/python tools/shot.py /route` logs in and screenshots a page.