TenantAtlas/specs/049-backup-restore-job-orchestration/data-model.md
2026-01-11 16:54:57 +01:00

3.3 KiB

Data Model: Backup/Restore Job Orchestration (049)

This feature relies on existing “run record” models/tables and (optionally) extends them to meet the orchestration requirements.

Entities

1) RestoreRun (restore_runs)

Purpose: Run record for restore executions and dry-run/preview workflows.

Model: App\Models\RestoreRun

Key fields (existing):

  • id (PK)
  • tenant_id (FK → tenants)
  • backup_set_id (FK → backup_sets)
  • requested_by (string|null)
  • is_dry_run (bool)
  • status (string)
  • requested_items (json|null)
  • preview (json|null) — persisted preview output
  • results (json|null) — persisted execution output (may include per-item outcomes)
  • failure_reason (text|null)
  • started_at / completed_at (timestamp|null)
  • metadata (json|null)

Relationships:

  • RestoreRun belongsTo Tenant
  • RestoreRun belongsTo BackupSet

State transitions (target):

  • queued → running → succeeded|failed|partial

Validation constraints (creation/dispatch):

  • tenant-scoped access required
  • backup_set_id must belong to tenant
  • preview/dry-run must not perform writes (constitution Read/Write Separation)

2) BulkOperationRun (bulk_operation_runs)

Purpose: Run record for background operations that process many internal items, including backup-set capture-like actions.

Model: App\Models\BulkOperationRun

Key fields (existing):

  • id (PK)
  • tenant_id (FK → tenants)
  • user_id (FK → users)
  • resource (string) — e.g. policy, backup_set
  • action (string) — e.g. export, add_policies
  • status (string) — pending, running, completed, completed_with_errors, failed, aborted
  • total_items, processed_items, succeeded, failed, skipped
  • item_ids (jsonb)
  • failures (jsonb|null) — safe per-item error summaries
  • audit_log_id (FK → audit_logs|null)

Relationships:

  • BulkOperationRun belongsTo Tenant
  • BulkOperationRun belongsTo User

Recommended additions (to satisfy FR-002/FR-004 cleanly):

  • idempotency_key (string, indexed; uniqueness enforced for active statuses via partial index)
  • started_at / finished_at (timestampTz)
  • error_code (string|null)
  • error_context (jsonb|null)

State transitions (target):

  • queued → running → succeeded|failed|partial
    • pending maps to queued
    • completed_with_errors maps to partial

3) Notification Event (DB notifications)

Purpose: Persist state transitions and completion notices for the initiating user.

Storage: Laravel Notifications (DB channel).

Payload shape (target):

  • tenant_id
  • run_type (restore_run / bulk_operation_run)
  • run_id
  • status (queued/running/succeeded/failed/partial)
  • counts (optional)
  • safe_error_code + safe_error_context (optional)

Notes on “per-item outcomes” (FR-005)

  • For restore workflows, per-item outcomes can initially be stored in restore_runs.results as a structured JSON array/object keyed by internal item identifiers.
  • For bulk operations, per-item outcomes are already persisted as bulk_operation_runs.failures plus the counter columns.
  • If Phase 1 needs relational per-item tables for querying/filtering, introduce a dedicated “run item results” table per run type (Phase 2+ preferred).