Files
DiunDashboard/.planning/PROJECT.md

5.2 KiB

DiunDashboard

What This Is

A web-based dashboard that receives DIUN webhook events and presents a persistent, visual overview of which Docker services have available updates. Built for self-hosters who use DIUN to monitor container images but need something better than dismissable push notifications — a place that nags you until you actually update.

Core Value

Reliable, persistent visibility into which services need updating — data never disappears, and the dashboard is the one place you trust to show the full picture.

Requirements

Validated

  • ✓ Receive and store DIUN webhook events — existing
  • ✓ Display all tracked images with update status — existing
  • ✓ Acknowledge/dismiss individual updates — existing
  • ✓ Manual tag/group organization via drag-and-drop — existing
  • ✓ Tag CRUD (create, delete, assign, unassign) — existing
  • ✓ Optional webhook authentication via WEBHOOK_SECRET — existing
  • ✓ Docker deployment with volume-mounted SQLite — existing
  • ✓ Auto-polling for new updates (5s interval) — existing
  • ✓ Service icon detection from image names — existing
  • ✓ SQLite foreign key enforcement (PRAGMA foreign_keys = ON) — Phase 1
  • ✓ Proper UPSERT preserving tag assignments on re-webhook — Phase 1
  • ✓ Request body size limits (1MB) on webhook and API endpoints — Phase 1
  • ✓ Test error handling uses t.Fatalf (no silent failures) — Phase 1
  • ✓ Store interface abstracts all persistence operations (9 methods) — Phase 2
  • ✓ Server struct replaces package-level globals (db, mu, webhookSecret) — Phase 2
  • ✓ Schema migrations via golang-migrate with embedded SQL files — Phase 2
  • ✓ Per-test in-memory databases for isolated, parallel-safe testing — Phase 2

Active

  • Add PostgreSQL support alongside SQLite (dual DB, user chooses)
  • Bulk acknowledge (dismiss all, dismiss by group)
  • Filtering and search across updates
  • In-dashboard new-update indicators (badge/counter/toast)
  • Data persistence resilience (survive container restarts reliably)

Out of Scope

  • DIUN bundling / unified deployment — future milestone, requires deeper DIUN integration research
  • Auto-grouping by Docker stack/compose project — future milestone, requires Docker socket or DIUN metadata research
  • Visual DIUN config management UI — future milestone, depends on DIUN bundling
  • Notification channel management UI — DIUN already handles this; visual config deferred to DIUN integration milestone
  • OAuth / user accounts — single-user self-hosted tool, auth beyond webhook secret not needed now
  • Mobile app — web-first, responsive design sufficient

Context

  • User hosts services on a VPS using Coolify (Docker-based PaaS)
  • DIUN monitors container images for new versions and sends webhooks
  • Previous approach (Gotify push notifications) failed because notifications were easy to dismiss and forget
  • Dashboard was a daily driver but data loss (likely volume misconfiguration + SQLite bugs) eroded trust
  • Coolify doesn't show available updates — this fills that gap
  • Target audience: self-hosters using DIUN, not limited to Coolify users
  • Existing codebase: Go 1.26 backend, React 19 + Tailwind + shadcn/ui frontend, SQLite via modernc.org/sqlite

Constraints

  • Tech stack: Go backend + React frontend — established, no migration
  • Database: Must support both SQLite (simple deploys) and PostgreSQL (robust deploys)
  • Deployment: Docker-first, single-container with optional compose
  • No CGO: Pure Go SQLite driver (modernc.org/sqlite) — must maintain this for easy cross-compilation
  • Backward compatible: Existing users with SQLite databases should be able to upgrade without data loss

Key Decisions

Decision Rationale Outcome
Dual DB (SQLite + PostgreSQL) SQLite is fine for simple setups, Postgres for users who want robustness — Pending
Fix SQLite bugs before adding features Data trust is the #1 priority; features on a broken foundation waste effort ✓ Phase 1
Store interface as persistence abstraction 9 methods, no SQL in handlers; enables PostgreSQL swap without touching HTTP layer ✓ Phase 2
Server struct over package globals Dependency injection via constructor; enables per-test isolated databases ✓ Phase 2
Defer auto-grouping to future milestone Requires research into Docker socket / DIUN metadata; don't want to slow down stability fixes — Pending
Defer DIUN bundling to future milestone Significant scope; need stability and UX improvements first — Pending

Evolution

This document evolves at phase transitions and milestone boundaries.

After each phase transition (via /gsd:transition):

  1. Requirements invalidated? → Move to Out of Scope with reason
  2. Requirements validated? → Move to Validated with phase reference
  3. New requirements emerged? → Add to Active
  4. Decisions to log? → Add to Key Decisions
  5. "What This Is" still accurate? → Update if drifted

After each milestone (via /gsd:complete-milestone):

  1. Full review of all sections
  2. Core Value check — still the right priority?
  3. Audit Out of Scope — reasons still valid?
  4. Update Context with current state

Last updated: 2026-03-24 after Phase 2 completion