AUTH4D-161 Flows console storyboard and test runs

The developer console now edits the AUTH4D-159 flows. The console route table is frozen, so Flows opens from existing screens:

  • Settings → Flows opens the project storyboard (/projects/{projectId}/settings?flows=1): one lane per trigger with the flow the whole project runs, its steps in order, the applications that override the lane, the project’s other flows for that trigger, and actions to create a flow, use a published flow for the project, or go back to the built-in default.
  • Applications → an application has a Flows section. Each trigger is either Inherit from project or Override. Choosing Override creates a flow for the application as a copy of what runs now (the project’s active version, or no steps), publishes it unchanged and binds it to the application, so behaviour does not change until the copy is edited and published. Choosing Inherit again removes the application binding; the flow is kept.
  • The flow editor (?flow={flowId} on either screen) shows the draft as a storyboard of step cards. Steps are added from a list of the built-in step types, edited in a form, and reordered with Move up and Move down buttons; nothing needs dragging. Save draft stores the draft, the editor shows what changed against the active version (per step and line by line), Publish makes the saved draft active, and the Versions table makes an earlier published version active again (rollback). Viewers see everything read-only and can run tests.
  • Test run runs one version against a sample sign-in and shows the per-step trace.
  • Recent executions lists the latest 50 runs with their per-step traces. For each call_backend step it shows how many of those runs failed or timed out, and highlights steps above 5%.

The console never shows the API’s error descriptions. It maps error codes to its own text and, for validation_failed and flow_invalid, names the step and field from details[].field only.

Test runs

The route is under /management/tenants/{tenantId}, needs a management token with tenant:read and any project role, like the executions list, and is reached from the console through its BFF at /api/management/..., which refuses cross-site requests (403 csrf_rejected). Responses are no-store.

Method and path Body Result
POST /flows/{flowId}/test { version?, event } { test }
{
  "version": 3,
  "event": {
    "applicationId": "cli_…",
    "method": "email",
    "country": "ZA",
    "provider": "email",
    "userId": "usr_…"
  }
}
  • version picks the version to run; without it the draft runs, else the active version. An unknown version answers 404.
  • event.applicationId must be one of the project’s applications (404 otherwise). method is a sign-in method (FlowMethodSchema); country (ISO 3166-1 alpha-2) and provider are optional.
  • event.userId is optional and must be a user of the project (404 otherwise). Data-reading steps (require_verified_email, the lists, set_role, terms_screen, condition) then read that user’s rows. Without it they see a placeholder user with no data. It is ignored for pre_registration, which has no user.
  • Nothing is written: no execution trace, no stored role or metadata, no terms acceptance and no audit event. call_backend steps are not called; they count as continuing and are listed in simulatedSteps.
  • Drafts are only structure-checked when saved, so a test of a draft can hit a condition type error at run time; the step then follows its onError policy, as it would in production.
{
  "test": {
    "version": 3,
    "status": "draft",
    "outcome": "continue",
    "reasonCode": null,
    "durationMs": 4,
    "steps": [
      { "step": "discord", "type": "deny", "outcome": "skipped", "durationMs": 0 },
      { "step": "tier", "type": "patch_claims", "outcome": "patched", "durationMs": 0 },
      { "step": "api-check", "type": "call_backend", "outcome": "continued", "durationMs": 0 }
    ],
    "claims": { "game:tier": "gold" },
    "roles": [],
    "storedRoles": {},
    "storedMetadataKeys": [],
    "simulatedSteps": ["api-check"]
  }
}

outcome is continue, deny or interact (a terms_screen the player has not accepted). claims and roles are the token patches a continue would carry; storedRoles and storedMetadataKeys are the role changes and metadata keys it would store, without values. The schemas are TestFlowRequestSchema and TestFlowResponseSchema in packages/contracts.

Tests

tests/integration/auth4d-161.flow-test-run.test.ts runs the route through the API composition (no rows written, chosen versions and users, interactions, refusals) and checks the BFF forwards it and refuses it cross-site. tests/e2e/auth4d-161.flows-console.spec.ts drives the console against a stateful BFF mock: storyboard lanes, creating and binding flows, inherit and override, keyboard editing and reordering, the diff, publish, rollback, test runs, executions and the error-rate hint, the viewer role, server error text never appearing, and axe checks at 1280px and 320px.

cd tests/integration && npx vitest run auth4d-161 --no-file-parallelism --testTimeout=30000
pnpm exec playwright test -c tests/e2e/auth4d-161.playwright.config.ts

Source: docs/api-spec/auth4d-161.md