TenantAtlas/specs/091-backupschedule-retention-lifecycle/contracts/backup-schedule-lifecycle-v1.openapi.yaml
ahmido 1c098441aa feat(spec-091): BackupSchedule lifecycle + create-CTA placement rule (#109)
Implements Spec 091 “BackupSchedule Retention & Lifecycle (Archive/Restore/Force Delete)”.

- BackupSchedule lifecycle:
  - Archive (soft delete) with confirmation; restores via Restore action; Force delete with confirmation and strict gating.
  - Force delete blocked when historical runs exist.
  - Archived schedules never dispatch/execute (dispatcher + job guard).
  - Audit events emitted for archive/restore/force delete.
  - RBAC UX semantics preserved (non-member hidden/404; member w/o capability disabled + server-side 403).

- Filament UX contract update:
  - Create CTA placement rule across create-enabled list pages:
    - Empty list: only large centered empty-state Create CTA.
    - Non-empty list: only header Create action.
  - Tests added/updated to enforce the rule.

Verification:
- `vendor/bin/sail bin pint --dirty`
- Focused tests: BackupScheduling + RBAC enforcement + EmptyState CTAs + Create CTA placement

Notes:
- Filament v5 / Livewire v4 compliant.
- Manual quickstart verification in `specs/091-backupschedule-retention-lifecycle/quickstart.md` remains to be checked (T031).

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #109
2026-02-14 13:46:06 +00:00

136 lines
3.4 KiB
YAML

openapi: 3.1.0
info:
title: TenantPilot Internal UI Contracts
version: 1.0.0
description: |
This OpenAPI document is used as a schema bundle for internal (non-HTTP) contracts.
Spec 091 does not introduce public HTTP endpoints; Filament/Livewire actions are
executed via framework internals. We still publish schemas here so the feature
has explicit, reviewable contracts under `specs/.../contracts/`.
paths: {}
components:
schemas:
BackupScheduleLifecycleAction:
type: string
description: Stable identifiers for lifecycle mutations.
enum:
- backup_schedule.archived
- backup_schedule.restored
- backup_schedule.force_deleted
BackupScheduleLifecycleGuard:
type: object
additionalProperties: false
required:
- can_archive
- can_restore
- can_force_delete
- force_delete_blocked_reason
properties:
can_archive:
type: boolean
can_restore:
type: boolean
can_force_delete:
type: boolean
force_delete_blocked_reason:
type: string
nullable: true
description: Human-friendly reason shown when force delete is blocked.
examples:
- Historical runs exist for this schedule.
BackupScheduleLifecycleMutation:
type: object
additionalProperties: false
required:
- action
- tenant_id
- backup_schedule_id
properties:
action:
$ref: '#/components/schemas/BackupScheduleLifecycleAction'
tenant_id:
type: integer
backup_schedule_id:
type: integer
actor_id:
type: integer
nullable: true
occurred_at:
type: string
format: date-time
nullable: true
metadata:
type: object
additionalProperties: true
description: Sanitized metadata payload.
RbacDecision:
type: object
additionalProperties: false
required:
- is_member
- has_capability
- outcome
properties:
is_member:
type: boolean
has_capability:
type: boolean
outcome:
type: string
description: Server-side outcome required by RBAC-UX.
enum:
- allow
- deny_as_not_found
- deny_as_forbidden
AuditLogEntry:
type: object
additionalProperties: false
required:
- action
- status
- recorded_at
properties:
tenant_id:
type: integer
nullable: true
workspace_id:
type: integer
nullable: true
actor_id:
type: integer
nullable: true
actor_email:
type: string
nullable: true
actor_name:
type: string
nullable: true
action:
type: string
description: Stable action id string.
examples:
- backup_schedule.archived
resource_type:
type: string
nullable: true
resource_id:
type: string
nullable: true
status:
type: string
enum: [success]
metadata:
type: object
description: Sanitized metadata payload.
additionalProperties: true
recorded_at:
type: string
format: date-time