# Apply Progress: Configurable Dashboard Widgets **Change:** `configurable-dashboard-widgets` **Apply run:** PR 1 / Slice 1 — Backend CRUD and default seeding **Date:** 2026-06-19 ## Completed tasks (Slice 1) All Slice 1 tasks are marked `- [x]` in `tasks.md`: - [x] 1.1 Create widget Pydantic models - [x] 1.2 Create backend widget registry - [x] 1.3 Implement widgets router (CRUD + metadata) - [x] 1.4 Extend `SettingsStore` for `dashboard_widgets` - [x] 1.5 Register widgets router in `main.py` - [x] 1.6 Add backend tests for registry, CRUD, and seeding - [x] 1.7 Verify backend slice ## Files changed ### New files - `backend/src/media_library_viewer_api/models/widgets.py` — Pydantic models: `WidgetInstance`, `WidgetInstanceInput`, `WidgetTypeInfo`, `WidgetDataResponse`, plus credential-key/secret-value validators. - `backend/src/media_library_viewer_api/widgets/__init__.py` — Package marker. - `backend/src/media_library_viewer_api/widgets/registry.py` — Closed `WIDGET_REGISTRY` for six Phase 1 widget types, source-type listing, type metadata, and lightweight config-schema validation. - `backend/src/media_library_viewer_api/routers/widgets.py` — REST endpoints for `/api/widgets/sources`, `/types`, `/instances`, and instance CRUD. - `backend/tests/test_widgets.py` — 12 tests covering registry, CRUD, validation, and seeding. ### Modified files - `backend/src/media_library_viewer_api/services/settings_store.py` — Added `dashboard_widgets` table, index, CRUD helpers, default seeding, and refactored `ensure_defaults()` to seed widgets independently of machine seeding. - `backend/src/media_library_viewer_api/main.py` — Registered `widgets_router`. ## Verification Commands run: ```bash cd backend .venv/bin/python -m ruff check . # All checks passed PYTHONPATH=src .venv/bin/python -m pytest # 185 passed, 2 warnings cd ../frontend npm run lint # 2 pre-existing warnings, 0 errors npm run build # Built successfully ``` Focused widget test output: `12 passed`. ## Deviations from design - None significant for Slice 1. The implementation follows the design's backend CRUD layout. - Used `HTTP_422_UNPROCESSABLE_CONTENT` instead of the deprecated `HTTP_422_UNPROCESSABLE_ENTITY`. ## Remaining work - Slice 2: Backend source adapters + `GET /api/widgets/instances/{id}/data` - Slice 3: Frontend types/API/hooks/registry/components - Slice 4: Dashboard loop + configuration UI + addon pages ## PR boundary This slice is **PR 1 of 4** in the approved stacked-to-main chain. It is backend-only and leaves the frontend build/lint green. **Actual changed-line count:** ~780 added lines across production code and tests (new files: ~597 lines; modified files: ~181 insertions). This is above the nominal ~400-line review budget, but Slice 1 is the smallest coherent backend unit: removing the CRUD router, store helpers, or tests would leave the slice non-functional or unverifiable. If the reviewer prefers a smaller blast radius, the store helpers (~90 lines) could be split into a preceding PR, though that PR would not be independently user-visible.