TenantAtlas/specs/081-provider-connection-cutover/data-model.md
ahmido 4db8030f2a Spec 081: Provider connection cutover (#98)
Implements Spec 081 provider-connection cutover.

Highlights:
- Adds provider connection resolution + gating for operations/verification.
- Adds provider credential observer wiring.
- Updates Filament tenant verify flow to block with next-steps when provider connection isn’t ready.
- Adds spec docs under specs/081-provider-connection-cutover/ and extensive Spec081 test coverage.

Tests:
- vendor/bin/sail artisan test --compact tests/Feature/Filament/TenantSetupTest.php
- Focused suites for ProviderConnections/Verification ran during implementation (see local logs).

Co-authored-by: Ahmed Darrazi <ahmeddarrazi@MacBookPro.fritz.box>
Reviewed-on: #98
2026-02-08 11:28:51 +00:00

4.0 KiB
Raw Blame History

Data Model: Provider Connection Full Cutover

Feature: specs/081-provider-connection-cutover/spec.md
Date: 2026-02-07

This document describes the entities involved in Spec 081 using the repos current schema.

Entities

Tenant

Represents: A managed tenant target (Entra/Intune tenant) within a workspace.

Relevant attributes (existing)

  • id (PK)
  • workspace_id (FK)
  • name
  • tenant_id (GUID-ish, used as Entra tenant ID)
  • external_id (alternate tenant identifier)
  • Legacy (deprecated by this spec):
    • app_client_id
    • app_client_secret (encrypted)
    • app_certificate_thumbprint
    • app_notes

Derived helpers (existing)

  • graphTenantId(): ?string returns tenant_id or external_id.
  • graphOptions(): array{tenant:?string,client_id:?string,client_secret:?string} (to be deprecated/unused at runtime).

Relationships (existing)

  • providerConnections(): HasMany → ProviderConnection
  • providerCredentials(): HasManyThrough → ProviderCredential (via ProviderConnection)
  • operationRuns(): HasMany (implicit via OperationRun.tenant_id)

ProviderConnection

Represents: A workspace-owned integration connection for a tenant + provider (e.g., Microsoft).

Table: provider_connections

Fields (existing)

  • id (PK)
  • workspace_id (FK, NOT NULL after migration)
  • tenant_id (FK)
  • provider (string, e.g. microsoft)
  • entra_tenant_id (string; expected to match the tenants Entra GUID)
  • display_name (string)
  • is_default (bool)
  • status (string; default needs_consent)
  • health_status (string; default unknown)
  • scopes_granted (jsonb array)
  • last_health_check_at (timestamp)
  • last_error_reason_code (string, nullable)
  • last_error_message (string, nullable; must be sanitized)
  • metadata (jsonb)
  • created_at, updated_at

Relationships (existing)

  • tenant(): BelongsTo
  • workspace(): BelongsTo
  • credential(): HasOne → ProviderCredential

Invariants (existing + required)

  • Uniqueness: unique (tenant_id, provider, entra_tenant_id)
  • Exactly one default per (tenant_id, provider): enforced by partial unique index provider_connections_default_unique.

Behaviors (existing)

  • makeDefault() clears other defaults and sets this record default in a DB transaction.

ProviderCredential

Represents: Encrypted credential material for a provider connection.

Table: provider_credentials

Fields (existing)

  • id (PK)
  • provider_connection_id (FK, unique)
  • type (string; default client_secret)
  • payload (encrypted array; hidden from serialization)
  • created_at, updated_at

Payload contract (current)

  • For type=client_secret:
    • client_id (string)
    • client_secret (string)
    • optional tenant_id (string) validated against ProviderConnection.entra_tenant_id

OperationRun

Represents: A canonical record for a long-running or operationally relevant action.

Table: operation_runs

Key fields (existing)

  • id (PK)
  • workspace_id (FK)
  • tenant_id (FK nullable in some cases)
  • type (string)
  • status (queued|running|completed)
  • outcome (pending|succeeded|partially_succeeded|failed + reserved cancelled)
  • context (json)
  • failure_summary (json)
  • summary_counts (json)
  • started_at, completed_at

Context contract (provider-backed runs)

  • provider (string)
  • provider_connection_id (int)
  • target_scope.entra_tenant_id (string)
  • module (string; from ProviderOperationRegistry definition)

Spec 081 extension (planned)

  • Introduce outcome=blocked and store reason_code + link-only next_steps in safe context/failure summary.

State Transitions

ProviderConnection default selection

  • is_default: false -> true via makeDefault().
  • Invariant: only one default per (tenant_id, provider).

Provider-backed operation starts

  • Start surface enqueues work and creates/dedupes OperationRun.
  • If blocked (missing default connection/credential), an OperationRun is still created and finalized as blocked.