Tighten §5 admin comments + README (todo §5 cleanup); compress the three near-identical admin module headers (drop restatement the README/code already carry), shorten the README Layout views/ run-on + add the missing delete-confirm view. Also bank a pre-existing AGENTS.md tweak: skip the stability-reviewer for purely doc/comment changes. Docs/comments-only — typecheck + 244 units green.
This commit is contained in:
@@ -1,11 +1,10 @@
|
||||
// Built-in Groups admin screen (todo §5): list / create / delete Keto groups and manage their
|
||||
// membership. A group is a Keto subject set `Group:<name>#members`; a membership tuple's subject is
|
||||
// a user (`subject_id = user:<id>`) or a nested group (`subject_set = Group:<other>#members`). Writes
|
||||
// go only to Keto (README "stateless"); there is no group store. Keto has no "create object" — a
|
||||
// group exists exactly while it has ≥1 member, so creating one writes its first-member tuple and
|
||||
// deleting one removes every member tuple. The pure builders turn tuples + the request URL into the
|
||||
// building-block view models; `handleAdminGroups` is the imperative shell app.ts dispatches to — it
|
||||
// gates (admin only), CSRF-guards every mutation, and maps each action to a RouteResult.
|
||||
// Built-in Groups admin screen (todo §5): list / create / delete Keto groups and manage membership.
|
||||
// A group is a Keto subject set `Group:<name>#members`; a member is a user or a nested group (see
|
||||
// parseSubject). Writes go only to Keto (README "stateless"). Keto has no "create object" — a group
|
||||
// exists exactly while it has ≥1 member, so create writes its first-member tuple and delete removes
|
||||
// every member tuple. Pure builders turn tuples + the request URL into view models; `handleAdminGroups`
|
||||
// is the imperative shell app.ts dispatches to — gated admin-only, CSRF-guarded, mapping each action
|
||||
// to a RouteResult.
|
||||
|
||||
import { ADMIN_GROUPS_BASE, adminNav, buildConfirmModel, guardedForm, requireAdmin } from "./admin-nav.ts";
|
||||
import type { FieldConfig } from "./admin-users.ts";
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Built-in Roles & permissions admin screen (todo §5): list / create / delete Keto roles and assign
|
||||
// them to users and groups. A role is a Keto subject set `Role:<name>#members` (OPL: members are
|
||||
// users or groups, resolved transitively) — the source of truth for the JWT `roles` claim. It shares
|
||||
// the user|group membership model of the Groups screen, so the pure helpers (parseSubject, member
|
||||
// pickers, tuple paging) are reused from admin-groups. The one role-specific piece is the **effective
|
||||
// access** view: `keto.expand(Role:<name>#members)` returns the membership tree, which we flatten to
|
||||
// the distinct set of users who hold the role directly or transitively via a group. Login resolves
|
||||
// the same transitive membership into the JWT `roles` (login.ts readRoles), so this view matches what
|
||||
// a user's token actually grants. Writes go only to Keto; Kratos is read only to label members.
|
||||
// `handleAdminRoles` is the imperative shell app.ts dispatches to — gated admin-only, CSRF-guarded.
|
||||
// them to users and groups. A role is a Keto subject set `Role:<name>#members` (OPL: members are users
|
||||
// or groups, resolved transitively) — the source of truth for the JWT `roles` claim. It shares the
|
||||
// Groups screen's membership model, so the pure helpers (parseSubject, member pickers, tuple paging)
|
||||
// are reused from admin-groups. The role-specific piece is the **effective access** view:
|
||||
// `keto.expand(Role:<name>#members)` flattened to the distinct users who hold the role directly or via
|
||||
// a group — matching what login projects into the JWT (login.ts readRoles). Writes go only to Keto;
|
||||
// Kratos is read only to label members. `handleAdminRoles` is the imperative shell app.ts dispatches
|
||||
// to — gated admin-only, CSRF-guarded.
|
||||
|
||||
import { ADMIN_PERMISSION, ADMIN_ROLES_BASE, adminNav, buildConfirmModel, guardedForm, requireAdmin } from "./admin-nav.ts";
|
||||
import {
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
// Built-in Users admin screen (todo §5): list Kratos identities (filter/sort/paginate) and
|
||||
// create / edit / deactivate / delete / trigger-recovery them. Writes go only to Kratos via the
|
||||
// admin client (README "stateless"); the app holds no user store. The pure builders here turn
|
||||
// identities + the request URL into the building-block view models; `handleAdminUsers` is the
|
||||
// imperative shell app.ts dispatches to — it gates (admin only), CSRF-guards every mutation, and
|
||||
// maps each action to a RouteResult (render a page, or redirect after a write — PRG).
|
||||
// Built-in Users admin screen (todo §5): list Kratos identities (filter/sort/paginate) +
|
||||
// create/edit/deactivate/delete/trigger-recovery. Writes go only to Kratos via the admin client
|
||||
// (README "stateless"). Pure builders turn identities + the request URL into building-block view
|
||||
// models; `handleAdminUsers` is the imperative shell app.ts dispatches to — gated admin-only,
|
||||
// CSRF-guarded, each action mapped to a RouteResult (render, or redirect after a write — PRG).
|
||||
|
||||
import { ADMIN_USERS_BASE, adminNav, buildConfirmModel, guardedForm, requireAdmin } from "./admin-nav.ts";
|
||||
import type { RequestContext, User } from "./context.ts";
|
||||
|
||||
Reference in New Issue
Block a user