Phase 0: lock platform contract, naming convention, and style enforcement
Establishes the framework's foundation as a multi-site adoptable platform. ADRs (migrations/adr/): - ADR-001 (ACCEPTED): Asset is the platform contract; Machine retires. Three relationship types (partof, controls, connectedto) with free-text label, position-resolution chain (asset > related > location), hierarchical locations, sibling-bay propagation. - ADR-002 (ACCEPTED): Plugin contract semver via __contract_version__. - ADR-003 (ACCEPTED): Hybrid plugin distribution (in-tree bundled + filesystem-based external). - ADR-004 (ACCEPTED): Per-site instances, not multi-tenant. - ADR-005 (ACCEPTED): Equipment plugin (manufacturing) split from measuringtools plugin (metrology). Subtype-table pattern for protocol data (FOCAS, CLM, MTConnect). - ADR-006 (ACCEPTED): Plugin collector contract via get_collector_schema hook with API-key auth and identity-based upsert. Naming convention v1 (CONTRIBUTING.md): - DB tables/columns: lowercase concatenated, no underscores or dashes - DB-mirrored Python/JS variables match column names exactly; pure code follows host-language convention (PEP 8 / camelCase) - Closed acronym allowlist (universal + shop-floor domain), banned shorthand list with suffix exception (printers_bp etc allowed) - Plain ASCII everywhere: chat, docs, comments, string literals Style enforcement (scripts/check-naming-and-style.sh): - Pre-commit-runnable check script: non-ASCII, banned shorthand, snake_case DB names, snake_case API params in frontend - Fixes 14 violations across 11 files (Unicode arrows, snake_case params, ctx -> canvasContext, res -> response, req -> request_obj) Project state (CLAUDE.md, README.md, frontend/CLAUDE.md): - De-staled CLAUDE.md to reflect actual current state - README unifies DB story (MySQL canonical, SQLite test-only) - frontend/CLAUDE.md points at root convention Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
166
CLAUDE.md
166
CLAUDE.md
@@ -1,108 +1,124 @@
|
||||
# ShopDB Flask Project
|
||||
|
||||
## Database Configuration
|
||||
Modern rewrite of the classic-ASP shopdb. Built as a framework so sister GE Aerospace sites can adopt it. Plugin system is the product.
|
||||
|
||||
- **Development database:** `shopdb_flask` (new schema with asset abstraction)
|
||||
- **Legacy database:** `shopdb` (Classic ASP schema - used for data migration reference only)
|
||||
- **Connection:** Configured in `.env` file
|
||||
## Database
|
||||
|
||||
## Current Tasks
|
||||
- **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`.
|
||||
|
||||
### Data Migration from Legacy Database
|
||||
Architecture decisions live in `migrations/adr/`. Read those before making schema or contract changes.
|
||||
|
||||
Migrate data from `shopdb` to `shopdb_flask` using the new asset-based schema.
|
||||
- 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
|
||||
|
||||
**Status:** Pending
|
||||
## Coding convention
|
||||
|
||||
**Migration guide:** `migrations/DATA_MIGRATION_GUIDE.md`
|
||||
`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.
|
||||
|
||||
**Tables to migrate:**
|
||||
- [ ] Reference data (vendors, models, locations, business units, subnets)
|
||||
- [ ] Equipment (machines with category='Equipment')
|
||||
- [ ] Computers/PCs (machines with pctypeid IS NOT NULL)
|
||||
- [ ] Network devices (machines with category='Network')
|
||||
- [ ] Printers (separate printers table)
|
||||
- [ ] Communications/IP addresses
|
||||
- [ ] Notifications
|
||||
- [ ] Machine relationships
|
||||
## Current state (as of 2026-05-08)
|
||||
|
||||
### Plugin Architecture Verification
|
||||
### Wired in
|
||||
|
||||
Verify all plugins follow plug-and-play architecture - can be added/removed without impacting core site or other plugins.
|
||||
- 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)
|
||||
|
||||
**Plugins to verify:**
|
||||
- [ ] Equipment (`plugins/equipment/`) - frontend: `views/machines/`
|
||||
- [ ] Computers (`plugins/computers/`) - frontend: `views/pcs/`
|
||||
- [ ] Printers (`plugins/printers/`) - frontend: `views/printers/`
|
||||
- [ ] Network (`plugins/network/`) - frontend: `views/network/`
|
||||
- [ ] USB (`plugins/usb/`) - frontend: `views/usb/`
|
||||
- [ ] Notifications (`plugins/notifications/`) - frontend: `views/notifications/`
|
||||
### In progress / partial
|
||||
|
||||
**Architecture checks:**
|
||||
- [ ] Core API uses try/except ImportError for plugin imports (see `shopdb/core/api/assets.py` for pattern)
|
||||
- [ ] Frontend router can dynamically add/remove routes per plugin
|
||||
- [ ] Navigation menu reads from plugin `get_navigation_items()`
|
||||
- [ ] Document plugin enable/disable mechanism in app factory
|
||||
- **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.
|
||||
|
||||
**Each plugin must have:**
|
||||
- `models/__init__.py` - exports all models
|
||||
- `api/routes.py` - Flask Blueprint with endpoints
|
||||
- `plugin.py` - implements BasePlugin class
|
||||
- `manifest.json` - plugin metadata (name, version, dependencies)
|
||||
- No direct imports from core code (use optional imports)
|
||||
- Modular frontend components
|
||||
### Pending
|
||||
|
||||
## Plugin Structure
|
||||
- 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 <name>`)
|
||||
- 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)
|
||||
|
||||
```
|
||||
plugins/
|
||||
{plugin_name}/
|
||||
__init__.py
|
||||
plugin.py # BasePlugin implementation
|
||||
manifest.json # Plugin metadata
|
||||
models/
|
||||
__init__.py # Export all models
|
||||
{model}.py # SQLAlchemy models
|
||||
api/
|
||||
__init__.py
|
||||
routes.py # Flask Blueprint
|
||||
```
|
||||
|
||||
## Key Files
|
||||
|
||||
- `shopdb/plugins/base.py` - BasePlugin class and PluginMeta
|
||||
- `shopdb/core/api/assets.py` - Example of optional plugin imports with try/except
|
||||
- `frontend/src/router/index.js` - Frontend routing
|
||||
- `frontend/src/components/AppSidebar.vue` - Navigation menu
|
||||
|
||||
## Migration Notes
|
||||
|
||||
See `migrations/` folder for:
|
||||
- `DATA_MIGRATION_GUIDE.md` - Complete guide for migrating from legacy shopdb to new schema
|
||||
- `MIGRATE_USB_DEVICES_FROM_EQUIPMENT.md` - USB device migration from equipment table
|
||||
- `FIX_LOCATIONONLY_EQUIPMENT_TYPES.md` - Fix for LocationOnly equipment types
|
||||
- `PRODUCTION_MIGRATION_GUIDE.md` - Production data import methods
|
||||
|
||||
## Quick Start
|
||||
## Quick start
|
||||
|
||||
```bash
|
||||
# Start dev environment
|
||||
~/start-dev-env.sh
|
||||
|
||||
# Create/update database tables
|
||||
# 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 after changes
|
||||
# Restart services
|
||||
pm2 restart shopdb-flask-api shopdb-flask-ui
|
||||
```
|
||||
|
||||
## Service URLs
|
||||
|
||||
- **Flask API:** http://localhost:5001
|
||||
- **Flask UI:** http://localhost:5173
|
||||
- **Legacy ASP:** http://192.168.122.151:8080
|
||||
- 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/
|
||||
<plugin_name>/
|
||||
__init__.py
|
||||
plugin.py # BasePlugin implementation
|
||||
manifest.json # Plugin metadata (name, version, dependencies, api_prefix)
|
||||
models/
|
||||
__init__.py # Export all models
|
||||
<model>.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)
|
||||
|
||||
Reference in New Issue
Block a user