lichen.page.review from the reviewed point 0b92cb61 to stack eb5a1653, as one PR per subsystem (review set)

product: 12 Dashboard: React pages served, Tera removed, custom dashboards #59

targeting oct/11-front-state from oct/12-dashboard
Closed opened by and assigned to notplants-bot.bsky.social
targeting oct/11-front-state from oct/12-dashboard

superseded by the full set from 09-23, #17–#37

description: Review set for lichen.page.review, 0b92cb61 (reviewed) → eb5a1653 (stack). PR 12 of 16. 22 files, +1391/−2768. One commit, 482d9b758c58, which sets these files to their content at eb5a1653. Targets #11 (oct/11-front-state). #13 stacks on this one. Tests and generated files are not in any PR; they are in main.

The multi-site dashboard is now a React app, and Tera is gone (DASHBOARD-REACT). This PR is the server side of that change; the app itself is in #14.

  • The pages /, /settings/ and /settings/{domain} answer the React app's index.html on the dashboard host and the desktop. Each page's data comes from a JSON view (GET /api/dashboard, /api/account, the site's settings view), so the page and the API show one thing. The app's files are embedded and served from a fixed list.
  • The per-site settings page moved to the dashboard (C2). The site's own Tera settings page (site-settings.html, 852 lines) and the server's Tera pages (dashboard, settings, login, share-password login) are deleted, with the Tera engine and hot_reload_templates.
  • Sign-in pages are React drawn on the server (unit 4), in a render child: a separate process (sandboxed where the sandbox is on), because a sign-in page renders what a visitor sends and its JavaScript must run where no secret is. One warm child serves renders one at a time; a stuck render kills it. The same child draws the sites list for a browser without JavaScript (U4b).
  • A host operator can replace the dashboard ([dashboard] source in lichen.toml): a local path, a sha256:-pinned archive, or a git source pinned by full commit id, fetched through the site frontend loader's guards at startup only. Requests see validated bytes, never a source or a reload. An invalid selection serves the built-in app with a notice. A site's settings cannot select it (the operator: one user must not change the dashboard for others).
  • The dashboard's settings view shows the remote and sync the front server records, not the site's own git config (SITE-FRONT-BOUNDARY units 6 and 7), and a share guest sees only its own admin acts (ADMIN-EDIT-HOST-SPLIT H1e).

info: Plans: DASHBOARD-REACT-2026-10-07.md (C2 amendment: the per-site settings page on the dashboard; the operator's "swap in their own dashboard … a user should not be able to change the dashboard for other users"), notes DASHBOARD-REACT-U3-DESIGN-2026-10-17.md (pages, files, custom dashboards) and -U4-DESIGN-2026-10-17.md (server-drawn sign-in, D1 the render child). Background: REPLACE-TERA-WITH-SSR-REACT-2026-10-07.md.

Files

Front server (crates/lichen-server/):

  • src/dashboard.rs (+410/−206) — the pages and their JSON views (sites, account, a site's settings), the edit-host links. Read first.
  • src/dashboard_app.rs — new: the embedded app and its fixed file list.
  • src/dashboard_source.rs — new: the host-selected dashboard, resolved at startup.
  • src/sign_in_render.rs — new: the render child and the sign-in pages.
  • src/templates.rs, src/utils.rs, static/lichen.toml.example — the Tera engine and its setting removed.
  • templates/dashboard.html, settings.html, login.html, site_password_login.html, confirm-modal.css — deleted.

Site (crates/lichen-site/):

  • page-templates/site-settings.html, base.html, dashboard-base.css, deploy-key-*.html — deleted; build.rs stops embedding the folder.
  • src/settings/page.rs, src/api/html.rs — the settings page's Tera context and render removed; the JSON values stay.
  • src/frontend/remote.rs, src/frontend/git.rs — the frontend loader now takes an explicit confined tree, so the server's dashboard store can use it (DASHBOARD kind, snapshot_from, read_copy_from).

Moved in: the Tera templates and their code from the site crate (page-templates/* and frontend/* were in the starting map's publishing bucket by path; settings/page.rs, api/html.rs, build.rs in site core). They are one change: the dashboard replacing the Tera pages.

Lives elsewhere

  • The dashboard's JSON API and its contract: #11. Sign-in itself (sessions, rate limit, handoff): #10.
  • The React dashboard, frontends/ui and lichen-ts/dashboard: #14. Its built bundles (app.js, ssr/dashboard-ssr.js, the ui.css copies) are generated and in main.
  • How an operator selects a dashboard: README-extended.md, #16.
  • Tests (tests/dashboard*.rs, sign_in_render.rs, the frontend browser tests) are in main.
Commits 0