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]
