diff --git a/AGENTS.md b/AGENTS.md index 28cace0..99ca732 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -125,8 +125,8 @@ not for the public pages. See `docs/design-principles.md` for the design. and their nav links point at their first child page. Dynamic regions have stable ids (`#page-banner`, `#nav`, `#sidebar`, `#main`) for fetch-navigation swaps (`#sidebar` may be absent on either side of a swap). - - `seed.py` — demo content written on startup for paths missing from the - database (never overwrites existing pages). + - `seed.py` — demo content written only when the database is first + created, via a `@kanta.bootstrap` handler in `app.py`. - `frontend/src/` — the Vue editor and public-page entries. - `main.js` — Vue editor app entry, mounts the tabbed EditorShell. - `pagerite.js` — public page entry; runs fetch-navigation, scroll-reveal, @@ -141,9 +141,11 @@ not for the public pages. See `docs/design-principles.md` for the design. learn the current session's admin status. The same reverse proxy that gates `/_api` returns 401 for anonymous users, 403 for users without the admin permission, and 200 for admins. When Paskia is detected, a - 🔑 login button (anonymous) or 🔐 profile button (logged in) is shown in - the banner corner; both open Paskia's iframe dialog via `showAuthIframe` - instead of navigating away. Admins also get the 🖊️ page/banner edit pens + 🔑 login link (anonymous) or 🔐 profile link (logged in) is shown in + the banner corner; both are plain `` links (Paskia + does not support being iframed, so we navigate normally), and a + `pageshow` handler re-probes auth when history navigation restores a + cached page. Admins also get the 🖊️ page/banner edit pens and a ⚙️ site-settings pen (asset URLs from the `pagerite:editor-src`/`-css` meta tags). If no Paskia SSO is detected (dev/no proxy), editing is left open. Pages themselves render diff --git a/pagerite/app.py b/pagerite/app.py index 75da8c2..b5bcc33 100644 --- a/pagerite/app.py +++ b/pagerite/app.py @@ -121,24 +121,26 @@ def _migrate_legacy() -> None: data.version += 1 +@kanta.bootstrap +def _seed(data: Data) -> None: + """Write the demo pages on database creation (never on existing dbs).""" + for path in seed.PAGES: + title, markdown, files, banner, order, design = seed.PAGES[path] + for orig, body in files.items(): + markdown, banner = _store_seed_file(markdown, banner, orig, body) + node = _ensure(data.menu, path) + node.title = title + node.content = markdown + node.banner = banner + node.banner_design = design + node.order = order + + @asynccontextmanager async def lifespan(_app: FastAPI) -> AsyncIterator[None]: - """Open the database, migrate/seed content, load assets.""" + """Open the database, migrate legacy content, load assets.""" await kanta.open() _migrate_legacy() - missing = [p for p in seed.PAGES if resolve(data.menu, p) is None] - if missing: - with kanta.transaction("seed missing pages"): - for path in missing: - title, markdown, files, banner, order, design = seed.PAGES[path] - for orig, body in files.items(): - markdown, banner = _store_seed_file(markdown, banner, orig, body) - node = _ensure(data.menu, path) - node.title = title - node.content = markdown - node.banner = banner - node.banner_design = design - node.order = order await frontend.load() yield await kanta.close()