Files
DiunDashboard/.planning/ROADMAP.md

5.1 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):

  1. A second DIUN event for the same image does not remove its tag assignment
  2. Deleting a tag removes all associated tag assignments (foreign key cascade enforced)
  3. An oversized webhook payload is rejected with a 413 response, not processed silently
  4. 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):

  1. All existing tests pass with zero behavior change after the refactor
  2. HTTP handlers contain no SQL — all persistence goes through named Store methods
  3. Package-level global variables (db, mu, webhookSecret) no longer exist
  4. Schema changes are applied via versioned migration files, not ad-hoc DDL in application code Plans: TBD

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):

  1. Setting DATABASE_URL starts the app using PostgreSQL; omitting it falls back to SQLite with DB_PATH
  2. A fresh PostgreSQL deployment receives all schema tables via automatic migration on startup
  3. An existing SQLite user can upgrade to the new binary without any data loss or manual schema changes
  4. 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):

  1. User can dismiss all pending updates with a single button click
  2. User can dismiss all pending updates within a specific tag group with a single action
  3. User can search by image name and filter by status, tag, and sort order without a page reload
  4. A badge/counter showing pending update count is always visible; the browser tab title reflects it (e.g., "DiunDash (3)")
  5. 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
  6. 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/? Not started -
3. PostgreSQL Support 0/? Not started -
4. UX Improvements 0/? Not started -