Context. surface studio · domain collaboration · route /studio/commenting-annotation-system · auth signed-in + studio entitlement · source apps/oshun/web/src/app/studio/commenting-annotation-system/page.tsx
Last walked. 2026-06-30 comment-threads real-BFF addendum — Playwright now covers the admin-scoped route render, real comment-thread catalog GET, default comments analyze POST/result, parent-chain depth semantics, repeated-mention dedupe, orphan detection, thread-resolution summary, quick-action targets, catalog loading/error state, malformed JSON client block, live BFF 400 detail, non-admin fail-closed, and anonymous redirect-before-render. Evidence: WALKTHROUGH/results/v1-real-infra-run-2026-06-22.md "Studio commenting and annotation coverage"; spec: apps/oshun/web/e2e/studio-commenting-annotation-system.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; content re-verified 2026-06-03 against current source
Purpose#
Operate the commenting and annotation system as a live, admin-scoped BFF
console. The workspace (StudioCommentingAnnotationSystemWorkspace) wires a
single Comment Thread Lane to the real comment-thread analyzer via
/v1/admin/studio/comment-threads: it derives each comment's nesting depth from
the parent chain, extracts @mention tokens, detects orphaned comments (missing
parents), and reports thread resolution. This is a real domain computation, not
a simulation.
Entry points#
- Studio root (
/studio) — discoverable as a collaboration workspace - Quick-action links from sibling workspaces (file/media ingestion, review/approval, presence, real-time collaboration, activity/change feeds, notification center)
- Direct URL / bookmark — yes
Layout regions#
page.tsx mounts ShellLayout active="studio", renders
StudioCommentingAnnotationSystemWorkspace, then a single panel containing 6
sibling quickAction links. There is no Route Map panel on this page.
- Shell header — from
ShellLayout - Workspace
<h1>— "Studio Commenting & Annotation System" (WorkspaceHeading), followed by adata-commenting-annotation-summaryparagraph describing the analysis - Comment Thread Lane (
<h2>data-ct-lane-heading"Comment Thread Lane") — the catalog/loading/unauthorized/error states, the analyze form, and the result - Quick-actions panel —
panelwith 6quickActionlinks to sibling workspaces (no self-link, no Route Map)
States#
- Loading —
data-ct-loading"Loading comment-thread analyzer…" while the GET catalog request is in flight (outcome === null) - Unauthorized —
data-ct-unauthorized"Access restricted." on 401/403 (admin scope required); shows the BFF message or "Studio admin scope required to analyze threads." - Error —
data-ct-error"Could not load the comment-thread analyzer." on any non-OK catalog response or network failure - Ready (form) — catalog loaded;
data-ct-enumsshows mention syntax plus{mentionSyntax}and{metrics.length} metrics, and thedata-ct-formform renders - Result — after a successful POST,
data-ct-resultrenders the thread headline + per-comment table - Analyze validation error —
data-ct-analyze-errorfor invalid JSON, network unavailable, or a non-200 POST (shows the POSTdetail) - Anonymous user — redirected to
/welcome?redirect=%2Fstudio%2Fcommenting-annotation-systembefore the workspace root renders
Interactions#
Comment Thread Lane form#
- Comments (
textareadata-ct-payload, aria-labelcomments json) — JSON{ comments[{ commentId, parentId, author, body, resolved }] }; seeded with a default payload - Analyze threads (
buttondata-ct-submit,type="submit") —submitAnalyzeparses the JSON (rejecting invalid JSON withdata-ct-analyze-error) and POSTs to/v1/admin/studio/comment-threads/analyze - Client-side malformed JSON block — invalid JSON surfaces "Payload must be valid JSON." and does not send a POST
- Live BFF invalid payload branch — valid JSON with
comments: []reaches the BFF and surfaces detail "comments must be a non-empty array" - Parent-chain depth + mention semantics — an edited payload proves
depth
0 → 1 → 2, repeated@bob @bobdedupes to one mention, and a missing parent rendersdata-orphan="true"
Result#
- Headline (
data-ct-headline) — renders<data-ct-thread-count> threads,{resolvedThreadCount} resolved,<data-ct-orphan-count>, and<data-ct-mention-count> - Comments table (
data-ct-comments) — onedata-ct-comment-rowper comment withdata-comment-id,data-depth,data-orphan, plusdata-ct-depth/data-ct-mentionscells
Quick actions#
- Open File and Media Ingestion workspace
- Open Review and Approval Workflows workspace
- Back to Presence and Cursor Systems workspace
- Back to Real-Time Collaboration Substrate workspace
- Back to Activity and Change Feeds workspace
- Back to Notification Center workspace
Data & contracts#
- GET catalog:
/v1/admin/studio/comment-threads— fetched on mount withbuildBffAuthHeaders()andcache: 'no-store'; returns{ mentionSyntax, metrics[] } - POST verb:
/v1/admin/studio/comment-threads/analyzewith body{ comments[{ commentId, parentId, author, body, resolved }] }→{ result: { comments[], summary{ commentCount, threadCount, resolvedThreadCount, orphanCount, totalMentions } } }(200) or adetailerror - Realtime: none — request/response only
- Client fetch: direct
fetchwithcache: 'no-store'; no client-side caching - Auth/role check: admin-scoped, fail-closed at the BFF (
admin:*|admin:studio; 401/403); reached through the signed-in + studio route gate
Cross-references#
- Parent:
../studio-overview.md - Sibling:
studio-presence-cursor-systems.md,studio-real-time-collaboration-substrate.md,studio-review-approval-workflows.md - Component:
apps/oshun/web/src/components/studio/StudioCommentingAnnotationSystemWorkspace.tsx - BFF route:
apps/oshun/bff/src/routes/admin-studio-comment-threads.ts - BFF store:
apps/oshun/bff/src/studio/comment-thread-store.ts
E2E coverage#
apps/oshun/web/e2e/studio-commenting-annotation-system.spec.ts— signed-in admin/studio/commenting-annotation-systemrender; real comment-thread catalog GET with admin bearer; default comments analyze POST through the live BFF; headline summary andc1-c5depth/mentions/orphan rows; edited-payload parent-chain depth, repeated-mention dedupe, and orphan proof; six sibling quick-action links; catalog loading/error; client-side malformed JSON zero-POST; live BFF 400 invalid-payload detail; non-admin 403 fail-closed; anonymous redirect-before-render.apps/oshun/web/e2e/studio-route-render-smoke.spec.ts— broad Studio route render and accessibility smoke coverage includes this route, but does not replace the focused real-BFF comment-thread spec above.
Open questions / known gaps#
- Confirm where annotations persist (postgres + ts_vector for search?) if the lane moves beyond a stateless analyze console
- Document how
@mentionextraction handles edge cases (punctuation, consecutive mentions, unknown users) - Live screen-reader and touch-device manual passes remain outside the automated route spec