openapi: 3.0.3
info:
  title: Veqtrx Partner API
  version: "1.0"
  description: |
    Server-to-server affordability assessment API for banks, fintechs and
    lenders. See docs/partner-api-guide.md for full integration notes.
servers:
  - url: https://veqtrx-staging-backend.onrender.com
    description: Staging
  - url: https://veqtrx-backend.onrender.com
    description: Production

security:
  - PartnerKey: []

paths:
  /api/partner/v1/health:
    get:
      summary: Health check
      security: []
      responses:
        "200":
          description: Service is alive
          content:
            application/json:
              schema:
                type: object
                properties:
                  status: { type: string, example: ok }
                  version: { type: string, example: "1.0" }

  /api/partner/v1/assess:
    post:
      summary: Run an affordability assessment
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AssessmentRequest"
      responses:
        "200":
          description: Assessment complete
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AssessmentResponse"
        "400":
          $ref: "#/components/responses/ValidationError"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          $ref: "#/components/responses/QuotaExceeded"

  /api/partner/v1/assessment/{assessment_id}:
    get:
      summary: Retrieve a previously created assessment
      parameters:
        - in: path
          name: assessment_id
          required: true
          schema: { type: string }
      responses:
        "200":
          description: Assessment found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AssessmentResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

  /api/partner/v1/usage:
    get:
      summary: Current quota / usage snapshot
      responses:
        "200":
          description: Usage info
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UsageResponse"
        "401":
          $ref: "#/components/responses/Unauthorized"

components:
  securitySchemes:
    PartnerKey:
      type: apiKey
      in: header
      name: X-Partner-Key

  responses:
    Unauthorized:
      description: Missing / invalid / disabled API key
      content:
        application/json:
          schema: { $ref: "#/components/schemas/Error" }
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema: { $ref: "#/components/schemas/Error" }
    QuotaExceeded:
      description: Monthly quota exhausted
      content:
        application/json:
          schema: { $ref: "#/components/schemas/Error" }
    ValidationError:
      description: Request validation failed
      content:
        application/json:
          schema: { $ref: "#/components/schemas/Error" }

  schemas:
    Error:
      type: object
      required: [detail]
      properties:
        detail: { type: string }

    Transaction:
      type: object
      required: [date, amount, merchant_name]
      properties:
        date: { type: string, format: date }
        amount: { type: number, description: "Positive = spending, negative = income/refund" }
        merchant_name: { type: string, minLength: 1, maxLength: 200 }
        description: { type: string, nullable: true }
        category_hint: { type: string, nullable: true }
        account_id: { type: string, default: default }

    Circumstances:
      type: object
      required: [housing, household_adults]
      properties:
        housing:
          type: string
          enum: [renter, homeowner_mortgage, homeowner_outright, social_housing]
        household_adults: { type: integer, minimum: 1, maximum: 10 }
        children_u16: { type: integer, minimum: 0, maximum: 10, default: 0 }
        children_16_18: { type: integer, minimum: 0, maximum: 10, default: 0 }
        vulnerabilities:
          type: array
          items: { type: string }
          default: []

    AssessmentRequest:
      type: object
      required: [customer_ref, transactions, circumstances]
      properties:
        customer_ref: { type: string, minLength: 1, maxLength: 128 }
        partner_ref: { type: string, maxLength: 128, nullable: true }
        transactions:
          type: array
          minItems: 1
          maxItems: 10000
          items: { $ref: "#/components/schemas/Transaction" }
        circumstances: { $ref: "#/components/schemas/Circumstances" }
        declared_income: { type: number, nullable: true }
        callback_url: { type: string, nullable: true }

    RiskFlag:
      type: object
      properties:
        type: { type: string }
        severity: { type: string }
        description: { type: string }
        monthly_spend: { type: number, nullable: true }
        evidence: { type: string, nullable: true }

    AssessmentResponse:
      type: object
      properties:
        assessment_id: { type: string }
        partner_ref: { type: string, nullable: true }
        customer_ref: { type: string }
        created_at: { type: string, format: date-time }
        monthly_income: { type: number }
        monthly_expenditure: { type: number }
        disposable_income: { type: number }
        affordable_amount: { type: number }
        affordability_score: { type: integer, minimum: 0, maximum: 100 }
        categories:
          type: object
          additionalProperties: { type: number }
        fca_compliant: { type: boolean }
        risk_flags:
          type: array
          items: { $ref: "#/components/schemas/RiskFlag" }
        vulnerability_flags:
          type: array
          items: { $ref: "#/components/schemas/RiskFlag" }
        transactions_analyzed: { type: integer }
        confidence_score: { type: number }
        months_analyzed: { type: number }
        processing_ms: { type: integer }

    UsageResponse:
      type: object
      properties:
        partner_id: { type: string }
        tier: { type: string }
        monthly_quota: { type: integer }
        current_usage: { type: integer }
        remaining: { type: integer }
        reset_date: { type: string }
