v0.315.0: one app page with four tabs; the guide the catalog can carry; no Raspberry Pi badge
gates / gates (push) Failing after 47s

An app was six pages — details, install/settings, logs, export, the per-app backup panel and a
details card for moving data — and every "Vissza" on them went to the app LIST, so there was no way
back to the app you were looking at. It is now ONE page with four tab URLs under /apps/{slug}/,
one shared header and one set of banners.

  settings  Mukodes (Start/Restart/Stop, Stop confirms) + the cards that want something from the
            household + the install-time and optional settings. The default for an installed app,
            RENDERED at the bare URL and never redirected to.
  data      the data folders, move to another drive, the nightly copy, the 2nd-copy setting, export
  guide     tagline, screenshots, use cases, first steps, the catalog's guide, the FAQ, the docs
            link — and the WHOLE page for an app that is not installed
  logs      the log, and the only tab whose poller runs

The tabs are links, not panels: a link in an alert has to land ON a tab, and the log poller must not
run on the other three. Start/Restart/Stop left the page header, where they read as menu buttons.

The old /stacks/{name}/{deploy,logs,export,backup} GETs answer 302 — never 301, which a browser
caches beyond anyone's reach — to the tab that now holds them, query string carried through, with
name->slug resolved through the stack list rather than assumed equal. Every POST on those paths is
untouched: the backup form, the app-email toggle and the reveal endpoints keep their URLs.

A value asked AFTER the app starts is now generic (D2). The catalog marks a field `after_start: true`
and supplies its label; the ACTION is Go, in a registry keyed by slug + env var. The catalog can
never declare what runs — a declared field with no registered action renders nothing, POSTs 404 and
logs one WARN with the env var KEY, never the value. A red-proof found the second half of that guard
unpinned: deleting the "the catalog must have DECLARED this field" check left the suite green, and a
POST for an undeclared field then reached Plex and opened the setup gate.
TestAfterStart_RegistryAloneIsNotAnInvitation pins it.

New catalog block app_info.guide (sections + faq + checked_version), parsed, localised field by
field and rendered with the household's own address filled in. It renders only when checked_version
names the image tag its author clicked through. No template carries one yet.

The Pi and "csak x86" badges are gone; PiCompatible and the catalog key stay this release, or a box
on 0.314.0 would read "csak x86" on every app (R-1067).

