V1 Web PWA · Surface walkthrough

Studio · Data Retention and Lifecycle Controls

A per-surface walkthrough of the V1 Web PWA studio surface: layout, states, interactions, data, and cross-references.

walked
9sections4 minread

On this page

Context. surface studio · domain governance · route /studio/data-retention-lifecycle-controls · auth signed-in + studio entitlement · source apps/oshun/web/src/app/studio/data-retention-lifecycle-controls/page.tsx

Last walked. 2026-06-30 real-dev-infra Playwright addendum — focused route journey verified direct admin navigation, live BFF catalog, seeded retention classification, unknown-class safe retain issue, legal-hold precedence, client-only JSON validation, live BFF 400 details, network-unreachable classify failure, catalog loading/error, non-admin fail-closed auth, pending-submit lockout, quick-action affordances, shared axe, and anonymous redirect. Evidence: WALKTHROUGH/results/v1-real-infra-run-2026-06-22.md §233; apps/oshun/web/e2e/studio-data-retention-lifecycle-controls.spec.ts

Purpose#

Classify records against their data-class retention policy with the real lifecycle engine: the Lifecycle Classification Lane decides retain / archive / purge by age, with legal-hold precedence that freezes a record regardless of age. It is a live admin console wired to /v1/admin/studio/data-retention, not an in-page simulation.

Entry points#

  • Direct URL / bookmark/studio/data-retention-lifecycle-controls (signed-in + studio entitlement; admin scope required to evaluate)
  • Sibling Studio routes — reached via the quick-action panel on security-hardening-program, audit-compliance-surfaces, backup-disaster-recovery-ux, and other governance/operations pages

Layout regions#

page.tsx mounts <ShellLayout active="studio"> and renders <StudioDataRetentionLifecycleControlsWorkspace /> followed by a single panel of quick-action links.

  • Shell: ShellLayout chrome with the Studio tab active
  • Workspace heading: WorkspaceHeading renders the page <h1> "Studio Data Retention & Lifecycle Controls", followed by the data-data-retention-summary paragraph
  • Lifecycle Classification Lane: an <h2> data-dr-lane-heading ("Lifecycle Classification Lane") section with the load states and, when ready, the classify form and result table
  • Quick-actions panel: data-dr-quick-actions data-dr-quick-action-count="5" wraps 5 sibling quickAction Links: data-dr-quick-action="backup-disaster-recovery-ux", security-hardening-program, sdk-documentation-integration, webhooks-external-automation, and audit-compliance-surfaces. No self-link and no Route Map panel.

States#

  • Loadingdata-dr-loading ("Loading retention evaluator…")
  • Unauthorizeddata-dr-unauthorized ("Access restricted.") on 401/403
  • Errordata-dr-error on a failed catalog GET
  • Ready / formdata-dr-enums ("N lifecycle actions") plus the data-dr-form classify form seeded with DEFAULT_PAYLOAD and data-dr-form-state="idle|pending"
  • Pending submitdata-dr-submit-state="pending", disabled, aria-disabled="true", and aria-busy="true" while the evaluate POST is in flight
  • Resultdata-dr-result with the data-dr-headline (data-dr-count="retain|archive|purge|hold" tallies), the data-dr-records table of data-dr-record-row rows (data-record-id, data-action, data-dr-record-action), and the optional data-dr-issues list (data-dr-issue-row)
  • Classify errordata-dr-evaluate-error for invalid JSON or a non-200 response
  • Offline — catalog GET fails closed to the error panel; the classify POST surfaces the generic error when the network is unreachable
  • Gated — admin scope denied → data-dr-unauthorized; the route itself is proxy-gated to signed-in + studio
  • Standalone PWA — renders within the shell; no URL-bar dependency

Interactions#

  • Records (JSON)textarea data-dr-payload, aria-label="retention json", seeded with DEFAULT_PAYLOAD (records with recordId, classId, ageDays, legal-hold, plus the policy classes)
  • Classify recordsbutton data-dr-submit (type="submit"); POSTs the parsed payload to /v1/admin/studio/data-retention/evaluate, setting data-dr-result on a 200 with a valid result, or data-dr-evaluate-error otherwise
  • Quick-action links — each quickAction Link navigates to its sibling Studio route (see Layout regions for the 5 targets)

Data & contracts#

  • Reads: GET /v1/admin/studio/data-retention on mount — returns the catalog (lifecycleActions[])
  • Writes: POST /v1/admin/studio/data-retention/evaluate — returns { summary: { retainCount, archiveCount, purgeCount, holdCount }, records[], issues[] }
  • Realtime: none
  • Caching: client fetch with cache: 'no-store'; buildBffAuthHeaders() attaches the bearer token; SSR shell only
  • Auth/role check: admin-scoped fail-closed — admin:* or admin:studio, 401/403 under the studio workspace gate

E2E coverage#

  • apps/oshun/web/e2e/studio-data-retention-lifecycle-controls.spec.ts forwards GET /v1/admin/studio/data-retention and POST /v1/admin/studio/data-retention/evaluate to the live dev BFF. It covers direct admin navigation, catalog bearer forwarding, seeded classification counts (1 retain · 1 archive · 2 purge · 1 hold), unknown-class issue rendering, legal-hold precedence, malformed JSON zero-POST rejection, live BFF invalid-payload details, network-unreachable classify error, catalog loading/error state, pending-submit lockout, non-admin fail-closed state, quick-action href/touch targets, shared axe, and anonymous redirect before the workspace renders.

Cross-references#

Open questions / known gaps#

  • Confirm whether the page will gain a breadcrumb/Route Map panel like other Studio surfaces, or keep the flat quick-action panel
  • Document the persisted record source the lane should classify once it runs against a live retention store rather than a pasted JSON payload
  • Manual screen-reader and installed/standalone PWA passes remain outside the automated Playwright route journey.