openapi: 3.1.0
info:
  title: Forecars Agent API
  version: "1.0.0"
  description: >
    Superficie GET, sin captcha, para que agentes/LLMs compren y sigan
    informes de vehículos por patente en Forecars. Flujo: (1) informe
    gratis → el agente entrega al usuario el link del informe gratis en
    https://forecars.cl (formulario con captcha, no forma parte de esta API);
    (2) informe pagado → GET /agent/v1/checkout crea el link de pago. Guía en
    lenguaje natural: /ai. Mismo dominio/ensamblador que los endpoints
    humanos (cars-api, pay-api, report-api) — el contrato nunca diverge entre
    humano y agente.
  contact:
    url: https://forecars.cl/ai
externalDocs:
  description: Guía completa para agentes/LLMs (ES/EN)
  url: https://forecars.cl/ai
servers:
  # Dominio custom provisto por AgentApiStack (ver stacks/agent_api_stack.py):
  # apigw.DomainName + registro Route53 alias sobre el cert wildcard existente
  # (*.forecars.cl), reusando la hosted zone que ya usa frontend_stack. Queda
  # activo recien tras correr services/deploy/13-deploy-agent-api.command.
  - url: https://agent-api.forecars.cl
    description: Producción

paths:
  /agent/v1/checkout:
    get:
      operationId: createCheckout
      summary: Crear (o recuperar) el link de pago del informe completo
      description: >
        Idempotente por email+patente durante 24h: reintentar el mismo par no
        crea una segunda preferencia de pago ni gasta cupo. El pago lo
        completa una persona — el agente debe entregar `payment_url` al
        usuario, nunca intentar pagarlo de forma autónoma.
      parameters:
        - name: ppu
          in: query
          required: true
          schema:
            type: string
            pattern: '^([A-Za-z]{4}\d{2}|[A-Za-z]{2}\d{4})$'
            example: AB1234
        - name: email
          in: query
          required: true
          schema:
            type: string
            format: email
        - name: product_id
          in: query
          required: false
          description: Producto del catálogo. Default forecheck_1 ($6.990 CLP, 1 informe).
          schema:
            type: string
            default: forecheck_1
            enum: [forecheck_1, forecheck_3, forecheck_10]
      responses:
        "200":
          description: Checkout creado (o recuperado si ya existía, idempotente).
          content:
            application/json:
              schema:
                type: object
                required: [payment_url, report_id, price_clp, product, instructions_es]
                properties:
                  payment_url:
                    type: string
                    format: uri
                    description: Link de pago de MercadoPago. Entregar tal cual al usuario.
                  report_id:
                    type: string
                    format: uuid
                    description: Identificador del informe. Usarlo en /progress y /report.
                  price_clp: { type: integer, example: 6990 }
                  product: { type: string, example: forecheck_1 }
                  instructions_es:
                    type: string
                    description: Instrucción textual de qué hacer con el link y cómo seguir el avance.
        "400":
          description: ppu/email inválidos o product_id desconocido.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ErrorMessage" }
        "421":
          description: Límite de 5 checkouts por email alcanzado (24h).
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ErrorMessage" }
        "429":
          description: Cupo diario global de la API de agentes alcanzado.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ErrorMessage" }
        "503":
          description: Servicio en mantención (kill switch).
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ErrorMessage" }

  /agent/v1/progress:
    get:
      operationId: getProgress
      summary: Avance de generación de un informe pagado
      description: >
        Traduce el estado interno a porcentaje + mensaje + ETA (estimación,
        nunca una promesa). Cuando el estado es "publicado" incluye
        `report_url` y un hint hacia /agent/v1/report.
      parameters:
        - name: id
          in: query
          required: true
          description: report_id devuelto por /agent/v1/checkout.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Estado de avance.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ProgressPayload" }
        "400":
          description: Falta el parámetro id.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ErrorMessage" }
        "404":
          description: report_id no existe.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ErrorMessage" }

  /agent/v1/report:
    get:
      operationId: getReport
      summary: Informe completo (o avance, si aún no está publicado)
      description: >
        Si el informe ya está publicado, devuelve el informe completo sin PII
        del propietario (include_pii siempre falso hacia agentes). Si no está
        publicado, devuelve exactamente el mismo shape que /agent/v1/progress,
        para que el agente siempre reciba algo útil.
      parameters:
        - name: id
          in: query
          required: true
          description: report_id devuelto por /agent/v1/checkout.
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Informe completo (publicado) o payload de avance (no publicado aún).
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    description: Informe completo ensamblado, sin PII.
                  - $ref: "#/components/schemas/ProgressPayload"
        "400":
          description: Falta el parámetro id.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ErrorMessage" }
        "404":
          description: report_id no existe.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ErrorMessage" }

components:
  schemas:
    ErrorMessage:
      type: object
      properties:
        message:
          type: string
    ProgressPayload:
      type: object
      required: [report_id, status, percent, stage_es]
      properties:
        report_id: { type: string, format: uuid }
        status:
          type: string
          enum:
            - pago_recibido
            - recoleccion_automatica_ok
            - datos_manuales_ok
            - enriquecido
            - publicado
        percent:
          type: integer
          minimum: 0
          maximum: 100
        stage_es:
          type: string
          description: Mensaje legible del estado actual.
        eta_hint_es:
          type: string
          description: Estimación de tiempo restante (ausente cuando status=publicado).
        report_url:
          type: string
          format: uri
          description: URL humana del informe (solo cuando status=publicado).
        report_api_hint:
          type: string
          description: Hint del endpoint GET /agent/v1/report?id=... (solo cuando status=publicado).
