TenantAtlas/specs/216-provider-dispatch-gate/data-model.md
Ahmed Darrazi 34230be79d
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 4m21s
feat: unify provider-backed action dispatch gating
2026-04-20 08:47:08 +02:00

9.8 KiB

Data Model: Provider-Backed Action Preflight and Dispatch Gate Unification

Overview

This feature does not introduce new persisted entities or tables. It extends the existing provider-backed start contract around ProviderConnection, OperationRun, and onboarding draft state so every covered operator-triggered start follows the same queue-admission, conflict-protection, and operator-feedback rules.

The key design constraint is that start truth remains service-owned and derived from existing runtime records:

  • provider readiness and connection identity from ProviderConnection plus ProviderConnectionResolver
  • accepted or prevented work truth from OperationRun
  • click-time queue-admission decisions from ProviderOperationStartGate
  • onboarding bootstrap continuity from existing TenantOnboardingSession.state
  • operator feedback from existing Ops UX helpers plus one thin shared provider-start presentation helper

Existing Persistent Inputs

1. ProviderConnection

  • Purpose: Tenant-owned provider credential and readiness record that defines which delegated connection a provider-backed operation can use.
  • Key persisted fields used by this feature:
    • id
    • tenant_id
    • provider
    • entra_tenant_id
  • Existing runtime facts consumed through current services:
    • default-vs-explicit selection
    • consent readiness
    • credential usability
    • provider identity and scope targeting
  • Relationships used by this feature:
    • owning tenant
    • related operation runs through OperationRun.context.provider_connection_id

2. OperationRun

  • Purpose: Canonical operational truth for queued or executed provider-backed work and for blocked preflight attempts that must remain observable.
  • Key persisted fields used by this feature:
    • id
    • tenant_id
    • type
    • status
    • outcome
    • reason_code
    • context
    • summary_counts
    • started_at
    • completed_at
  • Existing relationships or references used by this feature:
    • initiator user
    • tenant scope
    • canonical Monitoring → Operations detail route

3. TenantOnboardingSession

  • Purpose: Workspace-owned onboarding workflow record that already stores onboarding progress and step state, including bootstrap operation selections and related run references.
  • Key persisted fields used by this feature:
    • id
    • workspace_id
    • tenant_id (nullable until attached)
    • current_step
    • state
  • Existing state keys used by this feature:
    • bootstrap_operation_types
    • bootstrap_operation_runs
  • Relationships used by this feature:
    • workspace
    • attached tenant when present

4. RestoreRun

  • Purpose: Tenant-owned restore execution record whose execute action becomes part of the canonical provider-backed start contract.
  • Key persisted fields used by this feature:
    • id
    • tenant_id
    • restore configuration and preview state already captured before execution
  • Relationships used by this feature:
    • tenant
    • backup source records and restore safety flow already owned by existing restore logic

Existing Service-Owned Inputs

A. ProviderOperationRegistry Entry

This is an existing logical definition, not a new persisted entity.

Field Meaning
operationType The write-time operation type string admitted by the gate
module Current operation family/module metadata used in run context
dispatcher The queue-dispatch callback or equivalent start hook
requiredCapability Capability gate required to start the operation
providerScopeExpectation Whether the operation is connection-scoped and therefore protected by click-time conflict rules

Rules:

  • First-slice coverage adds entries for every covered action host instead of introducing a second registry.
  • This feature does not normalize historical operation names; registry entries follow current write-time operation types.

B. ProviderConnectionResolution

Logical output of ProviderConnectionResolver and ProviderOperationStartGate.

Field Meaning
providerConnectionId Explicit resolved connection identity when admission is possible
provider Provider family used for copy and downstream dispatch
targetScope Current tenant/provider scope metadata for run context
reasonCode Stable blocked reason when admission is prevented
reasonMeta Sanitized structured detail for translation and next steps
nextSteps Resolution path metadata used by the shared presentation helper

Rules:

  • Every accepted covered start must resolve this state before queue admission.
  • Blocked resolutions never admit a queued job.

Derived Coordination Entities

1. ProtectedProviderScope

