Context. surface studio · domain aja · route /studio/aja/content-moderation · auth signed-in + studio entitlement · source apps/oshun/web/src/app/studio/aja/content-moderation/page.tsx
Last walked. 2026-05-29 automated runtime walk (Playwright headless) — render, /v1 data (2xx), console/page-errors, expected content, screenshot verified; live screen-reader, touch, offline, and telemetry-delivery checks pending a manual AT pass. Evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md; body re-derived 2026-06-03 from current source (lane-console architecture)
Purpose#
Admin lane console for the moderation ban lifecycle, wired to the real
@aja/content-moderation BanManager via /v1/admin/aja/content-moderation:
issue user bans (with repeat-offense escalation tracked through
previousViolations), check scope-aware ban status, and revoke. The library's
ML upload detectors are deliberately not surfaced here.
Entry points#
- Direct URL —
/studio/aja/content-moderation(signed-in + studio entitlement) - Breadcrumb — Studio / Aja / Content Moderation
- Sibling quick-actions from this page — Content Security, Consent Management, Privacy Protection, Data Retention, Back to Studio
Layout regions#
page.tsx mounts ShellLayout with active="studio" and renders four panels.
- Breadcrumb panel (
data-aja-content-moderation-breadcrumbs):nav aria-label="Aja Content Moderation breadcrumbs"— Studio (link) / Aja / Content Moderation (aria-current="page") - Workspace panel (
data-aja-content-moderation-workspace):<h1>"Aja Content Moderation Workspace" (viaWorkspaceHeading)<p data-aja-content-moderation-summary>— "Issue, check, and revoke user bans with repeat-offense escalation and scope-aware enforcement — the moderation ban-lifecycle control plane."- The ban form + check form lanes (rendered once the catalog loads)
- Route Map panel (
data-aja-content-moderation-route-map):<h2>"Route Map" + one<article>perSTUDIO_AJA_CONTENT_MODERATION_ROUTE_MAPentry (6 entries) - Quick actions panel:
.quickAction<Link>s — see Interactions
States#
- Loading —
data-aja-cm-loading"Loading moderation catalog…" - Unauthorized — on 401/403,
data-aja-cm-unauthorized("Access restricted." + reason, default "Aja workspace scope required to view content moderation.") - Error — non-OK / malformed / unreachable →
data-aja-cm-error - Ready (forms) — catalog present: ban form + check form
- Ban result —
data-aja-cm-ban-resultwithdata-aja-cm-ban-id,data-aja-cm-ban-violations(prior violations), active/type - Check result —
data-aja-cm-check-resultwithdata-aja-cm-check-bannedanddata-aja-cm-check-history - Action error —
data-aja-cm-action-error(e.g. "User, reason, issued-by, and at least one category are required." / "A user ID is required to check status.")
Interactions#
Ban form (data-aja-cm-ban-form)#
- User ID —
input data-aja-cm-field-user - Ban type —
select data-aja-cm-field-type(options fromcatalog.banTypes) - Categories (comma-separated) —
input data-aja-cm-field-categories - Reason —
input data-aja-cm-field-reason - Issued by —
input data-aja-cm-field-issuedby - Issue ban —
button data-aja-cm-ban-submit;POST /v1/admin/aja/content-moderation/banwith{ userId, type, reason, categories, issuedBy }
Check form (data-aja-cm-check-form)#
- Check user ID —
input data-aja-cm-field-check - Check status —
button data-aja-cm-check-submit;POST /v1/admin/aja/content-moderation/checkwith{ userId }
Route Map panel (data-aja-content-moderation-route-map)#
Non-interactive <article> blocks from STUDIO_AJA_CONTENT_MODERATION_ROUTE_MAP
(6 entries): /studio/aja/content-moderation plus …/policies/[policyId],
…/reviews/[reviewId], …/cases/[caseId], …/parity/[parityId],
…/governance/[governanceId].
Quick actions panel#
- Open Aja Content Security workspace →
/studio/aja/content-security - Open Aja Consent Management workspace →
/studio/aja/consent-management - Open Aja Privacy Protection workspace →
/studio/aja/privacy-protection - Open Aja Data Retention workspace →
/studio/aja/data-retention - Back to Studio workspace index →
/studio
Data & contracts#
- Reads:
GET /v1/admin/aja/content-moderation(catalog:banTypes,categories) on mount viabuildBffAuthHeaders(),cache: 'no-store' - Writes:
POST …/ban→{ ban };POST …/check→{ status } - Realtime: none
- Caching: client fetch on mount (no-store); SSR shell only
- Auth: BFF endpoints admin-scoped + fail-closed (401/403 → unauthorized render); the route is signed-in + studio (proxy gate)
Cross-references#
- Parent:
../../studio-overview.md - Component sources:
apps/oshun/web/src/components/studio/StudioAjaContentModerationWorkspace.tsxapps/oshun/web/src/components/studio/StudioAjaContentModerationRouteMap.ts
- Siblings from quick-actions:
/studio/aja/content-security,/studio/aja/consent-management,/studio/aja/privacy-protection,/studio/aja/data-retention
Open questions / known gaps#
- Route-map sub-routes (
policies/reviews/cases/parity/governance) are descriptive only; confirm implementation status - Document the exact studio entitlement / proxy gate governing
/studio/aja/*