V1 Web PWA · Surface walkthrough

Studio · Generation · Living Scene

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

walked
8sections2 minread

On this page

Context. surface studio · domain generation · route /studio/generation/living-scene · auth anon (explicit public route) · source apps/oshun/web/src/app/studio/generation/living-scene/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

Purpose#

Approved Living Scene generation surface (§24.10). The route is explicitly public (middleware adds /studio/generation/living-scene to PUBLIC_PATHS) but enforces tier and tenant policy inside the page and the @yemaya/living-scenes-runtime library, so only approved templates and frozen workflow classes are exposed.

Entry points#

  • Direct URL / bookmark — yes (public)
  • Studio root — quick action to Compose; Living Scene is also exposed on the Studio root once entitled
  • Deep link with x-oshun-tier / x-oshun-living-scene-templates / x-oshun-living-scene-frozen-workflow-classes / x-oshun-locale headers (forwarded by upstream surfaces)

Layout regions#

The page is server-rendered. It reads the request headers (tier, tenantPolicy, requestedLocale) via next/headers, then renders:

  • Outer <main> with data-living-scene-route, data-living-scene-route-entitlement-gate="route", dark backdrop
  • Centered column with a single LivingSceneCard component receiving the accessContext ({ tier, tenantPolicy, requestedLocale })

The LivingSceneCard component (≈ 660 LOC) renders the Living Scene preview, control set, and tenant-policy banner. Walk that component in a dedicated sub-file if it becomes its own route.

States#

  • Anonymous user, no tier headertier defaults to free; tenantPolicy.enabled defaults to true; Living Scene renders for anonymous viewers with free-tier limits
  • x-oshun-tier=pro — paid templates / locales become available
  • x-oshun-tier=premium — full template set available
  • x-oshun-living-scenes-enabled=false — tenant policy disables Living Scene; the card renders the disabled state
  • x-oshun-living-scene-templates whitelist — only templates in the approved set + the header subset render
  • x-oshun-living-scene-frozen-workflow-classes set — listed workflow classes are frozen; mutating actions disabled
  • x-oshun-living-scene-locales set — Living Scene exposes the listed locales only
  • Default locale fallback — when x-oshun-locale is absent the page uses en-US
  • Reduced motion — Living Scene animations honor preference (handled inside LivingSceneCard)
  • Offline — page is server-rendered; subsequent generation requests use the SW cache where applicable

Interactions#

All interactive controls live inside the LivingSceneCard component (approved-template picker, generation trigger, preview pane, locale switch). Walk that component when verifying:

  • Template picker (only approved templates allowed)
  • Locale switch (constrained to allowedLocales when set)
  • Generate (gated by tier + frozen workflow class set)
  • Preview surface — renders generated output
  • Disclosure banner — surfaces tenant-policy state

Data & contracts#

  • Reads (server):
    • headers()x-oshun-tier, x-oshun-locale, x-oshun-living-scenes-enabled, x-oshun-living-scene-templates, x-oshun-living-scene-frozen-workflow-classes, x-oshun-living-scene-locales
  • Reads (library): @yemaya/living-scenes-runtimeAPPROVED_LIVING_SCENE_TEMPLATE_IDS, LivingSceneCustomerTier, LivingSceneTenantPolicy, LivingSceneTemplateId
  • Writes: handled inside the LivingSceneCard (generation requests)
  • Caching: SSR with header-derived inputs; SW caches static assets
  • Auth/role check: middleware allows anonymous (PUBLIC_PATHS); tier + tenant policy enforced inside the page and the runtime library

Cross-references#

Open questions / known gaps#

  • Confirm whether the public route stays anonymous in production or becomes signed-in once Yemaya entitlements are integrated
  • Document the upstream proxy that injects x-oshun-* headers (Cloudflare worker? BFF middleware?)