openapi: 3.1.0
info:
  title: GovMachine — API de Editais
  version: "1.0.0"
  description: |
    API pública, somente-leitura, para os seus próprios sistemas consultarem os
    editais que a sua empresa acompanha na GovMachine — em triagem, em análise,
    em precificação, prontos, descartados ou expirados.

    A autenticação é por chave de API por empresa (prefixo `gmk_`), gerada em
    Configurações → API de Editais dentro do app. Cada chave resolve para uma
    única empresa; o escopo de dados é garantido no banco por Row-Level Security,
    então uma chave nunca enxerga editais de outra empresa.
  contact:
    name: GovMachine
    url: https://govmachine.com.br/developers
servers:
  - url: https://app.govmachine.com.br
    description: Produção
security:
  - BearerApiKey: []
  - ApiKeyHeader: []
paths:
  /api/v1/editais:
    get:
      summary: Lista os editais da empresa
      description: |
        Retorna os editais da empresa autenticada, do mais recente para o mais
        antigo, com paginação. O escopo de empresa vem inteiramente da chave de API.
      operationId: listEditais
      parameters:
        - name: status
          in: query
          required: false
          description: |
            Filtro por status do ciclo de vida, separado por vírgula
            (ex.: `analysis,pricing`). Um status desconhecido retorna 400.
            Sem o parâmetro, todos os status são incluídos.
          schema:
            type: string
            example: analysis,pricing
        - name: limit
          in: query
          required: false
          description: Tamanho da página. Padrão 50, máximo 200.
          schema:
            type: integer
            default: 50
            maximum: 200
            minimum: 1
        - name: offset
          in: query
          required: false
          description: Deslocamento para paginação.
          schema:
            type: integer
            default: 0
            minimum: 0
      responses:
        "200":
          description: Página de editais.
          content:
            application/json:
              schema:
                type: object
                required: [editais, count, total, limit, offset]
                properties:
                  editais:
                    type: array
                    items:
                      $ref: "#/components/schemas/Edital"
                  count:
                    type: integer
                    description: Quantidade de itens nesta página.
                  total:
                    type: integer
                    description: Total de editais que casam com o filtro.
                  limit:
                    type: integer
                  offset:
                    type: integer
        "400":
          $ref: "#/components/responses/InvalidStatus"
        "401":
          $ref: "#/components/responses/Unauthorized"
  /api/v1/editais/{id}:
    get:
      summary: Detalha um edital
      description: |
        Retorna um único edital pelo seu `id`. Um `id` desconhecido para a empresa
        retorna 404 (por RLS, um id de outra empresa é indistinguível de inexistente).
      operationId: getEdital
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: ID do edital (campo `id` do objeto Edital).
      responses:
        "200":
          description: O edital.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Edital"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          description: Não encontrado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/editais/{id}/analysis:
    get:
      summary: Análise estruturada de um edital
      description: |
        Retorna a camada estruturada que a GovMachine já extraiu e avaliou do
        edital — pensada para ser consumida por sistemas e agentes de IA da
        própria empresa, em vez de reprocessarem o PDF do edital.

        Inclui: identidade, panorama (`overview`), requisitos de habilitação
        exigidos, itens e lotes, alertas de risco jurídico (com tese legal),
        investimento/garantias e o veredito de participação. Seções vazias são
        honestas: um edital só com triagem (`analysis_level: simple`) ainda não
        teve a projeção de requisitos/itens construída.
      operationId: getEditalAnalysis
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: ID do edital (campo `id` do objeto Edital).
      responses:
        "200":
          description: A análise estruturada.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EditalAnalysis"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          description: Não encontrado.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
