feat(homepage): the not-open-yet apps get their own section, below AI

Calibre-Web, RomM and Seerr sat inside "Media Library Apps" carrying a WIP
badge and a "not open to family users yet" sentence each, so the household
grid mixed doors they can use with doors they cannot. They now render under
their own "Work in progress" heading, placed after AI on the user page, and
the copy drops the restated "Work in progress:" for the ask-Frank line the
section heading no longer needs to repeat.

- app.js: SECTION_ORDER.user gains "Work in progress" last.
- services.json: the three cards' section, plus one-line copy trim.
- homepage_config.bats / homepage_pages.bats: the section contract now
  includes the new heading and pins the new order (the old test pinned AI
  last, which this change deliberately overturns).
- Homepage.md: the classification list and the SECTION_ORDER/wip contract
  lines catch up (the user order in the page was already stale, and "down"
  was an undocumented wip value).

The admin page is untouched: its WIP cards (Gluetun, mariadb, valkey,
Postgres) are plumbing inside Infrastructure, not applications.
This commit is contained in:
Frank committed 2026-11-04 13:09:16 -08:00
1 parent cae283047f
commit bad78079d7
5 files changed
+24 -22

No files matched your search

@@ -28,11 +28,12 @@ descriptions and a `docs` link to `/docs#models`.
**Sections + WIP split (2026-09-21):** both pages now group their panels **Sections + WIP split (2026-09-21):** both pages now group their panels
under section headings rendered by shared `renderSection()`/`renderPanel()` under section headings rendered by shared `renderSection()`/`renderPanel()`
components in `app.js`. The user page orders **AI, Web Apps, Media Library components in `app.js`. The user page orders **Web Apps, Media Library
Apps**; the admin page orders **Media Library Apps, Observability, AI, Apps, AI, Work in progress** (the three not-open-yet apps moved under their
Infrastructure**. The WIP badge split into **WIP: OPEN** (work in progress) own heading, below AI, on 2026-11-04); the admin page orders **Media Library
and **WIP: CLOSED** (work finished by decision — e.g. a card that is Apps, Observability, AI, Infrastructure**. The WIP badge split into **WIP:
deliberately unprobeable) via the `wip` value (`"open"` / `"closed"`). OPEN** (work in progress) and **WIP: CLOSED** (work finished by decision — e.g.
a card that is deliberately unprobeable) via the `wip` value.
Tautulli (Plex statistics, `192.168.0.235:8181`) joined the admin page's Tautulli (Plex statistics, `192.168.0.235:8181`) joined the admin page's
Media Library Apps section. Media Library Apps section.
@@ -314,9 +315,10 @@ flowchart TD
## Service classification ## Service classification
**User services** (root page), in section order: **User services** (root page), in section order:
- **AI** — OpenWebUI, and the three LLM fleet cards (frank-dragoon, frank-archon, frank-zealot — status + docs link, no Open link).
- **Web Apps** — SearXNG, Gitea, Copyparty, Marreta. - **Web Apps** — SearXNG, Gitea, Copyparty, Marreta.
- **Media Library Apps** — Calibre-Web, RomM, Plex, Jellyfin, Seerr, Audiobookshelf (moved up from the admin page 2026-11-03, once Authentik SSO made it a household app). - **Media Library Apps** — Plex, Jellyfin, Audiobookshelf (moved up from the admin page 2026-11-03, once Authentik SSO made it a household app).
- **AI** — OpenWebUI, and the three LLM fleet cards (frank-dragoon, frank-archon, frank-zealot — status + docs link, no Open link); their model table renders under this heading.
- **Work in progress** — Calibre-Web, RomM, Seerr. WIP badge, no Open link, no household account yet: the ask-Frank door. See the docs page's *Three doors that are not open to the household yet*.
**Admin services** (`/admin/`), in section order: **Admin services** (`/admin/`), in section order:
- **Media Library Apps** — the *arr stack (Prowlarr, Sonarr, Radarr, Lidarr, Readarr), qBittorrent, and Tautulli — live on FrankBook-Pro and Dankserver, operator-only: no vhosts (Tautulli included), direct IP:port access only. See [[FrankBook-Pro]]. - **Media Library Apps** — the *arr stack (Prowlarr, Sonarr, Radarr, Lidarr, Readarr), qBittorrent, and Tautulli — live on FrankBook-Pro and Dankserver, operator-only: no vhosts (Tautulli included), direct IP:port access only. See [[FrankBook-Pro]].
@@ -432,15 +434,15 @@ agent knowledge base (`~/.pi/agent/docs/caddy/caddyfile.md`).
- `category` — `user` or `admin`. Selects the page. - `category` — `user` or `admin`. Selects the page.
- `section` — the heading the panel renders under. Must be one of the page's - `section` — the heading the panel renders under. Must be one of the page's
`SECTION_ORDER` entries (user: AI, Web Apps, Media Library Apps; admin: `SECTION_ORDER` entries (user: Web Apps, Media Library Apps, AI, Work in
Media Library Apps, Observability, AI, Infrastructure), or the panel is progress; admin: Media Library Apps, Observability, AI, Infrastructure), or
silently dropped from the page. the panel is silently dropped from the page.
- `url` — the "Open" link (the Caddy site). - `url` — the "Open" link (the Caddy site).
- `docs` — the per-service docs page (`/docs/<svc>/`). - `docs` — the per-service docs page (`/docs/<svc>/`).
- `probe` — the backend `host:port` the checker probes. - `probe` — the backend `host:port` the checker probes.
- `method` — `tcp` or `http`. The probe type for this service (Q10). - `method` — `tcp` or `http`. The probe type for this service (Q10).
- `wip` — `false`, or `"open"` / `"closed"`. When set, the badge shows - `wip` — `false`, or `"open"` / `"closed"` / `"down"`. When set, the badge shows
**WIP: OPEN** or **WIP: CLOSED** and the checker skips the probe. **WIP: OPEN** / **WIP: CLOSED** / **WIP: DOWN** and the checker skips the probe.
**A card must be probeable from the monitor's host, or it must be `wip`.** The **A card must be probeable from the monitor's host, or it must be `wip`.** The
checker runs on Dankclaw, so its reach is: that host's own loopback, its own checker runs on Dankclaw, so its reach is: that host's own loopback, its own
+1 -1
View File
@@ -10,7 +10,7 @@ const CATEGORY = window.location.pathname.indexOf('/admin') !== -1 ? 'admin' : '
// same renderSection()/renderPanel() below. SECTION_ORDER fixes each page's // same renderSection()/renderPanel() below. SECTION_ORDER fixes each page's
// section order; a section with no services renders nothing. // section order; a section with no services renders nothing.
const SECTION_ORDER = { const SECTION_ORDER = {
user: ['Web Apps', 'Media Library Apps', 'AI'], user: ['Web Apps', 'Media Library Apps', 'AI', 'Work in progress'],
admin: ['Media Library Apps', 'Observability', 'AI', 'Infrastructure'], admin: ['Media Library Apps', 'Observability', 'AI', 'Infrastructure'],
}; };
+6 -6
View File
@@ -57,8 +57,8 @@
{ {
"name": "Calibre-Web", "name": "Calibre-Web",
"category": "user", "category": "user",
"section": "Media Library Apps", "section": "Work in progress",
"description": "E-book library. Work in progress: not open to family users yet.", "description": "E-book library. Not open to family users yet — ask Frank.",
"url": "", "url": "",
"docs": "", "docs": "",
"probe": "192.168.0.235:8083", "probe": "192.168.0.235:8083",
@@ -70,8 +70,8 @@
{ {
"name": "RomM", "name": "RomM",
"category": "user", "category": "user",
"section": "Media Library Apps", "section": "Work in progress",
"description": "ROM and emulator library. Work in progress: not open to family users yet.", "description": "ROM and emulator library. Not open to family users yet — ask Frank.",
"url": "", "url": "",
"docs": "", "docs": "",
"probe": "192.168.0.235:8085", "probe": "192.168.0.235:8085",
@@ -122,8 +122,8 @@
{ {
"name": "Seerr", "name": "Seerr",
"category": "user", "category": "user",
"section": "Media Library Apps", "section": "Work in progress",
"description": "Download requests. Work in progress: not open to family users yet.", "description": "Download requests. Not open to family users yet — ask Frank.",
"url": "", "url": "",
"docs": "", "docs": "",
"probe": "127.0.0.1:5055", "probe": "127.0.0.1:5055",
+1 -1
View File
@@ -37,7 +37,7 @@ PY
import json, sys import json, sys
data = json.load(open(sys.argv[1])) data = json.load(open(sys.argv[1]))
allowed = { allowed = {
"user": {"AI", "Web Apps", "Media Library Apps"}, "user": {"AI", "Web Apps", "Media Library Apps", "Work in progress"},
"admin": {"Media Library Apps", "Observability", "AI", "Infrastructure"}, "admin": {"Media Library Apps", "Observability", "AI", "Infrastructure"},
} }
for svc in data: for svc in data:
+2 -2
View File
@@ -41,8 +41,8 @@ setup() {
grep -q "repeat(auto-fill" "$BASE/style.css" grep -q "repeat(auto-fill" "$BASE/style.css"
} }
@test "the user page keeps the AI section at the bottom" { @test "the user page puts the Work in progress section last, below AI" {
grep -q "user: \['Web Apps', 'Media Library Apps', 'AI'\]" "$BASE/app.js" grep -q "user: \['Web Apps', 'Media Library Apps', 'AI', 'Work in progress'\]" "$BASE/app.js"
} }
@test "WIP badges distinguish open from closed work" { @test "WIP badges distinguish open from closed work" {