- 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
89 lines
5.4 KiB
Markdown
89 lines
5.4 KiB
Markdown
# 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:
|
|
- [x] 01-01-PLAN.md — Fix INSERT OR REPLACE → UPSERT in UpdateEvent(); enable PRAGMA foreign_keys = ON in InitDB(); add regression test
|
|
- [x] 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**: 2 plans
|
|
|
|
Plans:
|
|
- [x] 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):
|
|
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/2 | Not started | - |
|
|
| 3. PostgreSQL Support | 0/? | Not started | - |
|
|
| 4. UX Improvements | 0/? | Not started | - |
|