Files
serverAppConfigs/docs/Infrastructure/Homepage Design Grilling.md
T
Frank cdae928f37 Homepage: settle design (grilling Q1-Q5), log open questions Q6-Q43, progress report
- Homepage.md: rewritten to the settled design (single site, user + /admin/
  pages, server-side status.json via a 3-min systemd-timer checker, terminal
  TUI theme). Added mermaid diagrams: site structure, status states, checker
  flow. Recorded the classification (user vs admin; *arr excluded; LLM admin;
  backends status-only) and the documented future shift to client-side probing.
- Homepage Design Grilling.md (new): the decision log — settled Q1-Q5 plus 38
  open questions (Q6-Q43) across 10 categories, each with a recommendation.
- docs/index.md: link the grilling page (satisfies the index-links-every-page test).
- report/homepage-grilling-2026-08-22.html: self-contained terminal-TUI progress
  report (settled decisions, verified stack baseline, overnight processing, work
  threads, the open questions, and how to continue).

Baseline recorded: Dankclaw fully up (10/10); the Dankserver media stack is down
(only Calibre-Web + the LLM are up; no .env on the target) — a separate thread.
No homepage code built yet; the design is pending the operator's answers to Q6-Q43.
2026-08-23 02:59:48 -07:00

168 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Homepage Design Grilling
The decision log for the homepage design. It records what is settled and the open questions that remain. Answer the open questions in the morning report; the design is built only after they are settled.
## Decided
| # | Decision | Value |
|---|----------|-------|
| Q1 | How the page learns up/down | **Server-side** checker writes `status.json`; the page reads only that file. (Eventual target: client-side probing.) |
| Q2 | How the checker runs | **systemd timer**, rewrites `status.json` every **3 minutes**. |
| Q3 | Page model | **Single site** on Dankclaw. Root = user services (no host labels). `/admin/` = admin services, separate password. Optional `/how/` tourist page. |
| Q4 | (superseded by Q3 restructure) | — |
| Q5 | Service split | User: SearXNG, ComfyUI, OpenWebUI, Gitea, Calibre-Web, RomM, Copyparty, Plex, Jellyfin. Admin: Hermes, Grafana, Prometheus, Loki, Caddy, dnsmasq, Gluetun, LLM fleet, low-level backends (status-only). The *arr stack is **excluded** (separate effort, not started). |
Styling is settled in principle: terminal TUI, Terminus (monospace fallback), green-on-black, 1995 phosphor palette (green `#33ff66`, red `#ff5555`, amber `#ffcc33`, cyan `#33ccff`, bg `#050805`).
## Open questions
Each question carries a recommendation. Answer them in the morning report.
### A. Architecture and structure
**Q6 — The optional `/how/` "tourist" page: build now or defer?**
Recommendation: **defer** to a later effort. When built, make it **public** (no auth) so a visitor can see the architecture. It can render the mermaid diagrams from this repo.
**Q7 — One `status.json` or two (`user-status.json` + `admin-status.json`)?**
Recommendation: **one** `status.json`. Each service carries a `category` field. Each page filters client-side. One file, one checker output, one source of truth.
**Q8 — One `services.json` or split by page?**
Recommendation: **one** `services.json` with all services and a `category` field. The checker reads one file. Simpler to maintain.
### B. The checker
**Q9 — What language for the checker script?**
Recommendation: **python3** (available on Dankclaw, no dependencies, emits valid JSON cleanly). A bash + `nc` variant works too, but JSON by hand is error-prone.
**Q10 — Probe method: TCP connect or HTTP GET?**
Recommendation: **TCP connect** to `host:port`. Uniform, works for non-HTTP backends, and "port listening = up" matches the verified ground truth.
**Q11 — Probe timeout per service?**
Recommendation: **3 seconds**. A dead port refuses fast; a black-holed one times out at 3 s. With ~25 services the worst-case run is well under the 3-minute interval.
**Q12 — LLM "loading" state (health returns 503 during model load)?**
Recommendation: keep **three** states. A listening port shows **Up**. Optionally probe `/health` and treat 503 as Up (the process is alive). A dedicated "loading" state is a later refinement.
**Q13 — Where does the checker live in the repo?**
Recommendation: `scripts/homepage-status.py` plus `scripts/homepage-status.service` and `scripts/homepage-status.timer`, all tracked in git like the other units.
**Q14 — How does the checker reach the Dankserver backends?**
Recommendation: the `probe` field carries a full `host:port`. Dankclaw services use `127.0.0.1:PORT`. Dankserver services use `192.168.0.235:PORT`. The checker (on Dankclaw) connects to each over the LAN. Verified reachable.
### C. The status model
**Q15 — How is a service marked WIP?**
Recommendation: a static `"wip": true` field. The checker skips the probe and the page shows WIP. Drop the old self-referential "Homepage" entry (a page does not list itself).
**Q16 — Staleness: what if the timer fails and `status.json` is old?**
Recommendation: write a `generated_at` timestamp into `status.json`. The page shows a "status may be stale" warning when it is older than 10 minutes.
**Q17 — Atomic writes?**
Recommendation: the checker writes to a temp file, then renames over `status.json`. A crash never leaves a half-written file. The last good status survives.
### D. Auth
**Q18 — The admin password: a second `.env` variable?**
Recommendation: yes. `CADDY_ADMIN_HASH` in the host `.env` (git-ignored), rendered into the Caddyfile at deploy, operator-only. The root page keeps `CADDY_BASICAUTH_HASH`.
**Q19 — Per-path basicauth in Caddy v2?**
Recommendation: a `@admin path /admin/*` matcher with a second `basicauth @admin` block. Confirm the exact syntax against the Caddy docs during implementation.
### E. The pages and content
**Q20 — Where do the one-line descriptions come from?**
Recommendation: hand-written one-liners in `services.json`, drafted from the existing reference docs.
**Q21 — The "Open" link target: the Caddy site or the direct backend?**
Recommendation: the **Caddy site** URL (what a user actually opens). Status-only backends set `showLink: false` (no Open link).
**Q22 — The "docs" link: usage page or the existing reference doc?**
Recommendation: link to the **existing** reference doc (`docs/.../X.md`) as a placeholder. Swap to the per-service usage page when that workstream is built.
**Q23 — Page layout: cards or a terminal-style list?**
Recommendation: a **terminal-style list** (one service per line, like `systemctl list-units`). Columns: `STATUS | NAME | description | (open) (docs)`. Fits the TUI aesthetic better than cards.
**Q24 — A summary line at the top?**
Recommendation: yes. One line, e.g. `UP 9 DOWN 2 WIP 1`, per page.
### F. Styling
**Q25 — Terminus: bundle the font or use a fallback?**
Recommendation: **bundle** Terminus (woff2) via `@font-face`, with a monospace fallback stack. Confirm the license (Terminus is freely distributable) and drop the files in `fonts/`.
**Q26 — Confirm the palette?**
Recommendation: as proposed (green `#33ff66`, red `#ff5555`, amber `#ffcc33`, cyan `#33ccff`, bg `#050805`). Tune for contrast and readability.
**Q27 — CRT effects (scanlines + glow)?**
Recommendation: subtle scanlines + a soft green `text-shadow`. Make it toggleable (a `?crt=0` param) for those who find it much.
**Q28 — Blinking cursor / animation?**
Recommendation: a subtle CSS-only blinking block cursor on the header. Respect `prefers-reduced-motion`.
### G. The usage-docs workstream
**Q29 — Scope of the per-service usage pages?**
Recommendation: concise **how-to** guides (what it is, how to open it, the common tasks). Distinct from the deep reference docs in `docs/`.
**Q30 — Where do the usage pages live?**
Recommendation: served from the homepage site, same origin, at `/usage/<svc>/`. Source in the repo under `shared/homepage/usage/<svc>/`. Same origin keeps the "docs" link working.
**Q31 — Are the usage pages password-protected?**
Recommendation: yes. User usage pages behind the shared password, admin usage pages behind the operator password. Consistent with the pages they extend.
**Q32 — Is the usage-docs workstream a separate effort?**
Recommendation: yes, after the core homepage is live. For now the "docs" link points to the existing reference doc (Q22).
### H. Deployment and operations
**Q33 — How is the homepage deployed?**
Recommendation: extend `deploy.sh` (Dankclaw path): copy `shared/homepage/` to `/srv/homepage/`, install the timer + service, render the Caddyfile (both hashes), reload Caddy.
**Q34 — Who creates `/srv/homepage/`?**
Recommendation: `deploy.sh` creates it and copies the assets. The checker writes `status.json` there at runtime.
**Q35 — Is the timer enabled at boot?**
Recommendation: yes. A systemd timer + service, enabled, so it survives reboots and runs every 3 minutes.
### I. Testing
**Q36 — Tests for the checker?**
Recommendation: yes. A bats test runs the checker against a fake up port, a fake down port, and a WIP service, then validates the `status.json` schema. TDD, per repo rules.
**Q37 — Tests for the pages and config?**
Recommendation: yes. Validate the `services.json` schema (required fields, valid categories), run `caddy validate` on the Caddyfile, and check the pages reference `status.json`.
**Q38 — A security test for the two passwords?**
Recommendation: yes. Assert the Caddyfile carries two distinct basicauth hashes (root vs `/admin/`).
### J. Edge cases and robustness
**Q39 — A backend moves hosts (e.g. the *arr stack to a new box)?**
Recommendation: no code change. The `probe` field is a full `host:port`. A move is a config edit.
**Q40 — A slow LAN hop to a Dankserver backend?**
Recommendation: the 3 s timeout handles it. A slow-but-alive backend connects (Up); a dead one times out (Down).
**Q41 — Client-side auto-refresh?**
Recommendation: the page polls `status.json` every **60 s** (the file updates every 3 min; 60 s is responsive without hammering).
**Q42 — Mobile responsiveness?**
Recommendation: yes. Stack the columns and shrink the font on narrow screens.
**Q43 — A "last checked" timestamp on the page?**
Recommendation: yes. The footer shows `last checked HH:MM:SS` from `generated_at`.
## How to continue
Answer the open questions (Q6–Q43) in the morning report. Group the answers by category. Once settled, the build order is:
```mermaid
flowchart LR
A[settle Q6-Q43] --> B[write services.json + checker]
B --> C[write the pages + theme]
C --> D[extend deploy.sh + Caddyfile]
D --> E[tests green]
E --> F[deploy to Dankclaw]
F --> G[verify in browser]
```