openapi: 3.0.3 info: title: TenantPilot Backup Scheduling (Spec 032) version: "0.1" description: | Conceptual contract for Backup Scheduling MVP. TenantPilot uses Filament/Livewire; these endpoints describe behavior for review/testing and future API alignment. servers: - url: https://{host} variables: host: default: example.local paths: /tenants/{tenantId}/backup-schedules: get: summary: List backup schedules for a tenant parameters: - $ref: '#/components/parameters/TenantId' responses: '200': description: OK content: application/json: schema: type: array items: $ref: '#/components/schemas/BackupSchedule' post: summary: Create a backup schedule parameters: - $ref: '#/components/parameters/TenantId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BackupScheduleCreate' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/BackupSchedule' '422': description: Validation error (e.g. unknown policy_types) /tenants/{tenantId}/backup-schedules/{scheduleId}: patch: summary: Update a backup schedule parameters: - $ref: '#/components/parameters/TenantId' - $ref: '#/components/parameters/ScheduleId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BackupScheduleUpdate' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/BackupSchedule' '422': description: Validation error delete: summary: Delete (or disable) a schedule parameters: - $ref: '#/components/parameters/TenantId' - $ref: '#/components/parameters/ScheduleId' responses: '204': description: Deleted /tenants/{tenantId}/backup-schedules/{scheduleId}/run-now: post: summary: Trigger a run immediately parameters: - $ref: '#/components/parameters/TenantId' - $ref: '#/components/parameters/ScheduleId' responses: '202': description: Accepted (run created and job dispatched) content: application/json: schema: $ref: '#/components/schemas/BackupScheduleRun' /tenants/{tenantId}/backup-schedules/{scheduleId}/retry: post: summary: Create a new run as retry parameters: - $ref: '#/components/parameters/TenantId' - $ref: '#/components/parameters/ScheduleId' responses: '202': description: Accepted content: application/json: schema: $ref: '#/components/schemas/BackupScheduleRun' /tenants/{tenantId}/backup-schedules/{scheduleId}/runs: get: summary: List runs for a schedule parameters: - $ref: '#/components/parameters/TenantId' - $ref: '#/components/parameters/ScheduleId' responses: '200': description: OK content: application/json: schema: type: array items: $ref: '#/components/schemas/BackupScheduleRun' components: parameters: TenantId: name: tenantId in: path required: true schema: type: integer ScheduleId: name: scheduleId in: path required: true schema: type: integer schemas: BackupSchedule: type: object required: [id, tenant_id, name, is_enabled, timezone, frequency, time_of_day, policy_types, retention_keep_last] properties: id: { type: integer } tenant_id: { type: integer } name: { type: string } is_enabled: { type: boolean } timezone: { type: string, example: "Europe/Berlin" } frequency: { type: string, enum: [daily, weekly] } time_of_day: { type: string, example: "02:00:00" } days_of_week: type: array nullable: true items: { type: integer, minimum: 1, maximum: 7 } policy_types: type: array items: { type: string } description: Must be keys from config('tenantpilot.supported_policy_types'). include_foundations: { type: boolean } retention_keep_last: { type: integer, minimum: 1 } last_run_at: { type: string, format: date-time, nullable: true } last_run_status: { type: string, nullable: true } next_run_at: { type: string, format: date-time, nullable: true } BackupScheduleCreate: allOf: - $ref: '#/components/schemas/BackupScheduleUpdate' - type: object required: [name, timezone, frequency, time_of_day, policy_types] BackupScheduleUpdate: type: object properties: name: { type: string } is_enabled: { type: boolean } timezone: { type: string } frequency: { type: string, enum: [daily, weekly] } time_of_day: { type: string } days_of_week: type: array nullable: true items: { type: integer, minimum: 1, maximum: 7 } policy_types: type: array items: { type: string } include_foundations: { type: boolean } retention_keep_last: { type: integer, minimum: 1 } BackupScheduleRun: type: object required: [id, backup_schedule_id, tenant_id, scheduled_for, status] properties: id: { type: integer } backup_schedule_id: { type: integer } tenant_id: { type: integer } scheduled_for: { type: string, format: date-time } started_at: { type: string, format: date-time, nullable: true } finished_at: { type: string, format: date-time, nullable: true } status: { type: string, enum: [running, success, partial, failed, canceled, skipped] } summary: type: object additionalProperties: true error_code: { type: string, nullable: true } error_message: { type: string, nullable: true } backup_set_id: { type: integer, nullable: true }