docs(01-02): complete database schema and driver storage plan
- 01-02-SUMMARY.md: TDD execution results, decisions, self-check passed - STATE.md: progress updated (100% phase 1), 3 decisions recorded - ROADMAP.md: phase 1 marked Complete (3/3 summaries)
This commit is contained in:
@@ -12,7 +12,7 @@ ImpTune ships in five phases ordered by risk and dependency. The foundation phas
|
|||||||
|
|
||||||
Decimal phases appear between their surrounding integers in numeric order.
|
Decimal phases appear between their surrounding integers in numeric order.
|
||||||
|
|
||||||
- [ ] **Phase 1: Foundation** - Docker container scaffold, SQLite schema, and .intunewin format spike
|
- [x] **Phase 1: Foundation** - Docker container scaffold, SQLite schema, and .intunewin format spike (completed 2026-04-10)
|
||||||
- [ ] **Phase 2: Driver Management** - Driver ZIP upload, INF parsing, DriverDesc dropdown, volume persistence
|
- [ ] **Phase 2: Driver Management** - Driver ZIP upload, INF parsing, DriverDesc dropdown, volume persistence
|
||||||
- [ ] **Phase 3: Printer Configuration** - Full printer config form, client/tenant labels, SQLite persistence
|
- [ ] **Phase 3: Printer Configuration** - Full printer config form, client/tenant labels, SQLite persistence
|
||||||
- [ ] **Phase 4: Script Generation** - PowerShell install/uninstall/detection scripts with all correctness guards
|
- [ ] **Phase 4: Script Generation** - PowerShell install/uninstall/detection scripts with all correctness guards
|
||||||
@@ -108,7 +108,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5
|
|||||||
|
|
||||||
| Phase | Plans Complete | Status | Completed |
|
| Phase | Plans Complete | Status | Completed |
|
||||||
|-------|----------------|--------|-----------|
|
|-------|----------------|--------|-----------|
|
||||||
| 1. Foundation | 2/3 | In Progress| |
|
| 1. Foundation | 3/3 | Complete | 2026-04-10 |
|
||||||
| 2. Driver Management | 0/3 | Not started | - |
|
| 2. Driver Management | 0/3 | Not started | - |
|
||||||
| 3. Printer Configuration | 0/3 | Not started | - |
|
| 3. Printer Configuration | 0/3 | Not started | - |
|
||||||
| 4. Script Generation | 0/3 | Not started | - |
|
| 4. Script Generation | 0/3 | Not started | - |
|
||||||
|
|||||||
+12
-8
@@ -3,14 +3,14 @@ gsd_state_version: 1.0
|
|||||||
milestone: v1.0
|
milestone: v1.0
|
||||||
milestone_name: milestone
|
milestone_name: milestone
|
||||||
status: executing
|
status: executing
|
||||||
stopped_at: Completed 01-01-PLAN.md
|
stopped_at: Completed 01-02-PLAN.md
|
||||||
last_updated: "2026-04-10T09:27:00.000Z"
|
last_updated: "2026-04-10T09:33:07.640Z"
|
||||||
last_activity: 2026-04-10 — Plan 01-01 complete: Docker scaffold, FastAPI app shell, test suite
|
last_activity: "2026-04-10 — Plan 01-01 complete: Docker scaffold, FastAPI app shell, sidebar templates, 3-test green suite"
|
||||||
progress:
|
progress:
|
||||||
total_phases: 5
|
total_phases: 5
|
||||||
completed_phases: 0
|
completed_phases: 1
|
||||||
total_plans: 3
|
total_plans: 3
|
||||||
completed_plans: 2
|
completed_plans: 3
|
||||||
percent: 7
|
percent: 7
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -50,6 +50,7 @@ Progress: [░░░░░░░░░░] 7%
|
|||||||
- Trend: Consistent
|
- Trend: Consistent
|
||||||
|
|
||||||
*Updated after each plan completion*
|
*Updated after each plan completion*
|
||||||
|
| Phase 01-foundation P01-02 | 3 | 2 tasks | 7 files |
|
||||||
|
|
||||||
## Accumulated Context
|
## Accumulated Context
|
||||||
|
|
||||||
@@ -64,6 +65,9 @@ Recent decisions affecting current work:
|
|||||||
- [Phase 01]: Inner .intunewin ZIP uses DEFLATE compression; outer ZIP uses STORED (matches C# reference implementation)
|
- [Phase 01]: Inner .intunewin ZIP uses DEFLATE compression; outer ZIP uses STORED (matches C# reference implementation)
|
||||||
- [Plan 01-01]: Use asynccontextmanager lifespan instead of deprecated @app.on_event — required for FastAPI 0.115+ / Starlette 0.40+
|
- [Plan 01-01]: Use asynccontextmanager lifespan instead of deprecated @app.on_event — required for FastAPI 0.115+ / Starlette 0.40+
|
||||||
- [Plan 01-01]: TemplateResponse uses request= kwarg signature (not positional dict) — Starlette 0.40+ compatibility
|
- [Plan 01-01]: TemplateResponse uses request= kwarg signature (not positional dict) — Starlette 0.40+ compatibility
|
||||||
|
- [Phase 01-foundation]: Deferred SqliteDatabase(None) pattern so tests can patch DB_PATH via monkeypatch without module reload
|
||||||
|
- [Phase 01-foundation]: Full 4-table schema created upfront in phase 1 — later phases add routes/logic only, no schema changes
|
||||||
|
- [Phase 01-foundation]: init_db() added to lifespan (not @app.on_event) consistent with 01-01 established pattern
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
@@ -76,6 +80,6 @@ None yet.
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-04-10T09:27:00Z
|
Last session: 2026-04-10T09:33:07.637Z
|
||||||
Stopped at: Completed 01-01-PLAN.md
|
Stopped at: Completed 01-02-PLAN.md
|
||||||
Resume file: .planning/phases/01-foundation/01-02-PLAN.md
|
Resume file: None
|
||||||
|
|||||||
@@ -0,0 +1,139 @@
|
|||||||
|
---
|
||||||
|
phase: 01-foundation
|
||||||
|
plan: "02"
|
||||||
|
subsystem: database
|
||||||
|
tags: [peewee, sqlite, wal, orm, content-addressed-storage, sha256]
|
||||||
|
|
||||||
|
# Dependency graph
|
||||||
|
requires:
|
||||||
|
- phase: 01-01
|
||||||
|
provides: "FastAPI app shell with lifespan, config.py with DATA_DIR/DB_PATH/DRIVERS_DIR"
|
||||||
|
provides:
|
||||||
|
- "Peewee SqliteDatabase instance with WAL mode + foreign_keys pragma (imptune/db/database.py)"
|
||||||
|
- "Full ORM schema: Client, Driver, Printer, Icon models for phases 1-5 (imptune/db/models.py)"
|
||||||
|
- "SHA256 content-addressed DriverStore with deduplication (imptune/storage/driver_store.py)"
|
||||||
|
- "Auto-initializing database via FastAPI lifespan startup"
|
||||||
|
affects:
|
||||||
|
- phase-02-clients
|
||||||
|
- phase-03-drivers
|
||||||
|
- phase-04-printers
|
||||||
|
- phase-05-export
|
||||||
|
|
||||||
|
# Tech tracking
|
||||||
|
tech-stack:
|
||||||
|
added: [peewee==3.17.9]
|
||||||
|
patterns:
|
||||||
|
- "Deferred SqliteDatabase init (db.init() at runtime so tests can override DB_PATH)"
|
||||||
|
- "safe=True on create_tables() for idempotent schema creation"
|
||||||
|
- "SHA256 content-addressed file storage for deduplication"
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created:
|
||||||
|
- imptune/db/__init__.py
|
||||||
|
- imptune/db/database.py
|
||||||
|
- imptune/db/models.py
|
||||||
|
- imptune/storage/__init__.py
|
||||||
|
- imptune/storage/driver_store.py
|
||||||
|
- tests/test_db.py
|
||||||
|
modified:
|
||||||
|
- imptune/main.py
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "Deferred SqliteDatabase pattern (SqliteDatabase(None)) so tests can patch imptune.config.DB_PATH without module reload"
|
||||||
|
- "Full schema created upfront in phase 1 per locked user decision — later phases only add routes/logic, no schema changes"
|
||||||
|
- "init_db() placed in lifespan (not @app.on_event) consistent with 01-01 decision — plan text was outdated"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "TDD: RED (failing tests) then GREEN (implementation) for all db/storage modules"
|
||||||
|
- "ORM: All models extend BaseModel which references shared db instance via Meta.database = db"
|
||||||
|
- "Storage: DriverStore encapsulates all filesystem operations for driver packages"
|
||||||
|
|
||||||
|
requirements-completed: [INFRA-01, INFRA-02]
|
||||||
|
|
||||||
|
# Metrics
|
||||||
|
duration: 3min
|
||||||
|
completed: 2026-04-10
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 1 Plan 2: Database Schema and Driver Storage Summary
|
||||||
|
|
||||||
|
**Peewee ORM with deferred SQLiteDatabase, full 4-table schema (Client/Driver/Printer/Icon) for all phases, and SHA256-deduplicating DriverStore — wired into FastAPI lifespan**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** ~3 min
|
||||||
|
- **Started:** 2026-04-10T09:29:54Z
|
||||||
|
- **Completed:** 2026-04-10T09:32:07Z
|
||||||
|
- **Tasks:** 2 (Task 1 with TDD + Task 2)
|
||||||
|
- **Files modified:** 7
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- Full Peewee ORM schema with 4 tables covering all phases 1-5 (locked-in upfront design decision)
|
||||||
|
- WAL journal mode and foreign_keys pragma enforced via init_db() on every startup
|
||||||
|
- Deferred database pattern allows tests to safely redirect DB_PATH to tmp dirs without module reloads
|
||||||
|
- DriverStore provides SHA256 content-addressed storage with automatic deduplication on write
|
||||||
|
- init_db() integrated into FastAPI lifespan — database auto-creates at DATA_DIR/imptune.db on startup
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
Each task was committed atomically:
|
||||||
|
|
||||||
|
1. **Task 1: Peewee models, database init, and driver storage** - `dea4148` (feat — TDD GREEN)
|
||||||
|
2. **Task 2: Wire database init into FastAPI startup** - `88d9c5f` (feat)
|
||||||
|
|
||||||
|
**Plan metadata:** (docs commit follows)
|
||||||
|
|
||||||
|
_Note: TDD — tests written first (RED), then implementation (GREEN). No separate refactor pass needed._
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
- `imptune/db/__init__.py` - Package marker
|
||||||
|
- `imptune/db/database.py` - Deferred SqliteDatabase instance + init_db() with WAL/FK pragmas
|
||||||
|
- `imptune/db/models.py` - BaseModel, Client, Driver, Printer, Icon ORM models
|
||||||
|
- `imptune/storage/__init__.py` - Package marker
|
||||||
|
- `imptune/storage/driver_store.py` - SHA256 content-addressed DriverStore class
|
||||||
|
- `tests/test_db.py` - 7 TDD tests (table creation, WAL, FK, idempotency, save, dedup, get_path)
|
||||||
|
- `imptune/main.py` - Added import and call to init_db() in lifespan
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
- **Deferred database pattern**: Used `SqliteDatabase(None)` + `db.init()` at runtime so pytest's `monkeypatch` on `imptune.config.DB_PATH` works without module reload side effects.
|
||||||
|
- **Lifespan over @app.on_event**: Plan text referenced `@app.on_event("startup")` but 01-01 established the lifespan pattern. Followed existing code — no deviation registered as this was alignment with an existing decision.
|
||||||
|
- **Full schema upfront**: All 4 tables created in phase 1 per user's locked decision, so phases 2-5 only add application logic.
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
**1. [Rule 3 - Blocking] Installed missing peewee package**
|
||||||
|
- **Found during:** Task 1 setup
|
||||||
|
- **Issue:** peewee was in requirements.txt but not installed in the active Python environment
|
||||||
|
- **Fix:** Ran `python -m pip install peewee==3.17.*`
|
||||||
|
- **Files modified:** None (environment only)
|
||||||
|
- **Verification:** `import peewee` succeeds, all 7 tests pass
|
||||||
|
- **Committed in:** Not committed (environment dependency install)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Total deviations:** 1 auto-fixed (1 blocking — missing dependency)
|
||||||
|
**Impact on plan:** No scope creep. peewee install was a prerequisite, not new scope.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
- Plan Task 2 referenced `@app.on_event("startup")` but the existing `main.py` from plan 01-01 already uses `asynccontextmanager lifespan` (per a decision recorded in STATE.md). Added `init_db()` to the lifespan function instead — no regression.
|
||||||
|
|
||||||
|
## User Setup Required
|
||||||
|
|
||||||
|
None - no external service configuration required.
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
|
||||||
|
- Database layer complete — all ORM models importable and tested
|
||||||
|
- `init_db()` wired in — first app startup creates the database automatically in DATA_DIR
|
||||||
|
- DriverStore ready for driver upload routes (phase 3)
|
||||||
|
- All 24 tests pass (7 new + 17 existing), zero regressions
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 01-foundation*
|
||||||
|
*Completed: 2026-04-10*
|
||||||
Reference in New Issue
Block a user