Motivation
A self-hostable KB needs an operations surface, not just an API. AskMyDocs ships a full React admin SPA at/app/admin/*, every page behind Spatie role-based
access control, every mutation audit-trailed, and every destructive command
gated by a single-use confirm token.
What’s in it
- Dashboard — KPIs, health checks, charts from real seeded metrics.
- Users / Roles / RBAC — the five roles (super-admin / admin / dpo / editor / viewer), permission matrix, role editor.
- KB explorer — browse the canonical tree, an inline source editor (CodeMirror), a graph viewer, PDF export, the Cloud Time Machine (browse / diff / restore any version).
- Auto-Wiki admin — Wiki Health (lint + safe auto-fix), Wiki Indices (hub + roll-ups + operation log + rebuild), Wiki Explorer (promote auto→human / discard), Auto-Wiki Settings — see Auto-Wiki.
- Doc Insights — content-gap analytics + obsolescence intelligence on every change and delete, with an audited Apply engine.
- Tabular Review & Workflows — spreadsheet-style document extraction + AI-suggested workflow templates.
- Log viewer — five tabs (application / chat / failed jobs / audit / …).
- Maintenance runner — a whitelisted Artisan runner (see below).
- AI Insights — a daily computed insights panel.
- Sister admins — PII Redactor, Flow, Eval Harness, AI Act, MCP, Evidence & Risk Review — each cross-mounted natively.
RBAC + audit (every page)
Every protected route is in the R32 authorization matrix test — a new screen or endpoint that forgets itsrole: / can: gate fails CI. The five roles plus
the guest are asserted against the exact allow-set for each group.
The maintenance runner (6 gates)
Destructive Artisan commands run throughCommandRunnerService, which enforces:
(1) whitelist lookup in config('admin.allowed_commands'), (2) args-schema
validation, (3) a DB-backed single-use confirm token consumed inside a
lockForUpdate() transaction (R21 atomic), (4) the Spatie permission gate,
(5) audit-before-execute, (6) a per-user rate limit. The confirm-token table
carries a composite UNIQUE so a single-use bypass is structurally impossible.
Tri-surface (R44)
Every admin capability is one thin layer over a shared core service — the same core is also reachable as an Artisan command (PHP) and, where applicable, an MCP tool. Code-only is never “done”: a capability lands on all three surfaces or the omission is a documented choice.Worked example — running a maintenance command
nonce returns 409 Conflict, not a re-execution.
Gotchas & operations
- A new protected route / screen / gate / role MUST be added to the R32 authorization-matrix test in the same PR.
- Destructive commands always require the single-use confirm token — never add a bypass.
- Every admin mutation audit-trails; bypassing the audit path is a defect even when the change works.
Multi-tenant isolation
How admin reads stay scoped to one tenant.
Architecture overview
Where the admin surface sits in the system.