docs(01-01): complete backend scaffold plan — SUMMARY, STATE, ROADMAP, REQUIREMENTS updated

- Created 01-01-SUMMARY.md with full accomplishment record
- STATE.md: advanced to plan 2/3, progress 33%, added 3 key decisions
- ROADMAP.md: Phase 1 updated to 1/3 summaries (In Progress)
- REQUIREMENTS.md: marked INF-01, INF-02, DEV-01, DEV-02, SHW-01, SHW-02 complete
This commit is contained in:
Claude
2026-04-05 18:49:37 +00:00
parent 5e10272c69
commit dd5a1b22fd
4 changed files with 214 additions and 15 deletions

View File

@@ -17,8 +17,8 @@
### Device Registry ### Device Registry
- [ ] **DEV-01**: Register a device with: name, strip type (SK6812 / WS2801 / generic), LED count, target IP, target port - [x] **DEV-01**: Register a device with: name, strip type (SK6812 / WS2801 / generic), LED count, target IP, target port
- [ ] **DEV-02**: Devices persist across sessions (stored in config file) - [x] **DEV-02**: Devices persist across sessions (stored in config file)
- [ ] **DEV-03**: Device list shown in UI — enable/disable per show - [ ] **DEV-03**: Device list shown in UI — enable/disable per show
### Animation Library ### Animation Library
@@ -41,8 +41,8 @@
### Show Engine ### Show Engine
- [ ] **SHW-01**: Show files saved and loaded as JSON (schema_version field required in v1) - [x] **SHW-01**: Show files saved and loaded as JSON (schema_version field required in v1)
- [ ] **SHW-02**: Show file includes: audio path/URL, device registry snapshot, all animation blocks with timestamps, beat analysis data - [x] **SHW-02**: Show file includes: audio path/URL, device registry snapshot, all animation blocks with timestamps, beat analysis data
- [ ] **SHW-03**: Live show execution — follow MPV position, dispatch animation commands to devices via UDP at correct timestamps - [ ] **SHW-03**: Live show execution — follow MPV position, dispatch animation commands to devices via UDP at correct timestamps
### UDP Communication ### UDP Communication
@@ -67,8 +67,8 @@
### Infrastructure ### Infrastructure
- [ ] **INF-01**: Python 3.11 backend (FastAPI + uvicorn) - [x] **INF-01**: Python 3.11 backend (FastAPI + uvicorn)
- [ ] **INF-02**: Modular device abstraction — adding a new strip type requires only a new device class, no changes to core engine - [x] **INF-02**: Modular device abstraction — adding a new strip type requires only a new device class, no changes to core engine
- [ ] **INF-03**: Windows 11 timer resolution fix applied at startup (`timeBeginPeriod(1)` via ctypes) - [ ] **INF-03**: Windows 11 timer resolution fix applied at startup (`timeBeginPeriod(1)` via ctypes)
--- ---

View File

@@ -35,7 +35,7 @@ Decimal phases appear between their surrounding integers in numeric order.
**Plans**: 3 plans **Plans**: 3 plans
Plans: Plans:
- [ ] 01-01: Backend scaffold — FastAPI app, Pydantic show/device models, show store (JSON load/save), device registry - [x] 01-01: Backend scaffold — FastAPI app, Pydantic show/device models, show store (JSON load/save), device registry
- [ ] 01-02: Frontend shell — HTML/CSS terminal aesthetic, WebSocket client stub, device panel, show panel - [ ] 01-02: Frontend shell — HTML/CSS terminal aesthetic, WebSocket client stub, device panel, show panel
- [ ] 01-03: REST API — CRUD endpoints for devices and shows, static file serving, integration smoke test - [ ] 01-03: REST API — CRUD endpoints for devices and shows, static file serving, integration smoke test
**UI hint**: yes **UI hint**: yes
@@ -151,7 +151,7 @@ Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6 → 7
| Phase | Plans Complete | Status | Completed | | Phase | Plans Complete | Status | Completed |
|-------|----------------|--------|-----------| |-------|----------------|--------|-----------|
| 1. Foundation | 0/3 | Not started | - | | 1. Foundation | 1/3 | In Progress| |
| 2. Audio Engine | 0/3 | Not started | - | | 2. Audio Engine | 0/3 | Not started | - |
| 3. Communication Protocol | 0/3 | Not started | - | | 3. Communication Protocol | 0/3 | Not started | - |
| 4. Timeline Editor | 0/4 | Not started | - | | 4. Timeline Editor | 0/4 | Not started | - |

