V1 Web PWA · Surface walkthrough

Studio Hathor · Journal and Codex

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

walked
8sections4 minread

On this page

Context. surface studio · domain hathor · route /studio/hathor/journal-and-codex · auth signed-in + studio entitlement · source apps/oshun/web/src/app/studio/hathor/journal-and-codex/page.tsx

Last walked. 2026-07-03 focused real-dev-infra Playwright route walk — anonymous redirect, Hathor-admin catalog load, browser bearer propagation, exact default / empty-discovery / duplicate-flag codex unlock results through the real BFF, client JSON/object validation, BFF invalid-payload detail surfacing, malformed result/catalog fail-closed states, loading / 503 / non-admin / transport states, pending-submit lockout, route-map and quick-action contracts, mobile no-overflow / 44px targets, scoped axe, and direct BFF auth/schema gates. Evidence: apps/oshun/web/e2e/studio-hathor-journal-and-codex.spec.ts and WALKTHROUGH/results/v1-real-infra-run-2026-06-22.md#278-2026-07-03-studio-hathor-journal-and-codex-real-bff-coverage

Purpose#

The load-bearing surface is an admin lane console — the Live Codex Unlock Resolver — that runs the real codex-unlock resolver over a set of codex entries and player progress to compute which entries unlock, completion percentage, and the next unlock. The operator submits a JSON codex payload and the lane returns the resolved unlock state. The resolver is wrapped in a retained dense expert-mode shell (controls grid, observability, etc.).

Entry points#

  • Quick-action link from /studio/hathor/narrative-export — "Open Hathor Journal and Codex workspace"
  • Direct URL / bookmark — yes; alternates.canonical set to /studio/hathor/journal-and-codex
  • Studio overview — see ../../studio-overview.md

Layout regions#

page.tsx renders inside <ShellLayout active="studio">:

  • Workspace <StudioHathorJournalAndCodexWorkspace />:
    • WorkspaceHeading <h1> — "Hathor Journal and Codex Workspace" + an intro <p> describing journal/codex/citation governance
    • Live Codex Unlock Resolver lane (data-jcx-lane) — <h2 data-jcx-heading>; the real admin lane console (loading / unauthorized / error / form / result)
    • A retained "Expert Controls" shell beneath the lane (density / breakpoint selects under data-hathor-journal-and-codex-controls-grid and further expert panels) — scaffolding around the lane, not the load-bearing surface
  • Route Map panel data-hathor-journal-and-codex-route-map<h2> "Route Map" listing the 5 STUDIO_HATHOR_JOURNAL_AND_CODEX_ROUTE_MAP entries (entries / codex / citations / governance child paths) with data-hathor-jcx-route-count and per-entry data-route-path
  • Quick-action lane data-hathor-jcx-quick-actions — two Link.quickAction anchors: Story Graph Authoring, Back to Studio workspace index

States#

  • Loadingdata-jcx-loading "Loading codex unlock resolver…"; Playwright holds the catalog request before releasing it to a 503
  • Unauthorized (admin-scope 401/403)data-jcx-unauthorized, verified with a non-admin browser bearer forwarded to the real BFF
  • Errordata-jcx-error, verified for 503 catalog and malformed catalog bodies
  • Ready (form) — when outcome.status === 'ready': data-jcx-form exposes data-jcx-form-state="idle" and aria-busy="false" with the default codex payload
  • Pendingdata-jcx-form-state="pending", disabled textarea/button, aria-busy="true", and button text "Resolving…" while the POST is held
  • Resultdata-jcx-result with data-jcx-headline, data-jcx-completion, data-jcx-next, and data-jcx-entries (per-entry data-jcx-entry-row carrying data-jcx-entry-state / data-jcx-entry-missing), verified for default, empty-discovery, and duplicate-flag payloads against the real BFF
  • Validation errordata-jcx-resolve-error for invalid JSON, non-object JSON, BFF invalid-payload detail, malformed 200 result, and transport failure

Interactions#

Live Codex Unlock Resolver lane#

  • Codex entries payload<textarea data-jcx-payload> (aria-label "codex entries json"), disabled during pending submit, 44px minimum target, and mobile no-overflow verified
  • Submit<button data-jcx-submit> "Resolve unlocks" → POST JCX_RESOLVE_ENDPOINT; browser auth header and request body are captured while the same-origin call is forwarded to the real local BFF

Route Map panel#

  • Route entries — verified to match STUDIO_HATHOR_JOURNAL_AND_CODEX_ROUTE_MAP (5 entries) by data-hathor-jcx-route-count and per-entry data-route-path

Quick-action lane#

  • "Open Hathor Story Graph Authoring workspace"/studio/hathor/story-graph-authoring
  • "Back to Studio workspace index"/studio

Data & contracts#

  • Reads: GET /v1/admin/hathor/journal-and-codex (JCX_ENDPOINT) — the codex resolver catalog
  • Writes: POST /v1/admin/hathor/journal-and-codex/resolve (JCX_RESOLVE_ENDPOINT) with the codex entries payload
  • Realtime: none for the resolver lane
  • Caching: client fetch on mount, cache: 'no-store', buildBffAuthHeaders()
  • Auth/role check: admin-scoped, fail-closed on 401/403; route additionally gated signed-in + studio by the BFF proxy
  • Real-infra E2E: apps/oshun/web/e2e/studio-hathor-journal-and-codex.spec.ts forwards browser resolver calls to the real local BFF and separately asserts direct BFF unauthenticated, non-admin, invalid-payload, and valid-result gates.

Cross-references#

Open questions / known gaps#

  • The workspace still ships a large dense expert-mode shell (density / breakpoint controls, expert panels) around the real resolver lane. Confirm whether that shell is intended for V1 or is migration debris from the older list-detail-wizard template; the load-bearing surface is the resolver lane.
  • Hathor is unconfirmed-v1 per WALKTHROUGH/matrix/routes.csv. Confirm whether the dedicated /studio/hathor/ lane consoles ship at V1 or are internal-only.