Context. surface studio · domain aja · route /studio/aja/avatar-library · auth signed-in + studio entitlement · source apps/oshun/web/src/app/studio/aja/avatar-library/page.tsx
Last walked. 2026-07-02 avatar-lane console addendum — Playwright real-dev-infra coverage now proves signed-in render, breadcrumb and route-map contracts, capability card count, quick-action href order, ready form, 44 px submit target, malformed JSON client guard with no POST, real BFF duplicate-asset 400 detail, real dedup result rows/canonical selection/reclaimable bytes, fail-closed loading/unauthorized/error states, mobile no-overflow, and direct BFF 401/403/400 gates. Spec: apps/oshun/web/e2e/studio-aja-avatar-lane-consoles.spec.ts.' '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 whose operations lane is a content-addressable dedup analyzer
wired via /v1/admin/aja/avatar-library: it groups assets by content hash,
designates a canonical per group, marks the rest as duplicates, and reports
unique-content / duplicate counts, total bytes, and reclaimable bytes.
Entry points#
- Direct URL —
/studio/aja/avatar-library(signed-in + studio entitlement) - Breadcrumb — Studio / Aja / Avatar Library
- Sibling quick-actions from this page — Avatar Integration, Avatar Preview, Inverse Kinematics, Back to Studio
Layout regions#
page.tsx mounts ShellLayout with active="studio" and renders four panels.
- Breadcrumb panel (
data-aja-avatar-library-breadcrumbs):nav aria-label="Aja Avatar Library breadcrumbs"— Studio (link) / Aja / Avatar Library (aria-current="page") - Workspace panel (
data-aja-avatar-library-workspace):<h1>"Aja Avatar Library Workspace" (viaWorkspaceHeading)<p data-aja-avatar-library-summary>— "Dedicated Avatar Library route with typed operations, diagnostics, security controls, and canonical route map."- Capability Summary panel (
data-aja-avatar-library-capability-summary,<h2>"Capability Summary" +data-aja-avatar-library-capabilitycards — static descriptive copy) <section data-aja-avatar-library-operations-lane><h2>"Avatar Library Operations Lane" embedding theAssetDedupLane(section data-adp-lane,<h2 data-adp-heading>"Live Content-Addressable Dedup")
- Route Map panel (
data-aja-avatar-library-route-map):<h2>"Route Map" + one<article>perSTUDIO_AJA_AVATAR_LIBRARY_ROUTE_MAPentry (6 entries) - Quick actions panel:
.quickAction<Link>s — see Interactions
States#
- Loading —
data-adp-loading"Loading asset dedup analyzer…" - Unauthorized — on 401/403,
data-adp-unauthorized(admin-scope reason, default "Aja workspace scope required to analyze the library.") - Error — non-OK / unreachable →
data-adp-error - Ready (form) —
data-adp-formwith the JSON payload textarea - Result —
data-adp-result:data-adp-headline(unique/total ·data-adp-duplicates·data-adp-reclaimable) and adata-adp-assetstable (data-adp-canonical,data-adp-state) - Validation error —
data-adp-analyze-error"Payload must be valid JSON."
Interactions#
Capability Summary panel#
- Non-interactive
data-aja-avatar-library-capabilitycards (catalog-control-plane, diagnostics-and-observability, security-permission-audit-controls, api-parity-and-contract-assurance)
Asset dedup form (data-adp-form)#
- Assets JSON —
textarea data-adp-payload(defaultassetsarray with assetId/contentHash/sizeBytes) - Analyze library —
button data-adp-submit; submits parsed JSON toPOST /v1/admin/aja/avatar-library/analyzeand receives{ result: AdpResult }
Route Map panel (data-aja-avatar-library-route-map)#
Non-interactive <article> blocks from STUDIO_AJA_AVATAR_LIBRARY_ROUTE_MAP (6
entries): /studio/aja/avatar-library plus …/scenes/[sceneId],
…/exports/[exportId], …/revisions/[revisionId], …/parity/[parityId],
…/governance/[policyId].
Quick actions panel#
- Open Aja Avatar Integration workspace →
/studio/aja/avatar-integration - Open Aja Avatar Preview workspace →
/studio/aja/avatar-preview - Open Aja Inverse Kinematics workspace →
/studio/aja/inverse-kinematics - Back to Studio workspace index →
/studio
E2E coverage#
apps/oshun/web/e2e/studio-aja-avatar-lane-consoles.spec.tscovers signed-in shell render, breadcrumb visibility, capability cards, route map shape, exact quick-action hrefs, ready form, 44 px submit target, malformed JSON client guard with no POST, real BFF duplicate-asset 400 detail, real dedup result rows and reclaimable byte summary, loading/unauthorized/error fail-closed states, mobile no-overflow, and direct BFF auth/schema gates.
Data & contracts#
- Reads:
GET /v1/admin/aja/avatar-libraryon mount (response read but only used to gate the lane to ready) viabuildBffAuthHeaders(),cache: 'no-store' - Writes:
POST …/analyze→{ result: AdpResult } - 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/StudioAjaAvatarLibraryWorkspace.tsxapps/oshun/web/src/components/studio/StudioAjaAvatarLibraryRouteMap.ts
- Siblings from quick-actions:
/studio/aja/avatar-integration,/studio/aja/avatar-preview,/studio/aja/inverse-kinematics
Known downstream boundaries#
- The mount GET only gates readiness; the returned catalog body is not rendered by this leaf lane.
- Capability Summary cards are static descriptive copy; the live affordance is the content-addressable dedup analyzer.
- Route-map sub-routes are descriptive contracts; implementation status of those child pages is tracked separately from this leaf console.
- The signed-in/studio entitlement proxy gate is shared across
/studio/aja/*and is verified outside this leaf-lane spec.