§7 review checkpoint (todo §7); ran the architecture + product reviewers on the whole project and addressed findings, no Critical from either. Made permissions honest + decoupled the host from the plugin: new pure seedRoles + bootstrap discoverPlugins() seeds the demo admin admin(/ADMIN_ROLES) ∪ every discovered plugin's declared tokens, dropped the hardcoded scheduling:* from compose ADMIN_ROLES (clean-clone unchanged); docs now state a route/nav permission is a coarse role granted as Keto Role:<token>#members. Added src/plugin-api.ts — the stable author barrel the reference plugin now imports from instead of deep src/* (the contract boundary in code). Made per-plugin CSS usable: shell styles slot + plugins/scheduling/public/scheduling.css linked from the views. Reference now demonstrates hooks.onBoot validating SCHEDULING_UPSTREAM fail-loud (assertHttpUrl). Build ctx.chrome at most once per request (memoized). Doc honesty: fixed the false visual.spec coverage comment, softened the "every plugin ships a Playwright test" claim (authed flow = §8), added an Upstream contract block to the plugin README. Added LICENSE (MIT). Stability-reviewer APPROVE, no Critical/High; addressed both Low nits. typecheck + 301 units green. Deferred: internal route-table (M1)→§9, safeUrl()→§9, data-table empty-state + success-flash→§8/polish, apiVersion-literal enforcement (prose), permission→requireRole rename (future minor).
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
<%#
|
||||
App shell: sidebar (brand + nav slot + footer) · topbar · content slot.
|
||||
Slots are pre-rendered HTML locals — `nav` (sidebar tree, see nav-tree partial),
|
||||
`actions` (topbar buttons), `body` (page content). Text locals: `title`, `brand`
|
||||
`actions` (topbar buttons), `body` (page content); `styles` is an optional array of
|
||||
extra stylesheet hrefs (e.g. a plugin's own /public/<id>/x.css). Text locals: `title`, `brand`
|
||||
({ name, logo?, sub? } — logo image else the default mark), `theme` (default for the
|
||||
theme-switch), `user`, `breadcrumbs`, `csrfToken` (the Sign-out POST form's hidden field).
|
||||
Branding comes from config/menu.ts; `user`/`csrfToken` from §4 auth.
|
||||
@@ -13,6 +14,7 @@
|
||||
const nav = locals.nav || "";
|
||||
const actions = locals.actions || "";
|
||||
const body = locals.body || "";
|
||||
const styles = locals.styles || []; // extra per-page stylesheet hrefs (e.g. a plugin's own CSS)
|
||||
%><!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
@@ -20,7 +22,8 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title><%= title %></title>
|
||||
<link rel="stylesheet" href="/public/css/styles.css" />
|
||||
<link rel="icon" href="/public/favicon.svg" />
|
||||
<% styles.forEach((href) => { %><link rel="stylesheet" href="<%= href %>" />
|
||||
<% }) %><link rel="icon" href="/public/favicon.svg" />
|
||||
</head>
|
||||
<body>
|
||||
<a class="skip-link" href="#main-content">Skip to content</a>
|
||||
|
||||
Reference in New Issue
Block a user