Skip to content

Factory Studio — aggregate roots

Generated from the architecture model

This page is rendered from model/**/*.yaml by tools/docs_model during mkdocs build. Edit the YAML, not this page; hand-written design lives on the linked service, platform and plane pages.

Aggregate Service Root entity Events Tables
StudioSession StudioBff StudioSession StudioSessionStarted StudioSessions
SavedView StudioBff SavedView SavedViewChanged SavedViews
Notification StudioNotificationService Notification NotificationCreated Notifications
NotificationPreference StudioNotificationService NotificationPreference — NotificationPreferences
RealtimeSubscription StudioRealtimeGateway RealtimeSubscription — —

StudioSession (StudioBff)

The per-user session projection: the resolved execution scope (organization, tenant, project, environment switchers that grant nothing by themselves), roles and effective permissions snapshot, locale, theme, reduced-motion preference, current work area and the realtime subscriptions the session holds.

Field Type Required Description
sessionId guid yes
tenantId string yes
userId string yes
scope json yes execution-scope-v1: tenant, project, environment
permissionsSnapshot json yes
locale enum:Locale yes
theme string yes light
reducedMotion bool yes
workArea enum:WorkArea yes
subscriptions list:string yes
startedAt datetime yes
lastSeenAt datetime yes

Invariants

  • A switcher changes the scope the session reads under; it never grants a permission the identity platform and the Control plane did not grant (ADR-0015).
  • Every composed response is filtered by the owning platform under the session's scope; the BFF never widens a result set.

SavedView (StudioBff)

A user- or team-saved filter and layout for a list screen (runs, approvals, assets, alerts, fleet) with sharing scope.

Field Type Required Description
viewId guid yes
tenantId string yes
ownerUserId string yes
screenId string yes
name string yes
definition json yes
sharedWith string yes private
updatedAt datetime yes

Invariants

  • A shared view carries no data, only a filter definition; results are still scoped per viewer.

Notification (StudioNotificationService)

One notification for one user: kind, subject reference, scope, importance, read and dismissed state, and the deliveries made per channel with receipts.

Field Type Required Description
notificationId guid yes
tenantId string yes
userId string yes
kind enum:NotificationKind yes
subjectRef string yes
projectId string no
importance string yes info
summary string yes
readAt datetime no
dismissedAt datetime no
deliveries json yes
createdAt datetime yes

Invariants

  • A notification is created only for users whose scope and role allow seeing the subject; the fan-out resolves recipients through the owning platform's permission check, never from the event alone.
  • Content is a summary with a reference; the Studio fetches the subject under the user's permissions when opened.

NotificationPreference (StudioNotificationService)

Per-user channel preferences, quiet hours and digest settings per notification kind.

Field Type Required Description
userId string yes
tenantId string yes
channelsByKind json yes
quietHours json no
digest string yes none

Invariants

  • Action-required and critical notifications ignore quiet hours for the in-app channel.

RealtimeSubscription (StudioRealtimeGateway)

One session's subscription to one stream with its scope filter, the upstream gRPC stream or inbox it is served from, backpressure state and the last sequence delivered.

Field Type Required Description
subscriptionId guid yes
tenantId string yes
sessionId guid yes
connectionId string yes
kind enum:StreamKind yes
filter json yes run id, project, environment, product
lastSequence long yes
backpressure bool yes
startedAt datetime yes

Invariants

  • A subscription is created only after the BFF confirmed the session may read the subject; the filter cannot widen the session's scope.
  • On reconnect the client resumes from the last sequence; gaps beyond the buffer trigger a full refresh of the screen, never a silent skip.