template_id_gate.py now follows {{template}} includes, with a scope decoy proving the walk did not
become vacuous.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0117kRTSgs3rJWUFGxyoWN6Y
This commit is contained in:
2026-10-15 18:37:50 +02:00
parent 85f65c70d8
commit e66d4669d6
120 changed files with 16239 additions and 9866 deletions
+15 -3
View File
@@ -114,6 +114,18 @@
"app_import.tarolo": "Storage",
"app_import.titkos": "Encrypted",
"app_import.visszaallitas_inditasa": "Start restore",
"app_page.after_start_btn": "Save",
"app_page.after_start_title": "One more step",
"app_page.faq": "Frequently asked questions",
"app_page.guide_missing": "There is no guide for this app yet.",
"app_page.mukodes": "Running",
"app_page.not_installable": "This app cannot be installed right now.",
"app_page.stop_confirm": "Stop the app? While it is stopped, nobody in the house can use it.",
"app_page.tab_data": "Data and backup",
"app_page.tab_guide": "Guide",
"app_page.tab_logs": "Logs",
"app_page.tab_settings": "Settings",
"app_page.tabs_label": "App page tabs",
"app_info.known_login": "This app starts with a known, shared password: %s. Change it right after the install.",
"app_info.a_kezdeti_jelszo_beolvasasa_nem": "The first password could not be read.",
"app_info.a_regi_adatok_erintetlenek": "The old data is untouched.",
@@ -130,7 +142,6 @@
"app_info.az_elso_bejelentkezes_utan_azonnal_2": "Change it right after your first sign-in!",
"app_info.az_uzemelteto_allitotta_be": "set by the operator",
"app_info.beallitasok": "Settings",
"app_info.csak_x86": "x86 only",
"app_info.dokumentacio": "Documentation",
"app_info.ellenorzes": "Checking",
"app_info.elofeltetelek": "Before you start",
@@ -630,7 +641,6 @@
"common.levalasztva": "Disconnected",
"common.magyar_felulet": "Hungarian interface",
"common.megsem": "Cancel",
"common.pi_kompatibilis": "Runs on Pi",
"common.rendszer_gyoker": "System",
"common.torles": "Delete",
"common.ugyfel_azonosito": "Customer ID",
@@ -1195,6 +1205,7 @@
"disk.err.target_required": "a target storage is required for the move",
"disk.err.unknown_mode": "unknown mode (migrate or anyway)",
"disk.err.wipe_failed": "the erase failed: %s",
"err.after_start.failed": "Saving did not work. Try again.",
"err.backup.restore_drive_gone": "The drive “%s” cannot be reached, so the restore could not start. Connect the drive again, then start the restore again.",
"err.stacks.remove_keep_data_while_support": "While support is working on this app, its data cannot be deleted — you can remove the app and keep its data.",
"err.appexport.a_mentes_nem_tartalmaz_alkalmazasadatot_0": "the backup holds no app data (0 data folders, 0 volumes for an app that stores data)",
@@ -1835,6 +1846,8 @@
"note.unit_restore_none_returned": "%s: WARNING — the backup lists %d data volumes and %d database dumps, but none of them came back. Your data is unchanged. Ask for help before you try again.",
"note.unit_restore_settings_only": "%s: the settings are back — the app has restarted. WARNING: this backup held only the settings, no data. The app's data did NOT come back from this backup.",
"offbox.selection_changed": "The selection changed since the last run — the next remote backup includes it.",
"page.title.app_data": "%s — Data and backup",
"page.title.app_guide": "%s — Guide",
"page.title.app_settings": "%s — Settings",
"page.title.backups": "Backup",
"page.title.backups_apps": "Backup — Apps",
@@ -1855,7 +1868,6 @@
"page.title.storage_attach": "Attach an existing drive",
"page.title.storage_init": "Initialise a new drive",
"page.title.storage_network": "Network storage",
"page.title.tier2_config": "Second backup setup — %s",
"ping.label.backup": "Backup",
"ping.label.db_dump": "Database backup",
"ping.label.heartbeat": "Heartbeat",
+15 -3
View File
@@ -110,6 +110,18 @@
"app_import.tarolo": "Tároló",
"app_import.titkos": "Titkos",
"app_import.visszaallitas_inditasa": "Visszaállítás indítása",
"app_page.after_start_btn": "Mentés",
"app_page.after_start_title": "Még egy lépés",
"app_page.faq": "Gyakori kérdések",
"app_page.guide_missing": "Ehhez az alkalmazáshoz még nem készült útmutató.",
"app_page.mukodes": "Működés",
"app_page.not_installable": "Ez az alkalmazás most nem telepíthető.",
"app_page.stop_confirm": "Leállítod az alkalmazást? Amíg áll, a házban senki nem tudja használni.",
"app_page.tab_data": "Adatok és mentés",
"app_page.tab_guide": "Útmutató",
"app_page.tab_logs": "Napló",
"app_page.tab_settings": "Beállítások",
"app_page.tabs_label": "Alkalmazás lapjai",
"app_info.known_login": "Ez az alkalmazás egy ismert, közös jelszóval indul: %s. Telepítés után azonnal változtasd meg.",
"app_info.a_kezdeti_jelszo_beolvasasa_nem": "A kezdeti jelszó beolvasása nem sikerült.",
"app_info.a_regi_adatok_erintetlenek": "A régi adatok érintetlenek.",
@@ -126,7 +138,6 @@
"app_info.az_elso_bejelentkezes_utan_azonnal_2": "Az első bejelentkezés után azonnal változtasd meg!",
"app_info.az_uzemelteto_allitotta_be": "az üzemeltető állította be",
"app_info.beallitasok": "Beállítások",
"app_info.csak_x86": "Csak x86",
"app_info.dokumentacio": "Dokumentáció",
"app_info.ellenorzes": "Ellenőrzés",
"app_info.elofeltetelek": "Előfeltételek",
@@ -625,7 +636,6 @@
"common.levalasztva": "Leválasztva",
"common.magyar_felulet": "Magyar felület",
"common.megsem": "Mégsem",
"common.pi_kompatibilis": "Pi kompatibilis",
"common.rendszer_gyoker": "Rendszer",
"common.torles": "Törlés",
"common.ugyfel_azonosito": "Ügyfél azonosító",
@@ -1190,6 +1200,7 @@
"disk.err.target_required": "céltároló kötelező az áthelyezéshez",
"disk.err.unknown_mode": "ismeretlen mód (migrate vagy anyway)",
"disk.err.wipe_failed": "törlés sikertelen: %s",
"err.after_start.failed": "A mentés nem sikerült. Próbáld meg újra.",
"err.backup.restore_drive_gone": "A(z) „%s” meghajtó nem érhető el, ezért a visszaállítás nem tudott elindulni. Csatlakoztasd újra a meghajtót, majd indítsd el újra a visszaállítást.",
"err.stacks.remove_keep_data_while_support": "Amíg az ügyfélszolgálat foglalkozik az alkalmazással, az adatai nem törölhetők — az alkalmazást az adatai megtartásával eltávolíthatod.",
"err.appexport.a_mentes_nem_tartalmaz_alkalmazasadatot_0": "a mentés nem tartalmaz alkalmazásadatot (0 adatkönyvtár, 0 kötet egy adattárolós alkalmazásnál)",
@@ -1823,6 +1834,8 @@
"note.unit_restore_none_returned": "A(z) %s: FIGYELEM — a mentés %d adatkötetet és %d adatbázis-mentést sorol fel, de egyik sem állt vissza. Az adataid változatlanok maradtak. Kérj segítséget, mielőtt újra próbálod.",
"note.unit_restore_settings_only": "A(z) %s: a beállítások visszaálltak — az alkalmazás újraindult. FIGYELEM: ez a mentés csak a beállításokat tartalmazta, adatot nem. Az alkalmazás adatai NEM álltak vissza ebből a mentésből.",
"offbox.selection_changed": "A kijelölés módosult az utolsó futás óta — a következő távoli mentés már tartalmazza.",
"page.title.app_data": "%s — Adatok és mentés",
"page.title.app_guide": "%s — Útmutató",
"page.title.app_settings": "%s — Beállítások",
"page.title.backups": "Biztonsági mentés",
"page.title.backups_apps": "Biztonsági mentés — Alkalmazások",
@@ -1843,7 +1856,6 @@
"page.title.storage_attach": "Meglévő meghajtó csatolása",
"page.title.storage_init": "Új meghajtó inicializálása",
"page.title.storage_network": "Hálózati tárhely",
"page.title.tier2_config": "2. mentés beállítása — %s",
"ping.label.backup": "Biztonsagi mentes",
"ping.label.db_dump": "Adatbazis mentes",
"ping.label.heartbeat": "Eletjel (Heartbeat)",