components:
  securitySchemes:
    BearerApiKey:
      type: http
      scheme: bearer
      description: "Cabeçalho `Authorization: Bearer gmk_...`"
    ApiKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key
      description: "Alternativa ao Bearer: `X-API-Key: gmk_...`"
  responses:
    Unauthorized:
      description: Chave ausente ou inválida.
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    InvalidStatus:
      description: Status desconhecido no filtro.
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: string
                example: invalid_status
              detail:
                type: string
                example: "unknown status: foo"
  schemas:
    Edital:
      type: object
      required:
        - id
        - pncp_id
        - status
        - participation_confirmed
        - created_at
        - updated_at
      properties:
        id:
          type: string
          description: ID do edital para esta empresa (use em GET /api/v1/editais/{id}).
        pncp_id:
          type: string
          description: Identificador PNCP (cnpj-ano-sequencial).
        orgao:
          type: string
          description: Órgão comprador.
        objeto:
          type: string
          description: Objeto da contratação.
        numero:
          type: string
          description: Número do edital/processo.
        modalidade:
          type: string
          description: Modalidade (ex.: Pregão Eletrônico).
        uf:
          type: string
          description: UF do órgão.
        valor_estimado:
          type: number
          format: double
          description: Valor estimado (BRL).
        data_sessao:
          type: string
          format: date-time
          description: Data da sessão pública.
        pncp_url:
          type: string
          description: Link para o edital no portal de origem.
        status:
          type: string
          description: Fase da empresa neste edital.
          enum: [screening, analysis, pricing, ready, discarded, expired]
        participation_confirmed:
          type: boolean
          description: Se a empresa confirmou participação.
        discard_reason:
          type: string
          description: Motivo do descarte (quando status = discarded).
        committed_at:
          type: string
          format: date-time
          description: Quando a participação foi confirmada.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
    EditalAnalysis:
      type: object
      description: Camada estruturada extraída e avaliada do edital.
      required: [id, pncp_id, status, analysis_level, analyzed, verdict, requirements, items, alerts]
      properties:
        id:
          type: string
        pncp_id:
          type: string
        orgao:
          type: string
        objeto:
          type: string
        numero:
          type: string
        modalidade:
          type: string
        uf:
          type: string
        valor_estimado:
          type: number
          format: double
        data_sessao:
          type: string
          format: date-time
        pncp_url:
          type: string
        status:
          type: string
          enum: [screening, analysis, pricing, ready, discarded, expired]
        analysis_level:
          type: string
          description: Profundidade da análise já executada.
          enum: [none, simple, medium, deep]
        analyzed:
          type: boolean
          description: "false quando analysis_level = none."
        verdict:
          type: object
          description: Veredito de participação (vazio até uma avaliação rodar).
          properties:
            recommendation:
              type: string
              enum: [participar, cautela, nao_recomendado]
            reason:
              type: string
            summary:
              type: string
            bullets:
              type: array
              items:
                type: string
        overview:
          type: object
          description: |
            Panorama estruturado (nível simple): identidade, valor, logística,
            participação, prazos, lotes. Campos como orgao_licitante,
            lei_aplicavel, valor_estimado, is_srp, exclusivo_me_epp,
            prazo_impugnacao, locais_entrega, restricoes_participacao,
            atestado_capacidade_exigido, visita_tecnica_obrigatoria. Ausente
            quando nenhuma avaliação simple rodou.
          additionalProperties: true
        requirements:
          type: array
          description: Requisitos de habilitação exigidos pelo edital.
          items:
            type: object
            properties:
              category:
                type: string
                enum:
                  - habilitacao_juridica
                  - qualificacao_tecnica
                  - qualificacao_economica
                  - regularidade_fiscal
                  - regularidade_trabalhista
                  - declaracoes
                  - amostras
                  - visita_tecnica
                  - certificacoes
                  - garantias
                  - programa_integridade
                  - outros
              title:
                type: string
              required:
                type: string
                description: O que o edital exige.
              current:
                type: string
                description: Estado atual da empresa (quando avaliado).
              status:
                type: string
                enum: [red, yellow, green]
              ai_notes:
                type: string
              metadata:
                type: object
                description: Detalhe semiestruturado (CCT, pisos, entrega, gatilho de PI…).
                additionalProperties: true
        items:
          type: array
          description: Itens e lotes do edital (dados de catálogo do PNCP + recomendação de IA).
          items:
            type: object
            properties:
              numero_item:
                type: integer
              descricao:
                type: string
              quantidade:
                type: number
              unidade_medida:
                type: string
              valor_unitario_estimado:
                type: number
              valor_total:
                type: number
              material_ou_servico:
                type: string
                enum: [M, S]
              numero_lote:
                type: integer
                nullable: true
              criterio_julgamento_nome:
                type: string
              ai_selected:
                type: boolean
              ai_reasoning:
                type: string
              ai_confidence:
                type: number
        alerts:
          type: array
          description: Alertas de risco jurídico e oportunidades (somente publicados).
          items:
            type: object
            properties:
              type:
                type: string
                enum: [risk, opportunity, info]
              severity:
                type: string
                enum: [critical, high, medium, low]
              title:
                type: string
              description:
                type: string
              action_type:
                type: string
                enum: [impugnacao, esclarecimento, recurso, contrarrazao, none]
              legal_thesis:
                type: string
                nullable: true
        pricing:
          type: object
          nullable: true
          description: Investimento e garantias (ausente até rodar avaliação medium).
          properties:
            investimento_total:
              type: number
            garantia_proposta:
              type: number
            garantia_contratual:
              type: number
            margem_min:
              type: number
            margem_max:
              type: number
            risco_pagamento:
              type: string
              enum: ["", baixo, medio, alto, critico, desconhecido]
            is_srp:
              type: boolean
            sigiloso:
              type: boolean
        orgao_report:
          type: object
          nullable: true
          description: Confiabilidade de pagamento do órgão (dado público de transparência).
          properties:
            payment_risk:
              type: string
            status:
              type: string
        operational:
          type: object
          nullable: true
          description: Logística de entrega/execução (prazo, faseamento, locais).
          additionalProperties: true
    Error:
      type: object
      properties:
        error:
          type: string
          example: not found
