Skip to content

Factory Studio — workflows

Target

This page describes intended behaviour or structure. No implementation is claimed unless a section is explicitly marked Current implementation or Evidence.

Rewritten 2026-10-09 (design plan P13)

The June-2026 page (human review workflow, dashboard refresh, saved views) is archived under catalogs 2026-06; its review flow is now the Control plane's approval flow rendered by the Workspace area.

W1 — A session starts

sequenceDiagram
    participant U as User
    participant GW as Edge gateway (GW-01)
    participant B as StudioBff
    participant ID as Identity platform
    participant CP as ControlPlaneApi
    U->>GW: sign in (OpenIddict, PKCE)
    GW->>B: GET /studio/session (token)
    B->>ID: validate, user, roles
    B->>CP: effective permissions for the default scope (tenant, project)
    B-->>U: session: scope, permissions snapshot, locale (he → RTL), theme, work area, flags
    U->>B: PUT /studio/session/scope (project P)
    B->>CP: may the user read project P?
    B-->>U: scope switched, permissions re-snapshotted (nothing granted by the switch)
Hold "Alt" / "Option" to enable pan & zoom

W2 — A screen composes

The BFF reads each source in parallel under the session's scope, attaches freshness per source (projection lag, last observation), computes per-action permissions from the owning platform's answer, caches the composition for a few seconds keyed by scope, and returns it. A screen is defined once in the UX model (screens.yaml) with its sources and commands; the composition follows that definition.

W3 — A command is forwarded

sequenceDiagram
    participant U as User (Reviewer)
    participant B as StudioBff
    participant RC as RunControlService
    U->>B: POST /studio/commands/decide-approval {approvalId, version, decision} (idempotency key)
    B->>RC: DecideApproval (user token, scope, exact version)
    alt version matches, decider ≠ requester
        RC-->>B: 200 ApprovalDecided
    else proposal changed
        RC-->>B: 412 (stale version, the card re-renders with the new proposal)
    else not eligible
        RC-->>B: 403 (reason)
    end
    B-->>U: outcome rendered, the BFF never retries or queues
Hold "Alt" / "Option" to enable pan & zoom

W4 — A notification reaches the right people

An event (an alert, a release ready, an incident) is consumed by StudioNotificationService; recipients are resolved through the owning platform's permission check; preferences and quiet hours apply; the notification is pushed through the realtime gateway and, if chosen, delivered by email or chat through connectors with receipts. Opening it fetches the subject under the user's permissions at that moment.

W5 — A timeline streams and resumes

sequenceDiagram
    participant UI as Run page
    participant RT as StudioRealtimeGateway
    participant D as DashboardService
    UI->>RT: subscribe RunTimeline(run R)
    RT->>D: Operations.Subscribe (scope)
    D-)RT: RunProjectionUpdated seq 41, 42, 43
    RT-)UI: push 41, 42, 43
    Note over UI: network drop
    UI->>RT: reconnect, resume from 43
    alt within buffer
        RT-)UI: 44…
    else beyond buffer
        RT-)UI: refresh (the page re-composes through the BFF)
    end
Hold "Alt" / "Option" to enable pan & zoom

W6 — A source degrades

When a platform is unreachable, the composition returns the other sources, marks the missing one degraded with its last known freshness, disables its commands with a visible reason, and the status page shows the dependency; nothing is faked and nothing is queued.