TenantAtlas/specs/091-backupschedule-retention-lifecycle/data-model.md
2026-02-14 14:43:53 +01:00

1.7 KiB

Data Model — Spec 091 (BackupSchedule Retention & Lifecycle)

Entities

BackupSchedule (existing)

Table: backup_schedules

Existing fields (selected)

  • id (pk)
  • tenant_id (fk → tenants.id)
  • name (string)
  • is_enabled (bool)
  • timezone (string)
  • frequency (daily|weekly)
  • time_of_day (time)
  • days_of_week (json nullable)
  • policy_types (json)
  • include_foundations (bool)
  • retention_keep_last (int)
  • last_run_at (datetime nullable)
  • last_run_status (string nullable)
  • next_run_at (datetime nullable)
  • created_at, updated_at

New fields (this spec)

  • deleted_at (datetime nullable)

State

  • Active: deleted_at = null
  • Archived: deleted_at != null

Validation / rules (lifecycle)

  • Archive is allowed only for active schedules.
  • Restore is allowed only for archived schedules.
  • Force delete is allowed only for archived schedules.
  • Force delete is blocked if historical runs exist.

Relationships (existing)

  • tenant(): BelongsTo
  • operationRuns(): HasMany (derived from operation_runs using tenant_id + context->backup_schedule_id)

Operational Records

OperationRun (existing)

Historical runs for backup schedules are represented by operation_runs filtered via BackupSchedule::operationRuns().

Force delete constraint source

  • “Historical runs exist” is defined as: BackupSchedule::operationRuns()->exists().

Indexing / performance notes

  • Add an index supporting common list queries for schedules:
    • at minimum, backup_schedules(deleted_at) for soft delete scoping
    • consider composite index like backup_schedules(tenant_id, deleted_at) if query planner needs it

No other schema changes are required for this feature.