TenantAtlas/specs/086-retire-legacy-runs-into-operation-runs/data-model.md
2026-02-10 01:35:24 +01:00

4.4 KiB

Data Model (Spec 086)

This feature consolidates execution tracking into operation_runs while keeping legacy run tables as read-only history.

Entities

1) OperationRun (canonical)

Table: operation_runs

Purpose: Single source of truth for execution tracking: status/progress, results (counts), failures, provenance/context.

Fields (current):

  • id
  • workspace_id (FK, required)
  • tenant_id (FK, nullable)
  • user_id (FK, nullable)
  • initiator_name (string)
  • type (string; see OperationRunType registry)
  • status (string; queued|running|completed)
  • outcome (string; pending|succeeded|partially_succeeded|failed|blocked…)
  • run_identity_hash (string; deterministic hash for idempotency)
  • summary_counts (json/array; normalized counts + key metadata)
  • failure_summary (json/array; structured failures, sanitized)
  • context (json/array; provenance + inputs + target scope)
  • started_at, completed_at, created_at, updated_at

Indexes / constraints (current):

  • (workspace_id, type, created_at) and (workspace_id, created_at)
  • (tenant_id, type, created_at) and (tenant_id, created_at)
  • Partial unique indexes for active runs:
    • tenant-scoped: unique (tenant_id, run_identity_hash) where tenant_id IS NOT NULL and status IN ('queued','running')
    • workspace-scoped: unique (workspace_id, run_identity_hash) where tenant_id IS NULL and status IN ('queued','running')

Context contract (current patterns): The context JSON is used for “related links” and display. Existing keys include (non-exhaustive):

  • provider_connection_id
  • backup_schedule_id
  • backup_schedule_run_id
  • backup_set_id
  • policy_id
  • restore_run_id
  • target_scope (nested object)
  • selection and idempotency objects for bulk operations

Required additions for Spec 086 (planned):

  • New type values:
    • backup_schedule.scheduled
    • directory_role_definitions.sync
  • Scheduled backup context keys:
    • backup_schedule_id
    • scheduled_for (UTC timestamp/minute)
    • Optional backup_schedule_run_id if the legacy table remains for history during transition

2) InventorySyncRun (legacy)

Table: inventory_sync_runs

Purpose: Historical record (read-only) for pre-cutover tracking.

Key fields:

  • tenant_id
  • selection_hash
  • selection_payload (nullable)
  • status + timestamps + counters

Planned optional mapping:

  • Add nullable operation_run_id FK to enable deterministic redirect to canonical viewer when present. No backfill required.

3) EntraGroupSyncRun (legacy)

Table: entra_group_sync_runs

Purpose: Historical record (read-only) for pre-cutover group sync tracking.

Key fields:

  • tenant_id
  • selection_key, slot_key
  • status + error fields + counters

Planned optional mapping:

  • Add nullable operation_run_id FK to enable deterministic redirect when present.

4) BackupScheduleRun (legacy)

Table: backup_schedule_runs

Purpose: Historical record of backup schedule executions.

Planned behavior change:

  • Distinguish scheduled fires vs manual/retry at the OperationRun level by introducing backup_schedule.scheduled type.

Planned optional mapping:

  • Add nullable operation_run_id FK to enable deterministic redirect when present.

5) RestoreRun (domain)

Table: restore_runs

Purpose: Domain workflow record (requested items, dry-run, preview/results). Execution tracking and “View run” uses operation_runs.

Current linkage approach:

  • Canonical runs store restore_run_id in operation_runs.context (used by OperationRunLinks::related).

Enumerations / Registries

OperationRunType

Location: app/Support/OperationRunType.php

Planned additions:

  • BackupScheduleScheduled = 'backup_schedule.scheduled'
  • DirectoryRoleDefinitionsSync = 'directory_role_definitions.sync'

OperationCatalog

Location: app/Support/OperationCatalog.php

Planned additions:

  • Human label for backup_schedule.scheduled
  • Human label for directory_role_definitions.sync
  • Optional expected durations (if known)

State transitions

OperationRun

  • queuedrunningcompleted
  • outcome starts as pending, transitions to one of: succeeded, partially_succeeded, failed, blocked.

The canonical update surface is OperationRunService (dispatchOrFail, updateRun, appendFailures, incrementSummaryCounts, etc.).