# REPORT — v0.315.0: one app page with four tabs (2026-10-15) ## 1. Baselines | Repo | `main` at start | Version | → | |---|---|---|---| | felhom-controller | `85f65c7` | v0.314.0 | **v0.315.0** | | felhom.eu | `06e7cf8c` (the task said `3263bb2`; it had moved — two other sessions are pushing) | docs only | — | | app-catalog-felhom.eu | `e67aad4` | read only | — | Architecture read before any claim: `02-controller-module-map.md` (`web/`, the R-571 alert-placement rule), `10-localisation.md` §7, `15-media-library.md` (the Plex claim path), and the controller's `CLAUDE.md`, `REUSE.md` and `.claude/rules/{ui-hungarian,gates,unprompted-work}.md`. **Where the work ran.** Edited on the Windows workstation; **built and tested on DooPlex** in an isolated scratch clone (`/mnt/5_hdd/felhom.eu/scratch/cc-apptabs`) so the shared DooPlex checkout — which two other sessions are using tonight — was never dirtied. The sync normalises line endings to LF and restores any file it did not mean to touch, because this checkout has `core.autocrlf=true` while six files (`.gitignore`, `Dockerfile`, `Makefile`, the three infra templates) are stored in git WITH CRLF; a blanket normalisation rewrote all six on the first attempt. ## 2. Files created / modified **Created (11)** `controller/internal/web/app_page.go` · `after_start.go` · `app_page_test.go` · `guide_render_test.go` · `controller/internal/stacks/guide_test.go` · `templates/app_shell.html` · `app_settings.html` · `app_data.html` · `app_guide.html` · `app_logs.html` · `app_fields.html` **Deleted (4 templates)** `templates/app_info.html` · `logs.html` · `app_export.html` · `tier2_config.html` — with the three page handlers that rendered them (`logsHandler`, `exportPageHandler`, `tier2ConfigPageHandler`). The POST handlers beside them (`tier2ConfigSaveHandler`, `appEmailToggleHandler`) stay, with their URLs. **Modified (main ones)** `web/server.go` (routes + the GET-only redirects) · `web/handlers.go` (`appDetailHandler` → `appCommonData`; `deployHandler` → `deployPageData` + a thin renderer) · `web/media_events.go` (`applyPlexClaim` extracted) · `web/tier2_config_handler.go` (redirect targets) · `templates/deploy.html` (install-only; 1197 → 544 lines) · `stacks.html`, `dashboard.html`, `backups_apps.html`, `app_import.html` (links) · `stacks/metadata.go`, `metadata_i18n.go`, `appinfo_address.go`, `manager.go` (the guide) · both locale files · `scripts/template_id_gate.py`, `scripts/test_gate_decoys.py`, `scripts/i18n_go_keys.json`. ## 3. Commits on `main` | Commit | What | |---|---| | `e66d466` | v0.315.0 — the slice: tabs, routes, the after-start registry, the guide, the Pi removal, the fixtures. One commit, because the template split, the routes and the fixtures cannot be green apart | | `fe0228c` | style the tab bar; reuse the hero classes that already have rules (**found in a browser**) | | `db52f5a` | close the log tab's `` from `app_logs.html` again | `TestAppPage_ScriptTagsAreBalanced` FAILS: "logs: 3 `