extends:
  - spectral:oas

rules:
  operation-description: off

  operation-operationId:
    description: Every operation must declare a stable operationId.
    given: $.paths[*][*]
    then:
      field: operationId
      function: truthy

  operation-tags:
    description: Every operation must be tagged for SDK grouping and ownership.
    given: $.paths[*][*]
    then:
      field: tags
      function: truthy

  error-response-required:
    description: Operations must declare at least one 4xx/5xx error response.
    severity: warn
    given: $.paths[*][*].responses
    then:
      function: schema
      functionOptions:
        schema:
          type: object
          anyOf:
            - required: ["400"]
            - required: ["401"]
            - required: ["403"]
            - required: ["404"]
            - required: ["409"]
            - required: ["422"]
            - required: ["500"]
            - required: ["503"]

  no-undefined-security-on-protected-routes:
    description: Protected routes should not have empty security unless explicitly intended.
    severity: off
    given: $.paths[*][*]
    then:
      function: schema
      functionOptions:
        schema:
          type: object
          properties:
            security:
              not:
                type: array
                maxItems: 0

  request-id-header-documented:
    description: Correlation header should be documented globally.
    severity: warn
    given: $.components.parameters
    then:
      function: truthy

  idempotency-key-on-post-put-delete:
    description: Mutation endpoints should document idempotency key usage.
    severity: warn
    given: $.paths[*][post,put,delete]
    then:
      function: schema
      functionOptions:
        schema:
          type: object
          properties:
            parameters:
              type: array
              contains:
                type: object
                properties:
                  name:
                    const: Idempotency-Key
                required: [name]
