diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..a50f1af --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,123 @@ +# Dash — Roadmap + +A self-hosted homelab dashboard. CasaOS-grade ease of use, Vercel-grade design. +Single container, UI-managed, no YAML, no auth required. + +Stack: **Go + Gin + SQLite** (single static binary, embeds frontend) · **React 18 + Vite + TS strict + Tailwind + shadcn/ui + dnd-kit** · OpenAPI-generated client. + +--- + +## Design system + +Primary renderer: **Bento Mono** (`mockups/d-bento-mono.html`) — bento grid on a +monochrome zinc palette, Geist + Geist Mono, hairline borders, semantic status +color only. + +Alternate view themes ship post-MVP on the same data model (Phase 3.5): + +| Theme | Source mockup | Character | +|---|---|---| +| Bento Mono (default) | `d-bento-mono.html` | mixed-size grid, widgets inline | +| Mono Cards | `a-vercel-mono.html` | uniform card grid, quietest | +| Index | `e-editorial.html` | serif headers, list rows, stat strip | +| Console | `f-console.html` | terminal panels, `[ up ]` tags | + +Rule: themes change the renderer, never the data or the interactions. + +--- + +## Releases + +| Version | Contents | Gate | +|---|---|---| +| `v0.1.0` | Phase 0 + 1 — working MVP, single image | manual smoke test | +| `v0.2.0` | Phase 2 — widget layer + first integrations | Pi-hole widget live | +| `v0.3.0` | Phase 3 — alternate themes, search, icon packs | theme switcher works | +| `v1.0.0` | Phase 4 — OSS polish, docs, importers, CI releases | public repo launch | +| `v1.x` | Phase 5 — demand-driven extras only | per-feature | + +--- + +## Phase 0 — Foundation → part of v0.1.0 + +Repo hygiene and pipelines before features. + +- [ ] Monorepo scaffold (`apps/frontend`, `apps/backend`, `packages/api-client`, `infra/`, `data/`) +- [ ] MIT `LICENSE`, `README.md`, `.gitignore`, `AGENTS.md` +- [ ] `openapi.yaml` stub → generated TS client (`packages/api-client`) +- [ ] Backend skeleton: Gin router, `zap` logging, `/api/healthz`, SQLite open + goose migrations runner +- [ ] Frontend skeleton: Vite + TS strict + Tailwind + shadcn/ui, theme tokens matching `d-bento-mono.html` CSS vars +- [ ] CI (GitHub Actions): `go build ./...`, `go vet ./...`, `go test ./...`, `tsc --noEmit`, `oxlint` + vendored anti-slop rules, `npm run build` +- [ ] Multi-stage `Dockerfile` (frontend build → Go build → `FROM scratch`/distroless, `embed.FS` serves UI) +- [ ] `docker-compose.yml` — one service, `./data:/data` volume + +**Exit:** `docker compose up` serves a blank board. CI green on `main`. + +## Phase 1 — MVP → v0.1.0 + +The product's spine: sections, services, drag-drop, multi-URL. + +- [ ] Schema: `sections`, `items`, `urls`, `settings` (fractional `position REAL` ordering) +- [ ] REST API: CRUD for sections/items/urls, `reorder` endpoints, icon upload, `settings`, `export`/`import` JSON +- [ ] Board UI (Bento Mono): section headers (label, count, hairline, chevron), service tiles (icon, name, host, status chip) +- [ ] dnd-kit: reorder items in a section, move items between sections, reorder sections; persist on drop +- [ ] Collapse/expand sections (persisted) +- [ ] `UrlPopover`: 1 URL → direct open, 2+ → chooser (`local`/`external`/custom tags) +- [ ] `AddServiceDialog` / `EditServiceDialog` (name, URLs+labels, icon URL or file upload) +- [ ] Icon handling: upload to `data/icons/`, remote URL passthrough, letter-tile fallback +- [ ] Dark/light toggle (persisted), responsive to ~360px +- [ ] Status ping: server-side HEAD request per service URL, cached ~60s → `up`/`down` chip + +**Exit:** create sections, add services with icons and dual URLs, drag everything, reload — state persists. `docker run` single image works. Export/import round-trips. + +## Phase 2 — Widgets → v0.2.0 + +- [ ] Go widget registry: `Widget` interface (`Type()`, `Fetch(cfg)`), `GET /api/widgets/:id/data` with ~30s in-process TTL cache +- [ ] `GET /api/widgets/types` → registry metadata drives the add-widget dialog +- [ ] `WidgetHost` component: maps `config.type` → React component, polls with backoff +- [ ] Widgets as grid items (same `items` table, `kind = 'widget'`, `config JSON`) +- [ ] Clock/timezone widget (frontend-only) +- [ ] Pi-hole fetcher (blocked %, queries today, per-day bar series) +- [ ] AdGuard Home fetcher (blocked %, clients) +- [ ] Immich fetcher (photo count, library size) +- [ ] Per-widget config UI (endpoint URL, API key — stored in `config`, never logged) + +**Exit:** Pi-hole widget shows real data; adding a new integration = one Go file + one React component. + +## Phase 3 — Themes & ergonomics → v0.3.0 + +- [ ] Theme token layer finalized; view-theme switcher in settings +- [ ] Alternate renderers: Mono Cards, Index, Console +- [ ] ⌘K command palette: jump to service, add service, toggle theme +- [ ] dashboard-icons auto-suggest in icon picker (name → icon URL) +- [ ] User services list → prioritized widget backlog (owner-supplied list pending) + +**Exit:** all four renderers work off the same board state; palette navigates everything. + +## Phase 4 — Open-source launch → v1.0.0 + +- [ ] Docs: install, configuration, widget development guide (`docs/`) +- [ ] Importers: Homepage `services.yml`, Homarr JSON, Dashy `conf.yml` → sections/items/urls +- [ ] `README.md` hero: screenshots (4 themes), demo GIF, `docker run` one-liner +- [ ] goreleaser → binaries; GHCR image on tag; semver + `CHANGELOG.md` +- [ ] `CONTRIBUTING.md`, issue/PR templates, code of conduct, security policy +- [ ] i18n scaffolding (en default) +- [ ] Public repo flip + announcement assets + +**Exit:** a stranger can `docker run`, import their Homepage config, and have a working board in under two minutes. + +## Phase 5 — Post-1.0 (demand-driven only) + +Build only what users actually ask for. Candidates, unordered: + +- Optional auth (local password + OIDC) — most-requested, likely first +- Health-check history + uptime graphs +- Custom CSS / accent color / wallpaper +- Iframe/embed widgets, API-status widgets (generic JSON path) +- PWA install, mobile layout polish +- Multiple boards + +## Non-goals (v1) + +Auth, Postgres/external DB, multi-user, mobile app, container lifecycle +management, YAML-as-source-of-truth. Revisit only with evidence of demand. diff --git a/docs/specs/2026-09-16-dash-design.md b/docs/specs/2026-09-16-dash-design.md index c95bac6..8fe2087 100644 --- a/docs/specs/2026-09-16-dash-design.md +++ b/docs/specs/2026-09-16-dash-design.md @@ -86,53 +86,25 @@ Frontend never hand-writes API types — generated client from `openapi.yaml`. - `CommandPalette` (⌘K) — Phase 3 - dnd-kit `DndContext` at board level; sections and items both sortable -## 7. UI direction — pending +## 7. UI direction — DECIDED 2026-09-16 -Static mockups in `mockups/` — open each, compare. Round 1 shortlist: A + B. C rejected (glass/wallpaper is not the target look). +**Primary: `d-bento-mono.html`** — bento grid on the monochrome zinc palette. Geist + Geist Mono, hairline borders, no glow, status chips carry the only color (green/amber semantic). -| File | Direction | Character | +**Alternate view themes** (same data model, different renderers — post-MVP theme system): + +| Mockup | Theme | Character | |---|---|---| -| `a-vercel-mono.html` | Flat monochrome | Geist, hairlines, no shadows, quietest | -| `b-command-bento.html` | Bento grid | mixed tile sizes, widgets inline, densest; bg glow disliked | -| ~~`c-casa-glass.html`~~ | ~~Glass + wallpaper~~ | rejected | -| `d-bento-mono.html` | Bento + mono palette | B's grid on A's zinc palette, no glow — direct merge of the two favorites | -| `e-editorial.html` | List paradigm | serif index headers, full-width rows, stat strip — no cards | -| `f-console.html` | Terminal | JetBrains Mono, bordered panels, `[ up ]` tags, prompt glyphs | +| `a-vercel-mono.html` | Mono Cards | uniform card grid, quietest | +| `e-editorial.html` | Index | serif headers, full-width rows, stat strip | +| `f-console.html` | Console | JetBrains Mono, bordered panels, `[ up ]` tags | -Decision recorded here once picked. +Rejected and deleted: bento-with-glow (B), casa glass (C). + +Implementation note: design tokens (CSS vars → Tailwind theme) shared across all themes; layout renderer is the only per-theme component. Token structure must be decided in Phase 0 so alternates stay cheap. ## 8. Roadmap -### Phase 0 — Foundation -- [ ] Monorepo scaffold, LICENSE (MIT), README, .gitignore, AGENTS.md -- [ ] `openapi.yaml` stub → generated TS client pipeline -- [ ] CI: `go build`, `go vet`, `tsc --noEmit`, oxlint + vendored anti-slop rules -- [ ] `docker compose up` runs the app - -### Phase 1 — MVP -- [ ] Schema + goose migrations; section/item/URL CRUD -- [ ] Board UI: sections, cards, collapse, drag-drop ordering (persist position) -- [ ] Multi-URL popover; icon URL + upload -- [ ] Add/Edit dialogs; delete with confirm -- [ ] Dark/light; responsive to phone width -- [ ] Single-image Dockerfile; JSON export/import - -### Phase 2 — Widgets -- [ ] Widget registry (Go) + `WidgetHost` (React) -- [ ] Clock/timezone widget (frontend-only) -- [ ] Pi-hole, AdGuard Home, Immich fetchers + per-widget config UI -- [ ] Service up/down ping (server-side HEAD, cached) - -### Phase 3 — Open-source readiness -- [ ] Docs (install, config, widget dev guide), screenshots, demo GIF -- [ ] dashboard-icons auto-suggest in icon picker -- [ ] Importers: Homepage `services.yml`, Homarr JSON, Dashy `conf.yml` -- [ ] ⌘K search palette; i18n scaffolding -- [ ] goreleaser (binaries) + GHCR image + semver tags + CHANGELOG -- [ ] Issue/PR templates, CONTRIBUTING.md, code of conduct - -### Phase 4 — Post-1.0 (demand-driven only) -- Optional auth (local + OIDC), health-history graphs, custom CSS/themes, iframe widgets, PWA, wallpaper support for direction A +Canonical roadmap lives in [`ROADMAP.md`](../../ROADMAP.md) at repo root — single source of truth, kept versioned with the code. ### Explicit non-goals for v1 Auth, Postgres, multi-user, mobile app, container management, YAML-as-source-of-truth. diff --git a/mockups/b-command-bento.html b/mockups/b-command-bento.html deleted file mode 100644 index 77bdb4c..0000000 --- a/mockups/b-command-bento.html +++ /dev/null @@ -1,449 +0,0 @@ - - - - - -Dash — B · Command Bento - - - - - - -
-
- - Dash -
- home / main board - - - -
- -
-
- - - - -
-
Local time ● LIVE
-
--:--:--
-
PRG NYC TYO
-
-
-
Pi-hole · today
-
24.6%
-
20,721 ads blocked · 84,213 queries
-
-
-
-
AdGuard
-
11.2%
-
blocked · 31 clients
-
-
-
Immich
-
12,483
-
photos · 96.4 GB
-
-
-
Uptime · 30d
-
99.7%
-
1 incident · Radarr
-
-
-
Storage
-
61%
-
14.2 / 23.2 TB
-
- - - - -
-
-
Pi-hole
10.0.0.2
- UP -
-
-
-
-
AdGuard Home
10.0.0.3:3000
- UP -
-
-
-
Nginx Proxy Mgr
10.0.0.2:81
- UP -
-
-
-
-
Uptime Kuma
status.tdvorak.dev
- UP -
-
- - - - -
-
-
Jellyfin
watch.tdvorak.dev
- UP -
-
-
-
-
Immich
photos.tdvorak.dev
- UP -
-
-
-
-
Navidrome
10.0.0.10:4533
- UP -
-
-
-
qBittorrent
10.0.0.10:8080
- UP -
-
-
-
Sonarr
10.0.0.10:8989
- UP -
-
-
-
Radarr
10.0.0.10:7878
- DOWN -
- - - - -
-
-
Proxmox
10.0.0.4:8006
- UP -
-
-
-
Portainer
10.0.0.4:9000
- UP -
-
-
-
TrueNAS
nas.tdvorak.dev
- UP -
-
-
-
-
Grafana
10.0.0.4:3100
- UP -
-
-
-
Vaultwarden
vault.tdvorak.dev
- UP -
-
-
-
Home Assistant
home.tdvorak.dev
- UP -
-
-
-
-
Nextcloud
cloud.tdvorak.dev
- UP -
- -
- -