View File

@@ -1,3 +1,19 @@
---
gsd_state_version: 1.0
milestone: v1.0
milestone_name: milestone
status: executing
stopped_at: Completed 01-foundation/01-01-PLAN.md
last_updated: "2026-04-05T18:49:18.330Z"
last_activity: 2026-04-05
progress:
total_phases: 7
completed_phases: 0
total_plans: 3
completed_plans: 1
percent: 0
---
# Project State # Project State
## Project Reference ## Project Reference
@@ -5,20 +21,21 @@
See: .planning/PROJECT.md (updated 2026-04-05) See: .planning/PROJECT.md (updated 2026-04-05)
**Core value:** Load a song, build a synchronized light show, play it back live — with precise control over every effect on every device. **Core value:** Load a song, build a synchronized light show, play it back live — with precise control over every effect on every device.
**Current focus:** Phase 1 — Foundation **Current focus:** Phase 01 — foundation
## Current Position ## Current Position
Phase: 1 of 7 (Foundation) Phase: 01 (foundation) — EXECUTING
Plan: 0 of 3 in current phase Plan: 2 of 3
Status: Ready to plan Status: Ready to execute
Last activity: 2026-04-05 — Roadmap and state initialized Last activity: 2026-04-05
Progress: [░░░░░░░░░░] 0% Progress: [░░░░░░░░░░] 0%
## Performance Metrics ## Performance Metrics
**Velocity:** **Velocity:**
- Total plans completed: 0 - Total plans completed: 0
- Average duration: — - Average duration: —
- Total execution time: 0 hours - Total execution time: 0 hours
@@ -30,10 +47,12 @@ Progress: [░░░░░░░░░░] 0%
| - | - | - | - | | - | - | - | - |
**Recent Trend:** **Recent Trend:**
- Last 5 plans: — - Last 5 plans: —
- Trend: — - Trend: —
*Updated after each plan completion* *Updated after each plan completion*
| Phase 01-foundation P01 | 4 | 2 tasks | 23 files |
## Accumulated Context ## Accumulated Context
@@ -46,6 +65,9 @@ Recent decisions affecting current work:
- Init: python-mpv-jsonipc preferred over ctypes binding — no libmpv.dll dependency on Windows - Init: python-mpv-jsonipc preferred over ctypes binding — no libmpv.dll dependency on Windows
- Init: Firmware deferred to Phase 7 — protocol must be validated against simulator first - Init: Firmware deferred to Phase 7 — protocol must be validated against simulator first
- Init: undo/redo built in Phase 4 — retrofitting command pattern is expensive - Init: undo/redo built in Phase 4 — retrofitting command pattern is expensive
- [Phase 01-foundation]: Module-level state in main.py for registry/show_store — acceptable for Phase 1, Phase 2 migrates to Depends()
- [Phase 01-foundation]: StaticFiles mounted last in create_app() — prevents catch-all interception of /api/* routes
- [Phase 01-foundation]: encode_animation_cmd stubs return b'' — Phase 3 implements real UDP animation command encoding
### Pending Todos ### Pending Todos
@@ -59,8 +81,8 @@ None yet.
## Session Continuity ## Session Continuity
Last session: 2026-04-05 Last session: 2026-04-05T18:49:18.325Z
Stopped at: Roadmap created, STATE.md initialized Stopped at: Completed 01-foundation/01-01-PLAN.md
Resume file: None Resume file: None
Next action: `/gsd:plan-phase 1` Next action: `/gsd:plan-phase 1`

View File

@@ -0,0 +1,177 @@
---
phase: 01-foundation
plan: 01
subsystem: backend
tags: [python, fastapi, pydantic, uvicorn, websocket, nginx, terminal-ui]
# Dependency graph
requires: []
provides:
- "Python package lightsync/ with all backend modules"
- "Pydantic v2 DeviceConfig and ShowModel with full schema"
- "BaseDevice ABC + SK6812/WS2801 concrete implementations"
- "DeviceRegistry with JSON persistence (devices.json)"
- "ShowStore with JSON save/load (shows/ directory)"
- "FastAPI app with lifespan, REST stubs, WebSocket stub"
- "Terminal-aesthetic frontend shell (DAW skeleton)"
- "python -m lightsync entry point serving on port 8000"
affects: [phase-01-02, phase-02, phase-03, phase-04, phase-05, phase-06, phase-07]
# Tech tracking
tech-stack:
added:
- "FastAPI 0.115+ — web framework, REST, WebSocket, StaticFiles"
- "uvicorn[standard] 0.34+ — ASGI server with WebSocket support"
- "Pydantic v2 — model validation and JSON serialization"
- "aiofiles 24+ — async file I/O for show JSON and device registry"
- "python-dotenv — HOST/PORT config from .env file"
- "structlog — structured logging"
- "hatchling — build backend for pyproject.toml"
patterns:
- "lifespan context manager for startup/shutdown (replaces deprecated @app.on_event)"
- "Module-level registry/show_store refs in main.py — accessed via `import lightsync.main as state`"
- "StaticFiles LAST — API routes registered before mount to prevent catch-all interception"
- "Pydantic v2 APIs: model_dump_json(), model_validate_json(), model_validate() — never v1 .json()/.parse_obj()"
- "BaseDevice ABC + _DEVICE_CLASSES dict — adding new strip type = new file + one dict entry (INF-02)"
- "pathlib.Path throughout — cross-platform safe file paths"
- "aiofiles for all file I/O in async contexts — non-blocking"
key-files:
created:
- pyproject.toml
- .env
- .gitignore
- lightsync/__init__.py
- lightsync/__main__.py
- lightsync/main.py
- lightsync/models/__init__.py
- lightsync/models/device.py
- lightsync/models/show.py
- lightsync/devices/__init__.py
- lightsync/devices/base.py
- lightsync/devices/sk6812.py
- lightsync/devices/ws2801.py
- lightsync/devices/registry.py
- lightsync/store/__init__.py
- lightsync/store/show_store.py
- lightsync/api/__init__.py
- lightsync/api/devices.py
- lightsync/api/shows.py
- lightsync/api/ws.py
- lightsync/frontend/index.html
- lightsync/frontend/style.css
- lightsync/frontend/app.js
modified: []
key-decisions:
- "aiofiles for all JSON file I/O — keeps async handlers non-blocking per research guidance"
- "Module-level state in main.py for registry/show_store — acceptable for Phase 1, Phase 2 migrates to Depends()"
- "StaticFiles mounted last — required to prevent catch-all interception of /api/* routes"
- "encode_animation_cmd stubs return b'' — Phase 3 implements real UDP animation command encoding"
- ".gitignore excludes devices.json and shows/ — these are runtime data, not source"
patterns-established:
- "lifespan context manager for app startup/shutdown"
- "BaseDevice ABC + _DEVICE_CLASSES registry dict for extensible device type system"
- "Pydantic v2 serialization patterns (model_dump_json, model_validate_json)"
- "aiofiles for async file I/O in FastAPI route handlers"
- "CSS custom properties for terminal aesthetic — all colors via :root vars"
requirements-completed:
- INF-01
- INF-02
- DEV-01
- DEV-02
- SHW-01
- SHW-02
# Metrics
duration: 4min
completed: 2026-04-05
---
# Phase 1 Plan 01: Backend Scaffold Summary
**FastAPI backend scaffold with Pydantic v2 models, device ABC, JSON persistence stores, REST+WebSocket stubs, and terminal-aesthetic DAW skeleton frontend — all runnable via `python -m lightsync`**
## Performance
- **Duration:** ~4 min
- **Started:** 2026-04-05T18:43:46Z
- **Completed:** 2026-04-05T18:48:03Z
- **Tasks:** 2 (both auto)
- **Files created:** 23
## Accomplishments
### Task 1: Package structure, Pydantic models, device abstractions (commit: 061edfc)
- `pyproject.toml` with all Phase 1 dependencies (FastAPI, uvicorn, Pydantic v2, aiofiles, structlog)
- `lightsync/models/device.py``DeviceConfig` Pydantic model with `StripType` literal, UUID auto-ID, validation constraints
- `lightsync/models/show.py``ShowModel` with `schema_version=1`, `AudioRef`, `TrackModel`, `CueModel`, `AnalysisBlock`
- `lightsync/devices/base.py``BaseDevice` ABC with `encode_frame`, `encode_animation_cmd`, `bytes_per_pixel`
- `lightsync/devices/sk6812.py` — SK6812 RGBW (4 bytes/pixel), encode_frame builds RGBW bytearray
- `lightsync/devices/ws2801.py` — WS2801 RGB (3 bytes/pixel), encode_frame builds RGB bytearray
### Task 2: Registry, show store, FastAPI app, frontend shell (commit: 5e10272)
- `lightsync/devices/registry.py``DeviceRegistry` with `_DEVICE_CLASSES` dict, load/save (aiofiles), add/remove/get/list_all/instantiate
- `lightsync/store/show_store.py``ShowStore` with async save/load, `list_ids()` via glob
- `lightsync/main.py``create_app()` with lifespan hook, API routes registered before `StaticFiles` mount
- `lightsync/api/devices.py``GET /`, `POST /`, `DELETE /{id}` — full CRUD with save-on-write
- `lightsync/api/shows.py``GET /`, `POST /`, `GET /{id}` — create and retrieve shows
- `lightsync/api/ws.py``ConnectionManager` + `/ws` WebSocket endpoint with ack echo
- `lightsync/frontend/index.html` — DAW skeleton: header, sidebar (DEVICES + ANIMATIONS), TIMELINE main area, TRANSPORT footer
- `lightsync/frontend/style.css` — Terminal aesthetic: `#0a0a0a` bg, `#00ffff` cyan accent, `border-radius: 0` everywhere, CSS Grid layout
- `lightsync/frontend/app.js``LightSyncClient` WS with reconnect, `loadDevices()` populating device list
- `.gitignore` — excludes runtime data (`devices.json`, `shows/`), `.venv/`, `__pycache__/`
## Verification Results
All verification checks passed:
- `pip install -e ".[dev]"` — installs successfully
- `python -c "from lightsync.models.show import ShowModel; s = ShowModel(name='test'); assert s.schema_version == 1"` — passes
- `python -c "from lightsync.devices.registry import DeviceRegistry; print('OK')"` — passes
- `python -m lightsync` — starts server on port 8000, serves `GET /api/devices/` → 200 `[]`
## Task Commits
| Task | Commit | Description |
|------|--------|-------------|
| 1 | 061edfc | Package structure, Pydantic models, device abstractions |
| 2 | 5e10272 | Registry, show store, FastAPI app, frontend shell |
## Decisions Made
- Module-level `registry` and `show_store` refs in `main.py` — acceptable for Phase 1 single-process server; Phase 2 should migrate to `Depends()` for testability
- `encode_animation_cmd` stubs in SK6812/WS2801 return `b""` — Phase 3 implements real UDP frame encoding
- Google Fonts (JetBrains Mono) loaded from CDN — offline fallback to Consolas via CSS custom property chain
## Deviations from Plan
None — plan executed exactly as written.
## Known Stubs
These are intentional per-plan stubs, documented in the plan spec:
| Stub | File | Line | Reason |
|------|------|------|--------|
| `encode_animation_cmd` returns `b""` | lightsync/devices/sk6812.py | 28 | Phase 3 implements real UDP animation command encoding |
| `encode_animation_cmd` returns `b""` | lightsync/devices/ws2801.py | 26 | Phase 3 implements real UDP animation command encoding |
| ANIMATIONS panel placeholder | lightsync/frontend/index.html | — | Phase 3+ per design decision D-08 |
| TIMELINE panel placeholder | lightsync/frontend/index.html | — | Phase 2+ per design decision D-09 |
| TRANSPORT bar placeholder | lightsync/frontend/index.html | — | Phase 2+ per design decision D-10 |
All stubs are DAW skeleton placeholders (per D-06 decision: full panel layout from day 1) or device encoding stubs for UDP (Phase 3). They do not prevent the plan's goal from being achieved — the backend scaffold, persistence, and server entry point are fully functional.
## Next Phase Readiness
- Ready for 01-02: frontend UI details and static file serving verification
- Ready for 01-03: Docker deploy to groll.cloud
- All future phases can import from `lightsync.models`, `lightsync.devices`, `lightsync.store`
- `_DEVICE_CLASSES` dict ready to receive new strip types in Phase 5
---
*Phase: 01-foundation*
*Completed: 2026-04-05*