openapi: 3.0.3 info: title: TenantPilot Alerts v1 (conceptual contract) version: 0.1.0 description: | Documentation-only contract for Alerts v1. v1 is implemented via Filament (Livewire) UI surfaces, not as a public REST API. This OpenAPI file captures the intended domain operations and payload shapes to keep requirements explicit and support future API extraction. servers: - url: https://example.invalid paths: /workspaces/{workspaceId}/alerts/destinations: get: summary: List alert destinations parameters: - $ref: '#/components/parameters/WorkspaceId' responses: '200': description: OK content: application/json: schema: type: array items: $ref: '#/components/schemas/AlertDestination' post: summary: Create alert destination parameters: - $ref: '#/components/parameters/WorkspaceId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AlertDestinationCreate' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/AlertDestination' /workspaces/{workspaceId}/alerts/destinations/{destinationId}: get: summary: Get alert destination parameters: - $ref: '#/components/parameters/WorkspaceId' - $ref: '#/components/parameters/DestinationId' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/AlertDestination' patch: summary: Update alert destination parameters: - $ref: '#/components/parameters/WorkspaceId' - $ref: '#/components/parameters/DestinationId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AlertDestinationUpdate' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/AlertDestination' delete: summary: Delete alert destination parameters: - $ref: '#/components/parameters/WorkspaceId' - $ref: '#/components/parameters/DestinationId' responses: '204': description: No Content /workspaces/{workspaceId}/alerts/rules: get: summary: List alert rules parameters: - $ref: '#/components/parameters/WorkspaceId' responses: '200': description: OK content: application/json: schema: type: array items: $ref: '#/components/schemas/AlertRule' post: summary: Create alert rule parameters: - $ref: '#/components/parameters/WorkspaceId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AlertRuleCreate' responses: '201': description: Created content: application/json: schema: $ref: '#/components/schemas/AlertRule' /workspaces/{workspaceId}/alerts/rules/{ruleId}: get: summary: Get alert rule parameters: - $ref: '#/components/parameters/WorkspaceId' - $ref: '#/components/parameters/RuleId' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/AlertRule' patch: summary: Update alert rule parameters: - $ref: '#/components/parameters/WorkspaceId' - $ref: '#/components/parameters/RuleId' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AlertRuleUpdate' responses: '200': description: OK content: application/json: schema: $ref: '#/components/schemas/AlertRule' delete: summary: Delete alert rule parameters: - $ref: '#/components/parameters/WorkspaceId' - $ref: '#/components/parameters/RuleId' responses: '204': description: No Content /workspaces/{workspaceId}/alerts/deliveries: get: summary: List alert deliveries parameters: - $ref: '#/components/parameters/WorkspaceId' responses: '200': description: OK content: application/json: schema: type: array items: $ref: '#/components/schemas/AlertDelivery' components: parameters: WorkspaceId: name: workspaceId in: path required: true schema: type: integer DestinationId: name: destinationId in: path required: true schema: type: integer RuleId: name: ruleId in: path required: true schema: type: integer schemas: AlertDestination: type: object properties: id: { type: integer } workspace_id: { type: integer } name: { type: string } type: { type: string, enum: [teams_webhook, email] } is_enabled: { type: boolean } created_at: { type: string, format: date-time } updated_at: { type: string, format: date-time } required: [id, workspace_id, name, type, is_enabled] description: | Destination configuration details are intentionally not included here (secrets must not be exposed). AlertDestinationCreate: type: object properties: name: { type: string } type: { type: string, enum: [teams_webhook, email] } teams_webhook_url: { type: string, format: uri } email_recipients: type: array items: { type: string, format: email } required: [name, type] AlertDestinationUpdate: allOf: - $ref: '#/components/schemas/AlertDestinationCreate' AlertRule: type: object properties: id: { type: integer } workspace_id: { type: integer } name: { type: string } is_enabled: { type: boolean } event_type: { type: string, enum: [high_drift, compare_failed, sla_due] } minimum_severity: { type: string, enum: [low, medium, high, critical] } tenant_scope_mode: { type: string, enum: [all, allowlist] } tenant_allowlist: type: array items: { type: integer } cooldown_seconds: { type: integer, nullable: true } quiet_hours_enabled: { type: boolean } quiet_hours_start: { type: string, nullable: true, example: '22:00' } quiet_hours_end: { type: string, nullable: true, example: '06:00' } quiet_hours_timezone: { type: string, nullable: true, example: 'UTC' } destination_ids: type: array items: { type: integer } required: [id, workspace_id, name, is_enabled, event_type, minimum_severity, tenant_scope_mode] AlertRuleCreate: type: object properties: name: { type: string } is_enabled: { type: boolean } event_type: { type: string, enum: [high_drift, compare_failed, sla_due] } minimum_severity: { type: string, enum: [low, medium, high, critical] } tenant_scope_mode: { type: string, enum: [all, allowlist] } tenant_allowlist: type: array items: { type: integer } cooldown_seconds: { type: integer, nullable: true } quiet_hours_enabled: { type: boolean } quiet_hours_start: { type: string, nullable: true } quiet_hours_end: { type: string, nullable: true } quiet_hours_timezone: { type: string, nullable: true } destination_ids: type: array items: { type: integer } required: [name, event_type, minimum_severity, tenant_scope_mode, destination_ids] AlertRuleUpdate: allOf: - $ref: '#/components/schemas/AlertRuleCreate' AlertDelivery: type: object properties: id: { type: integer } workspace_id: { type: integer } tenant_id: { type: integer } alert_rule_id: { type: integer } alert_destination_id: { type: integer } fingerprint_hash: { type: string } status: { type: string, enum: [queued, deferred, sent, failed, suppressed, canceled] } send_after: { type: string, format: date-time, nullable: true } attempt_count: { type: integer } last_error_code: { type: string, nullable: true } last_error_message: { type: string, nullable: true } created_at: { type: string, format: date-time } updated_at: { type: string, format: date-time } required: [id, workspace_id, tenant_id, alert_rule_id, alert_destination_id, fingerprint_hash, status]