Context. surface studio · domain collaboration · route /studio/activity-change-feeds · auth signed-in + studio entitlement · source apps/oshun/web/src/app/studio/activity-change-feeds/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; content re-verified 2026-06-03 against current source
Purpose#
Operate activity and change feeds as a live, admin-scoped BFF console. The
workspace (StudioActivityChangeFeedsWorkspace) wires a single Change
Coalesce Lane to the real change-data-capture (CDC) coalescer via
/v1/admin/studio/change-feed: it folds a chronological event log into one net
change per entity (a created then deleted cancels to no-op, repeated
updated events collapse), reporting contributing event counts and the distinct
actors per entity. 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 (real-time collaboration, presence, commenting/annotation, review/approval, notification center, audit/compliance surfaces, enterprise tenant isolation)
- Direct URL / bookmark — yes
Layout regions#
page.tsx mounts ShellLayout active="studio", renders
StudioActivityChangeFeedsWorkspace, then a single panel containing 7 sibling
quickAction links. There is no Route Map panel on this page.
- Shell header — from
ShellLayout - Workspace
<h1>— "Studio Activity & Change Feeds" (WorkspaceHeading), followed by adata-activity-change-feeds-summaryparagraph describing the coalescing - Change Coalesce Lane (
<h2>data-cf-lane-heading"Change Coalesce Lane") — the catalog/loading/unauthorized/error states, the coalesce form, and the result - Quick-actions panel —
panelwith 7quickActionlinks to sibling workspaces (no self-link, no Route Map)
States#
- Loading —
data-cf-loading"Loading change-feed coalescer…" while the GET catalog request is in flight (outcome === null) - Unauthorized —
data-cf-unauthorized"Access restricted." on 401/403 (admin scope required); shows the BFF message or "Studio admin scope required to coalesce the feed." - Error —
data-cf-error"Could not load the change-feed coalescer." on any non-OK catalog response or network failure - Ready (form) — catalog loaded;
data-cf-enumsshows{changeTypes.length} change types · {netChanges.length} net changes, and thedata-cf-formform renders - Result — after a successful POST,
data-cf-resultrenders the feed headline + per-entity table - Coalesce validation error —
data-cf-coalesce-errorfor invalid JSON, network unavailable, or a non-200 POST (shows the POSTdetail)
Interactions#
Change Coalesce Lane form#
- Events (
textareadata-cf-payload,aria-label="events json") — JSON{ events[{ eventId, entityId, changeType, actor }] }; seeded with a default payload - Coalesce feed (
buttondata-cf-submit,type="submit") —submitCoalesceparses the JSON (rejecting invalid JSON withdata-cf-coalesce-error) and POSTs to/v1/admin/studio/change-feed/coalesce
Result#
- Headline (
data-cf-headline) —<data-cf-total-events> → {entries.length} entities · {createdCount} created · {updatedCount} updated · {deletedCount} deleted · {noOpCount} no-op - Entries table (
data-cf-entries) — onedata-cf-entry-rowper entity withdata-entity-id,data-net-change, plusdata-cf-net-change/data-cf-event-count/data-cf-actorscells
Quick actions#
- Open Real-Time Collaboration Substrate workspace
- Open Presence and Cursor Systems workspace
- Open Commenting and Annotation System workspace
- Open Review and Approval Workflows workspace
- Back to Notification Center workspace
- Back to Audit and Compliance Surfaces workspace
- Back to Enterprise Tenant Isolation workspace
Data & contracts#
- GET catalog:
/v1/admin/studio/change-feed— fetched on mount withbuildBffAuthHeaders()andcache: 'no-store'; returns{ changeTypes[], netChanges[] } - POST verb:
/v1/admin/studio/change-feed/coalescewith body{ events[{ eventId, entityId, changeType, actor }] }→{ result: { entries[], totalEvents, summary{ createdCount, updatedCount, deletedCount, noOpCount } } }(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-notification-center.md,studio-presence-cursor-systems.md,../governance/studio-audit-compliance-surfaces.md - Component:
apps/oshun/web/src/components/studio/StudioActivityChangeFeedsWorkspace.tsx - BFF route:
apps/oshun/bff/src/routes/admin-studio-change-feed.ts - BFF store:
apps/oshun/bff/src/studio/change-feed-store.ts
Open questions / known gaps#
- Confirm whether coalesced feeds persist, or whether the lane stays a stateless coalescer
- Document the net-change resolution for interleaved create/delete/update runs beyond the default cancel/collapse rules