Remove completed todo.md + html-css-foundation mockups; strip dead §N phase refs from comments/docs (simplify visual E2E to drop the mockup-comparison oracle)

This commit is contained in:
2026-06-23 22:49:28 +02:00
parent e22d24aa8a
commit a9f25a7692
143 changed files with 394 additions and 1538 deletions
+2 -2
View File
@@ -1,4 +1,4 @@
// Reference plugin (todo §7): a worked example of the contract — a list page that fetches upstream
// Reference plugin: a worked example of the contract — a list page that fetches upstream
// data, a CSRF-guarded form that forwards a write upstream, and permission-gated nav. Copy this
// folder, rename it, point it at your own backend. Full contract: docs/plugin-contract.md.
@@ -19,7 +19,7 @@ export default definePlugin({
// Merged into the global menu + filtered per user. "Overview" is `public`, so the "Scheduling"
// header shows for everyone (even signed out); "Shifts" needs `scheduling:read`, so the gated data
// stays hidden until a reader signs in (§10 — a plugin may make a page + its menu option public).
// stays hidden until a reader signs in (a plugin may make a page + its menu option public).
nav: [{
children: [
{ href: SCHEDULING_PATH, id: "scheduling:overview", label: "Overview", public: true },
+1 -1
View File
@@ -112,7 +112,7 @@ test("listShifts degrades to a recoverable error page when the upstream is down
assert.deepEqual((r.data["table"] as { rows: unknown[] }).rows, []);
});
// ---- public overview handler (§10: a page anyone can reach, gated data stays behind the role) ----
// ---- public overview handler (a page anyone can reach, gated data stays behind the role) ----
test("overview renders a public page for anyone; it links straight to Shifts only for a reader", async () => {
const anon = asView(await overview()(fakeCtx())); // user null, no roles
+5 -5
View File
@@ -1,4 +1,4 @@
// Reference plugin (todo §7) — Scheduling/Shifts handlers + the upstream client. Shows the blessed
// Reference plugin — Scheduling/Shifts handlers + the upstream client. Shows the blessed
// shape: a thin handler parses ctx, calls an upstream REST service, and returns a RouteResult the
// host renders. The plugin holds no state of its own (README "Stateless") — data lives upstream.
//
@@ -8,7 +8,7 @@
// One import from the host's plugin-api barrel — the stable author surface (see docs/plugin-contract.md).
import { can, CSRF_FIELD, GuardError, type PageChrome, parseListQuery, readFormBody, type RouteHandler, tracedFetch } from "../../src/plugin-api.ts";
export const SCHEDULING_PATH = "/scheduling"; // the plugin's public overview page (§10)
export const SCHEDULING_PATH = "/scheduling"; // the plugin's public overview page
export const SHIFTS_PATH = "/scheduling/shifts";
export const READ = "scheduling:read"; // permission token gating the list + nav
export const WRITE = "scheduling:write"; // permission token gating create
@@ -56,7 +56,7 @@ export function assertHttpUrl(value: string, name: string): void {
}
// REST client over the upstream service (a stand-in for the customer's real backend). `fetch`
// defaults to the host's tracedFetch (§9), so each upstream call joins the request's trace (a client
// defaults to the host's tracedFetch, so each upstream call joins the request's trace (a client
// span + a propagated traceparent); it's injectable so handlers unit-test against a mock, no network.
export function createUpstream(baseUrl: string, fetchImpl: typeof fetch = tracedFetch): ShiftsUpstream {
const base = baseUrl.replace(/\/+$/, "");
@@ -172,7 +172,7 @@ export function listShifts(upstream: ShiftsUpstream): RouteHandler {
try {
shifts = await upstream.list();
} catch (err) {
ctx.log.warn("scheduling upstream unreachable", { error: String(err) }); // plugin logging via ctx.log (§9)
ctx.log.warn("scheduling upstream unreachable", { error: String(err) }); // plugin logging via ctx.log
error = "Couldn't reach the scheduling service — try again shortly.";
}
const needle = q.toLowerCase();
@@ -185,7 +185,7 @@ export function newShiftForm(): RouteHandler {
return (ctx) => ({ data: buildFormModel({ chrome: ctx.chrome }), view: "shift-new" });
}
// Public overview (§10): a page anyone may reach — its route + nav node are marked `public`, so the
// Public overview: a page anyone may reach — its route + nav node are marked `public`, so the
// gate lets an anonymous visitor through and the menu option shows for everyone. The real data
// (the shifts list) stays behind `scheduling:read`; a reader gets a link straight to it, anyone
// else a prompt to sign in. ctx.user may be null here, so read the role via can() (zero I/O).
+1 -1
View File
@@ -1,5 +1,5 @@
<%#
Scheduling · public overview (reference plugin, §10). A page ANYONE may reach — the route and its
Scheduling · public overview (reference plugin). A page ANYONE may reach — the route and its
nav node are marked `public`, so an anonymous visitor is let through and the menu option shows for
everyone. The actual shifts data stays behind `scheduling:read`: a reader gets a link straight to
it, anyone else a prompt to sign in. Rendered in the native shell via ctx.chrome.