Mockup B — Command Bento. Widgets and services share one grid. Click a multi-URL tile (Jellyfin, Immich…) for the chooser. Section headers collapse.

-
- - - - diff --git a/mockups/c-casa-glass.html b/mockups/c-casa-glass.html deleted file mode 100644 index 61b0d34..0000000 --- a/mockups/c-casa-glass.html +++ /dev/null @@ -1,466 +0,0 @@ - - - - - -Dash — C · Casa Glass - - - - -
- -
-
- - Dash -
- - - -
- -
-
-
-
Good evening
-
--:--
-
-
-
-
Prague
--:--
-
New York
--:--
-
Tokyo
--:--
-
-
- -
-

Widgets

4 - -
-
-
-
-
Pi-hole
-
24.6%
-
ads blocked today · 84,213 queries
-
-
-
AdGuard Home
-
11.2%
-
blocked · 31 clients online
-
-
-
Immich
-
12,483
-
photos · 96.4 GB library
-
-
-
Storage
-
61%
-
14.2 of 23.2 TB used
-
-
-
-
- -
-

Network

4 - -
-
-
-
-
Pi-hole
-
2 URLs
-
-
-
-
-
AdGuard Home
-
-
-
-
-
Nginx Proxy Mgr
-
2 URLs
-
-
-
-
-
Uptime Kuma
-
2 URLs
-
-
-
-
- -
-

Media

6 - -
-
-
-
-
Jellyfin
-
2 URLs
-
-
-
-
-
Immich
-
2 URLs
-
-
-
-
-
Navidrome
-
-
-
-
-
qBittorrent
-
-
-
-
-
Sonarr
-
-
-
-
-
Radarr
-
-
-
-
- -
-

Infrastructure

7 - -
-
-
-
-
Proxmox
-
-
-
-
-
Portainer
-
-
-
-
-
TrueNAS
-
2 URLs
-
-
-
-
-
Grafana
-
-
-
-
-
Vaultwarden
-
-
-
-
-
Home Assistant
-
2 URLs
-
-
-
-
-
Nextcloud
-
-
-
-
- -

Mockup C — Casa Glass. Wallpaper + glass trays + homescreen tiles. Click a “2 URLs” tile for the chooser. Trays collapse.

-
- - - -