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'sindex.htmlon 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 andhot_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] sourceinlichen.toml): a local path, asha256:-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.rsstops 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 (DASHBOARDkind,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/uiandlichen-ts/dashboard: #14. Its built bundles (app.js,ssr/dashboard-ssr.js, theui.csscopies) are generated and inmain. - How an operator selects a dashboard:
README-extended.md, #16. - Tests (
tests/dashboard*.rs,sign_in_render.rs, the frontend browser tests) are inmain.