This is a logical concurrency boundary, not a new table.

Field Meaning
tenantId Tenant boundary for the operation
providerConnectionId Connection boundary for provider-backed conflict protection
activeRunId Existing queued or running run occupying the scope, when present
activeOperationType Operation currently using the protected scope

Rules:

  • At most one provider-backed operation may be accepted at a time for one protected scope.
  • If the same operation type is already active on the scope, the result is deduped.
  • If a different covered operation is already active on the same scope, the result is scope_busy.

2. PreflightStartResult

This is the shared logical result of a covered start attempt.

Field Meaning Source
internalState Current service-owned state such as started, deduped, scope_busy, or blocked ProviderOperationStartResult
operatorState Operator-facing vocabulary: accepted, deduped, scope_busy, blocked shared presenter
operationType Covered operation being started action host + registry
runId Canonical run for accepted, deduped, or scope-busy results, and optionally for blocked truth where already created OperationRun
providerConnectionId Resolved connection identity when known gate + resolver
reasonCode Stable problem class for blocked or other directed outcomes current reason system
nextSteps Structured resolution or follow-up guidance next-step registry / helper

Validation rules:

  • blocked must never dispatch a background job.
  • accepted, deduped, and scope_busy must point to the canonical run the operator should inspect.
  • accepted must carry the explicit provider_connection_id into accepted-work context.

3. AcceptedProviderBackedRunContext

Logical accepted-work context persisted inside OperationRun.context.

Field Meaning
provider_connection_id Explicit connection identity used by the accepted run
provider Provider family label for display and diagnostics
target_scope Sanitized tenant/provider scope metadata
source_surface Action-host family such as tenant detail, provider connection, onboarding, restore, or directory sync
initiator_user_id Starting actor
operation_specific_context Existing per-operation context already needed by downstream jobs

Rules:

  • Jobs must receive the same provider_connection_id that was accepted at click time.
  • Monitoring and notifications explain accepted work using this context rather than a runtime default connection lookup.

4. ProviderStartPresentation

Logical derived presentation output returned by the shared start-result helper.

Field Meaning
title Standardized accepted/deduped/scope-busy/blocked headline
body Short reason or queue message aligned with the spec vocabulary
statusStyle Existing toast/notification severity
viewRunAction Canonical open-run action when a run exists
nextStepActions[] Optional resolution actions or follow-up links
domainVerb Local action verb preserved from the host surface
domainTarget Local object noun preserved from the host surface

Rules:

  • Accepted and deduped outcomes continue to use the existing OperationUxPresenter toast style.
  • Blocked and scope-busy outcomes must no longer rely on page-local copy branches.
  • Domain verb and target remain local so the shared contract does not flatten the product vocabulary into generic verbs.

5. OnboardingBootstrapAdmission

Logical onboarding-only coordination model built from existing draft state.

Field Meaning
selectedOperationTypes[] Bootstrap operations the operator selected
acceptedOperationType The one operation type admitted for the current submission
pendingOperationTypes[] Remaining selected types still waiting to run
runIdsByOperationType Existing and newly accepted run references persisted in draft state

Rules:

  • A bootstrap submission may accept at most one provider-backed operation for the protected scope.
  • Remaining bootstrap selections stay in existing draft state rather than spawning a new orchestration entity.
  • The onboarding step continues to be the only primary context; operators should not need a new workflow page to understand the pending follow-up.

State Transitions

Covered Start Attempt

requested
  -> blocked      (no queue admission, blocked truth retained where applicable)
  -> deduped      (existing same-operation active run reused)
  -> scope_busy   (existing different-operation active run reused)
  -> accepted     (run admitted, queued job dispatched with explicit provider connection)

Onboarding Bootstrap Submission

selected operations
  -> blocked / deduped / scope_busy  (no new run admitted)
  -> accepted operation + pending operations retained in draft state

Non-Goals In The Data Model

  • No new provider-start table or umbrella batch entity
  • No new persisted summary or presentation artifact
  • No platform-wide operation-type rename or taxonomy rewrite
  • No new status family beyond the shared start-result vocabulary already required by the spec