# Feature Landscape **Domain:** Container image update monitoring dashboard (self-hosted) **Researched:** 2026-03-23 **Confidence note:** Web search and WebFetch tools unavailable in this session. Findings are based on training-data knowledge of Portainer, Watchtower, Dockcheck-web, Diun, Uptime Kuma, and the self-hosted container tooling ecosystem. Confidence levels reflect this constraint. --- ## Table Stakes Features users expect from any container monitoring dashboard. Missing any of these and the tool feels unfinished or untrustworthy. | Feature | Why Expected | Complexity | Notes | |---------|--------------|------------|-------| | Persistent update list (survives page reload, container restart) | Core value prop — the whole point is to not lose track of what needs updating | Low | Already exists but broken by SQLite bugs; fixing it is table stakes | | Individual acknowledge/dismiss per image | Minimum viable workflow to mark "I dealt with this" | Low | Already exists | | Bulk acknowledge — dismiss all | Without this, users with 20+ images must click 20+ times; abandonment is near-certain | Medium | Flagged in CONCERNS.md as missing; very high priority | | Bulk acknowledge — dismiss by group/tag | If you've tagged a group and updated everything in it, dismissing one at a time is painful | Medium | Depends on tag feature existing (already does) | | Search / filter by image name | Standard affordance in any list of 10+ items | Medium | Missing; flagged in PROJECT.md as active requirement | | Filter by status (pending update vs acknowledged) | Separating signal from noise is core to the "nag until you fix it" value prop | Low | Missing; complements search | | New-update indicator (badge, counter, or highlight) | Users need to know at a glance "something new arrived since I last checked" | Medium | Flagged in PROJECT.md as active requirement | | Page/tab title update count | Gives browser-tab visibility without opening the page — "DiunDashboard (3)" in the tab | Low | Tiny implementation, high perceived value | | Data integrity across restarts | If the DB loses data on restart, trust collapses | Medium | High-priority bug: INSERT OR REPLACE + missing FK pragma | | PostgreSQL option for non-SQLite users | Self-hosters who run Postgres expect it as an option for persistent services | High | Flagged in PROJECT.md; dual-DB is the plan | --- ## Differentiators Features not universally expected but meaningfully better than the baseline. Build these after table stakes are solid. | Feature | Value Proposition | Complexity | Notes | |---------|-------------------|------------|-------| | Filter by tag/group | Users who've organized images into groups want to scope their view | Low | Tag infrastructure already exists; filter is a frontend-only change | | Visual "new since last visit" highlight (session-based) | Distinguish newly arrived updates from ones you've already seen | Medium | Requires client-side tracking of "last seen" timestamp (localStorage) | | Toast / in-page notification on new update arrival (during polling) | Passive, non-intrusive signal when updates arrive while the tab is open | Medium | Uses existing 5-second poll; could compare prior state | | Browser notification API on new update | Reaches users when the tab is backgrounded | High | Requires permission prompt; risky UX if over-notified; defer | | Sort order controls (newest first, image name, registry) | Power-user need once list grows beyond 20 images | Low | Pure frontend sort; no backend change needed | | Filter by registry | Useful for multi-registry setups | Low | Derived from image name; no schema change needed | | Keyboard shortcuts (bulk dismiss with keypress, focus search) | Power users strongly value keyboard-driven UIs | Medium | Rarely table stakes for self-hosted tools but appreciated | | Light / dark theme toggle (currently hardcoded dark) | Respects system preferences; accessibility baseline | Low | Flagged in CONCERNS.md; CSS variable change + prefers-color-scheme | | Drag handle always visible (not hover-only) | Accessibility: keyboard and touch users need discoverable reordering | Low | Flagged in CONCERNS.md | | Alternative to drag-and-drop for tag assignment | Dropdown select for assigning tags; removes dependency on pointer hover | Medium | Fixes accessibility gap in CONCERNS.md | | Data retention / auto-cleanup of old acknowledged entries | Prevents unbounded DB growth over months/years | Medium | Configurable TTL for acknowledged records | --- ## Anti-Features Features to deliberately NOT build in this milestone. | Anti-Feature | Why Avoid | What to Do Instead | |--------------|-----------|-------------------| | Auto-triggering image pulls or container restarts from the dashboard | This app is a viewer, not an orchestrator; acting on the host would require Docker socket access and creates a significant security surface | Remain read-only; users run `docker pull` / Coolify update themselves | | Notification channel management UI (email, Slack, webhook routing) | DIUN already manages notification channels; duplicating this is wasted effort and creates config drift | Keep DIUN as the notification layer; this dashboard is the persistent record | | OAuth / multi-user accounts | Single-user self-hosted tool; auth complexity is disproportionate to the use case | Document "don't expose to the public internet"; optional basic auth via reverse proxy is sufficient | | Real-time WebSocket / SSE updates | The 5-second poll is adequate for this use case; SSE/WS adds complexity without meaningful UX gain for a low-frequency signal | Improve the poll with ETag/If-Modified-Since to reduce wasted bandwidth instead | | Mobile-native / PWA features | Web-first responsive design is sufficient; self-hosters rarely need a fully offline-capable PWA for an internal tool | Ensure the layout is responsive for mobile browser access | | Auto-grouping by Docker stack / Compose project | Requires Docker socket access or DIUN metadata changes; significant scope increase | Defer to a dedicated future milestone per PROJECT.md | | DIUN config management UI | Requires DIUN bundling; out of scope for this milestone | Defer per PROJECT.md | | Changelog or CVE lookups per image | Valuable but requires external API integrations (Docker Hub, Trivy, etc.); different product scope | Document as a possible future phase | | Undo for dismiss actions | Adds state complexity; accidental dismisses are recoverable by the next DIUN scan | Keep dismiss as final; communicate this in the UI | --- ## Feature Dependencies ``` Data integrity fixes (SQLite upsert + FK pragma) → must precede all UX features (broken data undermines everything) PostgreSQL support → depends on struct-based refactor (global state → Server struct) → struct refactor is also a prerequisite for safe parallel tests Bulk acknowledge (all) → no dependencies; purely additive API + frontend work Bulk acknowledge (by group) → depends on tag feature (already exists) Search / filter by image name → no backend dependency; frontend filter on existing GET /api/updates payload Filter by status → no backend dependency; frontend filter Filter by tag → depends on tag data being returned by GET /api/updates (already is) New-update indicator (badge/counter) → depends on frontend comparing poll results across cycles → no backend change needed Page title update count → depends on update count being derivable from GET /api/updates (already is) Toast notification on new arrival → depends on new-update indicator logic (same poll comparison) → can share implementation Sort controls → no dependencies; pure frontend Data retention / TTL → depends on PostgreSQL support OR can be added to SQLite path independently → no frontend dependency Light/dark theme → no dependencies; CSS + localStorage Drag handle accessibility fix → no dependencies Alternative tag assignment (dropdown) → no dependencies ``` --- ## MVP Recommendation for This Milestone The milestone goal is: bug fixes, dual DB, and UX improvements (bulk actions, filtering, search, new-update indicators). Prioritize in this order: 1. **Fix SQLite data integrity** (UPSERT + FK pragma) — trust foundation; nothing else matters if data is lost 2. **Bulk acknowledge (all + by group)** — the single highest-impact UX addition; drops manual effort from O(n) to O(1) 3. **Search + filter by name/status/tag** — table stakes for any list of >10 items 4. **New-update indicator + page title count** — completes the "persistent visibility" core value with in-page signal 5. **PostgreSQL support** — requires struct refactor; large but well-scoped; enables users who need it 6. **Light/dark theme + accessibility fixes** — low complexity; removes known complaints Defer to next milestone: - **Data retention / TTL**: Real but not urgent; unbounded growth is a future problem for most users - **Toast notifications**: Nice to have but the badge + title count cover the signal adequately - **Alternative tag assignment (dropdown)**: Accessibility improvement but drag-and-drop exists and works - **Browser notification API**: High complexity, UX risk, very low reward vs. the badge approach --- ## Sources - Project context: `.planning/PROJECT.md` (validated requirements and constraints) - Codebase audit: `.planning/codebase/CONCERNS.md` (confirmed gaps: bulk ops, search, indicators, FK bugs) - Training-data knowledge of: Portainer CE, Watchtower (no UI), Dockcheck-web, Diun native notifications, Uptime Kuma (comparable self-hosted monitoring dashboard UX patterns) — **MEDIUM confidence** (cannot be verified in this session due to tool restrictions; findings should be spot-checked against current Portainer docs and community forums before roadmap finalization)