- 02-01-SUMMARY.md: Store interface + SQLiteStore + golang-migrate v4.19.1 - STATE.md: advanced to plan 2 of 2, recorded decisions and metrics - ROADMAP.md: phase 02 progress updated (1/2 summaries) - REQUIREMENTS.md: REFAC-01 and REFAC-03 marked complete
5.4 KiB
Roadmap: DiunDashboard
Overview
This milestone restores data trust and then extends the foundation. Phase 1 fixes active bugs that silently corrupt user data today. Phase 2 refactors the backend into a testable, interface-driven structure — the structural prerequisite for everything that follows. Phase 3 adds PostgreSQL as a first-class alternative to SQLite. Phase 4 delivers the UX features that make the dashboard genuinely usable at scale: bulk dismiss, search/filter, new-update indicators, and accessibility fixes.
Phases
Phase Numbering:
- Integer phases (1, 2, 3): Planned milestone work
- Decimal phases (2.1, 2.2): Urgent insertions (marked with INSERTED)
Decimal phases appear between their surrounding integers in numeric order.
- Phase 1: Data Integrity - Fix active SQLite bugs that silently delete tag assignments and suppress test failures
- Phase 2: Backend Refactor - Replace global state with Store interface + Server struct; prerequisite for PostgreSQL
- Phase 3: PostgreSQL Support - Add PostgreSQL as an alternative backend via DATABASE_URL, with versioned migrations
- Phase 4: UX Improvements - Bulk dismiss, search/filter, new-update indicators, and accessibility fixes
Phase Details
Phase 1: Data Integrity
Goal: Users can trust that their data is never silently corrupted — tag assignments survive new DIUN events, foreign key constraints are enforced, and test failures are always visible Depends on: Nothing (first phase) Requirements: DATA-01, DATA-02, DATA-03, DATA-04 Success Criteria (what must be TRUE):
- A second DIUN event for the same image does not remove its tag assignment
- Deleting a tag removes all associated tag assignments (foreign key cascade enforced)
- An oversized webhook payload is rejected with a 413 response, not processed silently
- A failing assertion in a test causes the test run to report failure, not pass silently Plans: 2 plans
Plans:
- 01-01-PLAN.md — Fix INSERT OR REPLACE → UPSERT in UpdateEvent(); enable PRAGMA foreign_keys = ON in InitDB(); add regression test
- 01-02-PLAN.md — Add http.MaxBytesReader body limits to 3 handlers (413 on oversized); replace 6 silent test returns with t.Fatalf
Phase 2: Backend Refactor
Goal: The codebase has a clean Store interface and Server struct so the SQLite implementation can be swapped without touching HTTP handlers, enabling parallel test execution and PostgreSQL support Depends on: Phase 1 Requirements: REFAC-01, REFAC-02, REFAC-03 Success Criteria (what must be TRUE):
- All existing tests pass with zero behavior change after the refactor
- HTTP handlers contain no SQL — all persistence goes through named Store methods
- Package-level global variables (db, mu, webhookSecret) no longer exist
- Schema changes are applied via versioned migration files, not ad-hoc DDL in application code Plans: 2 plans
Plans:
- 02-01-PLAN.md — Create Store interface (9 methods), SQLiteStore implementation, golang-migrate migration infrastructure with embedded SQL files
- 02-02-PLAN.md — Convert handlers to Server struct methods, remove globals, rewrite tests for per-test isolated databases, update main.go wiring
Phase 3: PostgreSQL Support
Goal: Users running PostgreSQL infrastructure can point DiunDashboard at a Postgres database via DATABASE_URL and the dashboard works identically to the SQLite deployment Depends on: Phase 2 Requirements: DB-01, DB-02, DB-03 Success Criteria (what must be TRUE):
- Setting DATABASE_URL starts the app using PostgreSQL; omitting it falls back to SQLite with DB_PATH
- A fresh PostgreSQL deployment receives all schema tables via automatic migration on startup
- An existing SQLite user can upgrade to the new binary without any data loss or manual schema changes
- The app can be run with Docker Compose using an optional postgres service profile Plans: TBD UI hint: no
Phase 4: UX Improvements
Goal: Users can manage a large list of updates efficiently — dismissing many at once, finding specific images quickly, and seeing new arrivals without manual refreshes Depends on: Phase 2 Requirements: BULK-01, BULK-02, SRCH-01, SRCH-02, SRCH-03, SRCH-04, INDIC-01, INDIC-02, INDIC-03, INDIC-04, A11Y-01, A11Y-02 Success Criteria (what must be TRUE):
- User can dismiss all pending updates with a single button click
- User can dismiss all pending updates within a specific tag group with a single action
- User can search by image name and filter by status, tag, and sort order without a page reload
- A badge/counter showing pending update count is always visible; the browser tab title reflects it (e.g., "DiunDash (3)")
- New updates arriving during active polling trigger a visible in-page toast, and updates seen for the first time since the user's last visit are visually highlighted
- The light/dark theme toggle is available and respects system preference; the drag handle for tag reordering is always visible without hover Plans: TBD UI hint: yes
Progress
Execution Order: Phases execute in numeric order: 1 → 2 → 3 → 4
| Phase | Plans Complete | Status | Completed |
|---|---|---|---|
| 1. Data Integrity | 0/2 | Not started | - |
| 2. Backend Refactor | 0/2 | Not started | - |
| 3. PostgreSQL Support | 0/? | Not started | - |
| 4. UX Improvements | 0/? | Not started | - |