Workflow Studio Architecture
Workflow Studio is the browser authoring application under apps/admin-web. It is a Next.js 16 React 19 app that lets authenticated administrators edit step-gate workflows, inspect legacy modules, validate exact revisions, publish signed releases, and inspect channel state. It is not exposed as participant MCP and does not execute participant workflow steps.
Runtime entrypoints
| Surface | Source | Responsibility |
|---|---|---|
| Page app | apps/admin-web/app/page.tsx | Main client component, navigation views, data loading, draft editing, validation/publish orchestration. |
| Session API | apps/admin-web/app/api/session/route.ts | Private staging login/logout using STUDIO_ACCESS_TOKEN and HttpOnly cookie. |
| Backend BFF | apps/admin-web/app/api/backend/[...path]/route.ts | Server-side proxy to Admin API. Filesystem reader could not load bracket path, but grep shows it uses ADMIN_API_URL, ADMIN_API_BEARER_TOKEN, and upstream fetch. |
| API helper | apps/admin-web/lib/api.ts | Browser fetch helper for /api/backend/{path}, JSON decoding, no-store cache, and ApiError. |
| Domain types | apps/admin-web/lib/types.ts | TypeScript shapes for legacy and engine workflow documents, assets, validators, releases, channels, and dependency views. |
The package scripts are pnpm typecheck, pnpm build, and pnpm test:e2e.
Session and BFF trust boundary
/api/session implements a private staging credential, not production OIDC. GET returns anonymous unless the configured token is at least 32 characters and matches the HttpOnly cookie. POST accepts { token }, compares it with timingSafeEqual, and sets rimthan_studio_session with httpOnly, sameSite: "strict", production-only secure, path /, and eight-hour max age. DELETE clears the cookie.
Browser code calls api<T>(path, init) in lib/api.ts. That helper always sends JSON to /api/backend/{path}, sets cache: "no-store", and maps non-OK responses to ApiError. The BFF holds ADMIN_API_BEARER_TOKEN; the browser receives only the Studio session cookie. The deployment contract in deploy/workflow-studio/env.example names these variables and states neither backend credential is exposed to browser JavaScript.
Main page state model
app/page.tsx is a single rich client component. Important state groups include:
- authentication and view:
authenticated,view(workflows,content,modules,releases); - catalogue data:
workflows,catalog,presentations,registryAssetDrafts,validatorDrafts,releases,channels; - selected workflow:
selectedWorkflow,revisions,selectedRevision,draft,working,workingLayout,selectedNode; - release flow:
targetRelease,validation,releaseSheetOpen,busy; - editor drawers: module, step, asset, validator, and create workflow sheet state;
- UI feedback:
notice,search, per-editor errors.
loadAll fetches workflows, modules, assets, releases, and channels in parallel. Draft selection fetches the current draft and revision list. Historical revision selection fetches exact revision snapshots and editor layout, allowing immutable history inspection without mutating the draft head.
Domain model split
lib/types.ts explicitly models two workflow document families:
LegacyWorkflowDocumentusesnodes, module references/candidates,route_module, and presentation bundles. It is retained for migration and legacy module editing.EngineWorkflowDocumentusesdefinition,steps,assets, andvalidators. It is the current step-gate workflow-engine authoring model.
The type guards isEngineWorkflow and isLegacyWorkflow drive UI branching. This is the frontend equivalent of the backend workflow_kind split in Admin API.
Data operations
The page implements these authoring operations against Admin API routes:
- create/load/select workflow drafts;
- save workflow draft head with
expected_revisionandeditor_layout; - load revision summaries and snapshots;
- edit legacy module candidates;
- edit engine step instructions and step JSON;
- edit registry assets and validator definitions;
- validate exact workflow revision for a target release;
- publish validated revision to production channel;
- inspect release detail and dependency views;
- activate/observe channels indirectly via release/publish flow.
The helper withAssetContent computes SHA-256 in the browser using crypto.subtle.digest, enforces the 1 MiB content limit, and validates JSON asset content before saving. This mirrors backend asset digest and size validation but does not replace it.
Relationship to other pages
- Workflow authoring semantics and schema invariants are documented in Workflow Schemas and Starter.
- The publication side of validation and publish is documented in Publication Pipeline.
- UI details for canvas, drawers, and release flow are documented in Workflow Editor and Release UI.
Focused validation
cd apps/admin-web && pnpm typecheckcd apps/admin-web && pnpm buildcd apps/admin-web && pnpm test:e2e