Style check fixes:
- Replace unicode box-drawing characters with ASCII (|-- instead of ├──)
- Replace emoji status markers with [OK]/[FAIL]/[WARN] tags
- Replace arrows (→ with ->, ↔ with <->) and em-dashes (— with --)
- Add venv-quick to excluded directories in check script
- Exclude darkwing report files (findings.sarif, report.md)
Backup finalization fix:
- Fix finalize-restore endpoint to not claim the upgrade sentinel
- Endpoint now checks for pending upgrade and returns {queued: true}
- Leaves UPGRADE_SENTINEL for background watcher to claim and process
- Prevents inline Alembic runs that can outlast request timeout
Claude Code context:
- Add .claude/ directory with INDEX.md and QUICK-REFERENCE.md
- Add CLAUDE.md with project overview and conventions
- Helps Claude Code understand project structure and rules
Fixes failing test: test_the_endpoint_does_not_run_the_upgrade_itself
Fixes naming/style CI check violations
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
3.4 KiB
3.4 KiB
ShopDB Quick Reference
Fast lookup for architectural decisions and contracts.
Critical ADRs (in wiki)
- ADR-001: Asset as platform contract - Core asset model, BaseAsset, composition
- ADR-004: Deployment topology - Air-gapped sites, bundle workflow
- ADR-006: Collector contract - Endpoint agent protocol
- ADR-007: Product versioning - Semantic versioning, release process
- ADR-008: Plugin migration ownership - PLUGIN_TABLE_OWNERS, migration chains
- ADR-013: Plugin catalog - Lean builds, plugin manifest
- ADR-015: Site-specific configuration - Where site literals belong
- ADR-016: Credential delivery - Device tokens, kiosk auth
Import Surface (stable API)
from shopdb.api import (
# Database
db,
# Core Models
Asset, Employee, User, Building, MapLevel,
# Plugin Base
BasePlugin,
# Auth/Authz
requires_role, requires_device_token,
# Utilities
badges, datevalues, queryargs
)
Plugin Structure
plugins/{name}/
|-- plugin.py # BasePlugin subclass, manifest
|-- models/ # SQLAlchemy models
| +-- {name}.py
|-- api/ # Flask routes
| +-- routes.py
|-- frontend/ # Vue components
| +-- views/
| |-- {Name}List.vue
| |-- {Name}Detail.vue
| +-- {Name}Form.vue
|-- migrations/ # Alembic migrations
| +-- versions/
+-- services/ # Business logic (optional)
Database Naming
- Tables:
printedpart,mappeddrives(lowercase concatenated) - Columns:
serial_number,last_seen(snake_case) - Enforced:
scripts/check-naming-and-style.sh
Branch Model
wj-> prod (WJ shop floor)dev-> ops (monitoring/pilot)main-> public mirror (GitHub only)wilm-> upstream (benjamin.baker's changes)
Common Commands
# Run tests
pytest -v
# Check style
scripts/check-naming-and-style.sh
# Create migration
cd plugins/{name}
alembic revision -m "description"
# Dev server
docker compose up
# Bundle for dev PC
# (on work PC) ~/Documents/github/pull-shopdb-bundle.cmd
# Fetch wilm changes
# (on work PC) ~/Documents/github/fetch-wilm-branch.cmd
Test Patterns
def test_feature(client, db_session):
# Setup
item = Model(name="test")
db_session.add(item)
db_session.commit()
# Execute
resp = client.get('/api/plugin/endpoint')
# Assert
assert resp.status_code == 200
assert resp.json['name'] == 'test'
Site Data Rules (ADR-015)
[OK] Allowed:
shopdb/core/settings/buildings.pyshopdb/core/seed/*.sqlscripts/site_imports/*.py
[FAIL] Forbidden:
- Hardcoded in plugin code
- Embedded in migrations
- Configuration files
Migration Ownership (ADR-008)
Each plugin owns its chain. Coordinate cross-plugin FK changes via PLUGIN_TABLE_OWNERS:
PLUGIN_TABLE_OWNERS = {
'asset': 'core',
'employee': 'employees',
'pc': 'computers',
'endpoint': 'endpoints',
# ...
}
Device Tokens (ADR-016)
Kiosks require device authentication:
from shopdb.api import requires_device_token
@bp.route('/kiosk/endpoint')
@requires_device_token(['usb_kiosk', 'parts_kiosk'])
def kiosk_view():
return render_template('kiosk.html')
Wiki Location
Full docs: ~/Documents/github/shopdb-flask.wiki/
All ADRs, deployment guides, plugin development docs live there.