fix: replace unicode characters and fix finalize-restore endpoint
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>
This commit is contained in:
116
.claude/INDEX.md
Normal file
116
.claude/INDEX.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# ShopDB Index - Load Only What You Need
|
||||
|
||||
Quick pointers to avoid reading entire wiki or codebase.
|
||||
|
||||
## When Working On...
|
||||
|
||||
**Plugin development**:
|
||||
- Read: `CLAUDE.md` (overview)
|
||||
- Grep: `class BasePlugin` in `shopdb/api/__init__.py`
|
||||
- Reference: `../shopdb-flask.wiki/ADR-001-asset-as-platform-contract.md`
|
||||
|
||||
**Database migrations**:
|
||||
- Read: `../shopdb-flask.wiki/ADR-008-plugin-migration-ownership.md`
|
||||
- Grep: `PLUGIN_TABLE_OWNERS` for dependency order
|
||||
- Pattern: `plugins/{name}/migrations/versions/*.py`
|
||||
|
||||
**Site-specific config**:
|
||||
- Read: `../shopdb-flask.wiki/ADR-015-site-specific-configuration.md`
|
||||
- Locations: `shopdb/core/settings/`, `shopdb/core/seed/`, `scripts/site_imports/`
|
||||
|
||||
**Kiosk/device auth**:
|
||||
- Read: `../shopdb-flask.wiki/ADR-016-credential-delivery.md`
|
||||
- Grep: `requires_device_token`
|
||||
|
||||
**Deployment/branches**:
|
||||
- Read: `../shopdb-flask.wiki/ADR-004-deployment-topology.md`
|
||||
- Scripts: `~/Documents/github/*.cmd`
|
||||
|
||||
**Frontend plugin panels**:
|
||||
- Read: `../shopdb-flask.wiki/ADR-010-frontend-plugin-hooks.md`
|
||||
- Pattern: `plugins/{name}/frontend/views/*.vue`
|
||||
|
||||
**Testing**:
|
||||
- Read: `tests/conftest.py` for fixtures
|
||||
- Pattern: `tests/test_plugins/test_{plugin}_{feature}.py`
|
||||
|
||||
## Plugin Map (20 plugins)
|
||||
|
||||
Core asset types:
|
||||
- `computers`, `endpoints`, `printers`, `machines`, `measuringtools`, `network`, `tools`
|
||||
|
||||
Workflows:
|
||||
- `printedparts`, `usb`, `slides`, `notifications`
|
||||
|
||||
Integrations:
|
||||
- `warranty`, `geenforce`, `guides`, `knowledgebase`
|
||||
|
||||
Admin:
|
||||
- `employees`, `backups`
|
||||
|
||||
## Key Files
|
||||
|
||||
- `shopdb/api/__init__.py` - Stable import surface (75 lines)
|
||||
- `shopdb/config.py` - App configuration
|
||||
- `shopdb/core/models/asset.py` - Base asset model
|
||||
- `docker-compose.yml` - Dev stack definition
|
||||
- `scripts/check-naming-and-style.sh` - Pre-commit hook
|
||||
|
||||
## Git Branches
|
||||
|
||||
**Current repo state**:
|
||||
- `wj` (checked out) - Prod branch for WJ shop floor
|
||||
- `main` - Public GitHub mirror, deploys nowhere
|
||||
- `origin/wilm` - Upstream changes from benjamin.baker (86 commits ahead)
|
||||
- `origin/dev-be` - Historical dev branch
|
||||
|
||||
**Branch workflow** (ADR-004):
|
||||
- `wj` -> prod deployment (WJ site)
|
||||
- `dev` -> ops deployment (monitoring/pilot sites, on gitea only)
|
||||
- `main` -> GitHub public mirror only (no deployments)
|
||||
- `wilm` -> fetch from GitHub, review, merge to wj or dev
|
||||
|
||||
**On this work PC**:
|
||||
- Has GitHub credentials (ge-aero/shopdb-flask)
|
||||
- Fetch wilm: `~/Documents/github/fetch-wilm-branch.cmd`
|
||||
- Bundle to dev PC: `~/Documents/github/pull-shopdb-bundle.cmd`
|
||||
|
||||
## Common Paths
|
||||
|
||||
- Plugin code: `plugins/{name}/`
|
||||
- Core models: `shopdb/core/models/`
|
||||
- Core API: `shopdb/core/api/`
|
||||
- Frontend core: `frontend/src/`
|
||||
- Tests: `tests/test_plugins/`
|
||||
- Migrations: `migrations/` (core) + `plugins/{name}/migrations/`
|
||||
- Scripts: `scripts/`
|
||||
- Docs: `../shopdb-flask.wiki/`
|
||||
|
||||
## Avoid Reading These Unless Needed
|
||||
|
||||
- `docs/openapi.json` (489 lines, generated)
|
||||
- `frontend/dist/` (build output)
|
||||
- `node_modules/`, `venv/`, `.pytest_cache/`
|
||||
- `agent/` (C# endpoint agent, 10k+ lines)
|
||||
- Full wiki (68 files) - use index above
|
||||
|
||||
## Token-Efficient Patterns
|
||||
|
||||
1. **Grep before Read**: Find the exact file/function first
|
||||
2. **Read with limit**: Use offset/limit for large files
|
||||
3. **Reference by path**: Cite `file:line` instead of quoting code
|
||||
4. **Use memory**: Store repeated patterns in memory files
|
||||
5. **Wiki on-demand**: Only read specific ADRs when relevant
|
||||
|
||||
## One-Line ADR Summaries
|
||||
|
||||
- ADR-001: Asset is the platform primitive for all equipment
|
||||
- ADR-004: Three air-gapped environments, bundle workflow
|
||||
- ADR-006: Endpoint agent sends telemetry, receives commands
|
||||
- ADR-007: Semantic versioning, GitHub releases
|
||||
- ADR-008: Each plugin owns its migration chain, no conflicts
|
||||
- ADR-009: Frontend plugins gate on backend features
|
||||
- ADR-010: Plugins register Vue components via manifest
|
||||
- ADR-013: Lean builds include only needed plugins
|
||||
- ADR-015: Site literals go in settings/seed/site_imports only
|
||||
- ADR-016: Kiosks use device tokens, not user sessions
|
||||
152
.claude/QUICK-REFERENCE.md
Normal file
152
.claude/QUICK-REFERENCE.md
Normal file
@@ -0,0 +1,152 @@
|
||||
# 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)
|
||||
|
||||
```python
|
||||
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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```python
|
||||
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.py`
|
||||
- `shopdb/core/seed/*.sql`
|
||||
- `scripts/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:
|
||||
|
||||
```python
|
||||
PLUGIN_TABLE_OWNERS = {
|
||||
'asset': 'core',
|
||||
'employee': 'employees',
|
||||
'pc': 'computers',
|
||||
'endpoint': 'endpoints',
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
## Device Tokens (ADR-016)
|
||||
|
||||
Kiosks require device authentication:
|
||||
|
||||
```python
|
||||
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.
|
||||
27
.claude/settings.json
Normal file
27
.claude/settings.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"bash:pytest*",
|
||||
"bash:git status",
|
||||
"bash:git log*",
|
||||
"bash:git diff*",
|
||||
"bash:git branch*",
|
||||
"bash:docker compose*",
|
||||
"bash:docker ps",
|
||||
"bash:alembic*",
|
||||
"bash:python scripts/*",
|
||||
"grep:**",
|
||||
"glob:**"
|
||||
]
|
||||
},
|
||||
"hooks": {
|
||||
"beforeCommit": [
|
||||
"scripts/check-naming-and-style.sh"
|
||||
]
|
||||
},
|
||||
"context": {
|
||||
"alwaysInclude": [
|
||||
".claude/INDEX.md"
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user