openapi: 3.1.0

info:
  title: Chassi de Controles Internos — API
  version: 0.1.0
  summary: Catálogo regulatório versionado e colaborativo para o sistema financeiro brasileiro.
  description: |
    A API do Chassi de Controles Internos expõe um catálogo curado de **normas, processos,
    riscos e seus vínculos qualificados** aplicáveis a entidades reguladas pelo CMN, BCB,
    CVM, CNSP, SUSEP, PREVIC, COAF, ANPD e auto-reguladores (B3, BSM, ANBIMA).

    ## Filosofia

    A API é **leve e idempotente**. O consumidor passa atributos categóricos da entidade
    dele (tipo, segmento, atividades) e recebe a fatia aplicável. **Nenhum dado do
    consumidor é armazenado.** Não há multi-tenancy, não há perfil de cliente, não há
    histórico de consultas pessoais.

    O valor está no **catálogo curado e versionado** — colaborativo, mantido pela
    comunidade que o usa.

    ## Modalidades de consumo

    1. **API REST** (este documento) — chamadas idempotentes, cacheáveis
    2. **Snapshot baixável** — `GET /snapshot/json` ou `GET /snapshot/sqlite`
    3. **SDK** (em desenvolvimento) — pacotes `chassi-sdk` (npm e PyPI)

    ## Acesso

    A API é **aberta e sem autenticação** — dados públicos, leitura apenas. Pode
    chamar diretamente do navegador, do `curl`, do seu código.

    Se você prefere não depender do serviço hospedado, baixe o snapshot
    `chassi.json` ou `chassi.sqlite` e rode contra ele localmente — o conteúdo é
    idêntico.

    ## Licenciamento

    - **Código** desta API e do schema: MIT License
    - **Conteúdo do catálogo** (normas, processos, riscos, vínculos): CC BY 4.0

    Veja o repositório no GitHub para os arquivos de licença e o guia de contribuição.

    ## Versionamento

    O catálogo é versionado em SemVer. A URL contém `/v1` que se refere ao **contrato
    da API**, não à versão do catálogo. Para descobrir a versão atual do conteúdo,
    consulte `GET /chassi/version`.

  contact:
    name: Walter C. Neto
    url: https://waltercneto.github.io/
    email: walter.correa.neto@gmail.com
  license:
    name: MIT (code) + CC BY 4.0 (data)
    url: https://github.com/walterCNeto/ChassiRO

servers:
  - url: https://chassiro-api.fly.dev/v1
    description: Produção
  - url: http://localhost:8000/v1
    description: Local (FastAPI rodando em sua máquina)

tags:
  - name: Catálogos
    description: Catálogos de domínio (reguladores, tipos de entidade, segmentos, atividades).
  - name: Normas
    description: Catálogo de normas regulatórias e seus artigos.
  - name: Processos
    description: Hierarquia de processos do chassi (P0 → P4).
  - name: Riscos
    description: Hierarquia de riscos do chassi (R0 → R4).
  - name: Vínculos
    description: Relações qualificadas norma↔processo, norma↔risco, processo↔risco.
  - name: Instância
    description: Filtragem do chassi pela fatia aplicável a uma entidade.
  - name: Chassi
    description: Versão, changelog e snapshot do catálogo.

paths:
  # =========================================================
  # CATÁLOGOS
  # =========================================================
  /reguladores:
    get:
      tags: [Catálogos]
      summary: Lista reguladores
      description: Retorna o catálogo completo de reguladores e auto-reguladores.
      responses:
        '200':
          description: Lista de reguladores
          content:
            application/json:
              schema:
                type: array
                items: { $ref: '#/components/schemas/Regulador' }

  /reguladores/{id}:
    get:
      tags: [Catálogos]
      summary: Detalhe de um regulador
      parameters:
        - $ref: '#/components/parameters/ReguladorId'
      responses:
        '200':
          description: Regulador
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Regulador' }
        '404':
          $ref: '#/components/responses/NotFound'

  /tipos-entidade:
    get:
      tags: [Catálogos]
      summary: Lista tipos de entidade
      parameters:
        - in: query
          name: grupo
          schema:
            type: string
            enum: [bancario, mercado_capitais, seguros, previdencia, capitalizacao, outros, conglomerado]
      responses:
        '200':
          description: Lista de tipos
          content:
            application/json:
              schema:
                type: array
                items: { $ref: '#/components/schemas/TipoEntidade' }

  /tipos-entidade/{id}:
    get:
      tags: [Catálogos]
      summary: Detalhe de um tipo de entidade
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string, example: ENT_BANCO_MULTIPLO }
      responses:
        '200':
          description: Tipo de entidade
          content:
            application/json:
              schema: { $ref: '#/components/schemas/TipoEntidade' }
        '404':
          $ref: '#/components/responses/NotFound'

  /segmentos:
    get:
      tags: [Catálogos]
      summary: Lista segmentos prudenciais
      parameters:
        - in: query
          name: regulador_id
          schema: { type: string }
      responses:
        '200':
          description: Lista de segmentos
          content:
            application/json:
              schema:
                type: array
                items: { $ref: '#/components/schemas/Segmento' }

  /atividades:
    get:
      tags: [Catálogos]
      summary: Lista atividades canônicas
      parameters:
        - in: query
          name: grupo
          schema: { type: string, example: cambio }
      responses:
        '200':
          description: Lista de atividades
          content:
            application/json:
              schema:
                type: array
                items: { $ref: '#/components/schemas/Atividade' }

  # =========================================================
  # NORMAS
  # =========================================================
  /normas:
    get:
      tags: [Normas]
      summary: Lista normas com filtros
      description: |
        Suporta filtragem combinada por regulador, tipo, status, tipo de entidade,
        segmento e atividade. Combinação de filtros é **AND**.

        Atenção: este endpoint não é o mesmo que `/instancia`. Aqui você consulta
        sob critérios livres; em `/instancia` você passa o cartão completo da
        entidade e recebe a fatia integrada.
      parameters:
        - in: query
          name: regulador_id
          schema: { type: string }
        - in: query
          name: tipo
          schema:
            type: string
            enum:
              [lei, lei_complementar, decreto, decreto_lei, res_cmn, res_bcb,
               circ_bcb, carta_circ_bcb, instr_bcb, res_cvm, instr_cvm, res_cnsp,
               circ_susep, res_cnpc, instr_previc, res_coaf, res_anpd,
               codigo_anbima, oficio_b3, oficio_bsm, outros]
        - in: query
          name: status
          schema:
            type: string
            enum: [vigente, revogada, parcialmente_revogada, em_consulta, revogada_tacita]
            default: vigente
        - in: query
          name: aplica_a
          description: Filtra normas aplicáveis a determinado tipo de entidade.
          schema: { type: string, example: ENT_BANCO_MULTIPLO }
        - in: query
          name: segmento
          description: Filtra normas aplicáveis ao segmento.
          schema: { type: string, example: S2 }
        - in: query
          name: atividade
          description: Filtra normas aplicáveis à atividade canônica.
          schema: { type: string, example: ATV_CAMBIO_COMERCIAL }
        - in: query
          name: limit
          schema: { type: integer, default: 100, maximum: 500 }
        - in: query
          name: offset
          schema: { type: integer, default: 0 }
      responses:
        '200':
          description: Lista paginada de normas
          content:
            application/json:
              schema:
                type: object
                properties:
                  total: { type: integer }
                  limit: { type: integer }
                  offset: { type: integer }
                  data:
                    type: array
                    items: { $ref: '#/components/schemas/Norma' }

  /normas/{id}:
    get:
      tags: [Normas]
      summary: Detalhe de uma norma
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string, example: RES_CMN_4557_17 }
      responses:
        '200':
          description: Norma com aplicabilidade consolidada
          content:
            application/json:
              schema: { $ref: '#/components/schemas/NormaDetalhe' }
        '404':
          $ref: '#/components/responses/NotFound'

  /normas/{id}/artigos:
    get:
      tags: [Normas]
      summary: Artigos de uma norma
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Lista de artigos
          content:
            application/json:
              schema:
                type: array
                items: { $ref: '#/components/schemas/Artigo' }

  # =========================================================
  # PROCESSOS
  # =========================================================
  /processos:
    get:
      tags: [Processos]
      summary: Lista processos da hierarquia
      parameters:
        - in: query
          name: nucleo
          schema:
            type: string
            enum: [U, B, MC, S, P, C, CG]
            description: U=universal, B=bancário, MC=mercado capitais, S=seguros, P=previdência, C=capitalização, CG=conglomerado
        - in: query
          name: nivel
          schema: { type: integer, minimum: 0, maximum: 4 }
        - in: query
          name: nivel_max
          schema: { type: integer, minimum: 0, maximum: 4 }
        - in: query
          name: parent_id
          schema: { type: string }
      responses:
        '200':
          description: Lista de processos
          content:
            application/json:
              schema:
                type: array
                items: { $ref: '#/components/schemas/Processo' }

  /processos/{id}:
    get:
      tags: [Processos]
      summary: Detalhe de um processo
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string, example: P0.B.2 }
      responses:
        '200':
          description: Processo com filhos imediatos e normas vinculadas
          content:
            application/json:
              schema: { $ref: '#/components/schemas/ProcessoDetalhe' }
        '404':
          $ref: '#/components/responses/NotFound'

  # =========================================================
  # RISCOS
  # =========================================================
  /riscos:
    get:
      tags: [Riscos]
      summary: Lista riscos da hierarquia
      parameters:
        - in: query
          name: nucleo
          schema:
            type: string
            enum: [U, B, MC, S, P, C, CG]
        - in: query
          name: nivel
          schema: { type: integer, minimum: 0, maximum: 4 }
        - in: query
          name: parent_id
          schema: { type: string }
      responses:
        '200':
          description: Lista de riscos
          content:
            application/json:
              schema:
                type: array
                items: { $ref: '#/components/schemas/Risco' }

  /riscos/{id}:
    get:
      tags: [Riscos]
      summary: Detalhe de um risco
      parameters:
        - in: path
          name: id
          required: true
          schema: { type: string, example: R0.U.4 }
      responses:
        '200':
          description: Risco com filhos imediatos e processos vinculados
          content:
            application/json:
              schema: { $ref: '#/components/schemas/RiscoDetalhe' }

  # =========================================================
  # VÍNCULOS
  # =========================================================
  /vinculos/norma-processo:
    get:
      tags: [Vínculos]
      summary: Vínculos norma → processo
      parameters:
        - in: query
          name: norma_id
          schema: { type: string }
        - in: query
          name: processo_id
          schema: { type: string }
        - in: query
          name: tipo_vinculo
          schema:
            type: string
            enum: [primaria, secundaria, informativa]
      responses:
        '200':
          description: Lista de vínculos
          content:
            application/json:
              schema:
                type: array
                items: { $ref: '#/components/schemas/VinculoNormaProcesso' }

  /vinculos/processo-risco:
    get:
      tags: [Vínculos]
      summary: Matriz processo × risco
      parameters:
        - in: query
          name: processo_id
          schema: { type: string }
        - in: query
          name: risco_id
          schema: { type: string }
        - in: query
          name: materialidade_min
          schema: { type: integer, minimum: 1, maximum: 5 }
      responses:
        '200':
          description: Lista de pares com materialidade default
          content:
            application/json:
              schema:
                type: array
                items: { $ref: '#/components/schemas/VinculoProcessoRisco' }

  # =========================================================
  # INSTÂNCIA
  # =========================================================
  /instancia:
    get:
      tags: [Instância]
      summary: Calcula a fatia aplicável a uma entidade
      description: |
        Recebe o cartão categórico da entidade (tipo, segmento, atividades) e
        retorna o conjunto integrado de normas, processos relevantes e matriz
        P×R aplicáveis.

        **Importante:** os atributos passados são categóricos (labels do
        catálogo). Não passe CNPJ, razão social ou qualquer dado identificador
        do cliente — eles seriam ignorados.
      parameters:
        - in: query
          name: tipo_entidade
          required: true
          schema: { type: string, example: ENT_BANCO_MULTIPLO }
        - in: query
          name: segmento
          required: false
          schema: { type: string, example: S2 }
        - in: query
          name: atividades
          description: Lista de atividades separadas por vírgula.
          required: false
          schema:
            type: string
            example: ATV_DEPOSITO_VISTA,ATV_CREDITO_PJ,ATV_CAMBIO_COMERCIAL
      responses:
        '200':
          description: Fatia integrada do chassi
          content:
            application/json:
              schema: { $ref: '#/components/schemas/Instancia' }

  # =========================================================
  # CHASSI / VERSIONAMENTO
  # =========================================================
  /chassi/version:
    get:
      tags: [Chassi]
      summary: Versão atual do catálogo
      description: |
        Retorna a versão atualmente publicada do conteúdo do chassi (não da API).
      responses:
        '200':
          description: Metadados da versão
          content:
            application/json:
              schema: { $ref: '#/components/schemas/ChassiVersao' }

  /chassi/changelog:
    get:
      tags: [Chassi]
      summary: Histórico de mudanças do catálogo
      parameters:
        - in: query
          name: since_version
          schema: { type: string, example: 0.1.0 }
      responses:
        '200':
          description: Lista de entradas do changelog
          content:
            application/json:
              schema:
                type: array
                items: { $ref: '#/components/schemas/ChangelogEntry' }

  /snapshot/json:
    get:
      tags: [Chassi]
      summary: Download do snapshot completo em JSON
      description: |
        Retorna o catálogo inteiro como JSON. Usado por consumidores que preferem
        operação offline (sem dependência operacional do serviço).
      responses:
        '200':
          description: Snapshot JSON
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true

  /snapshot/sqlite:
    get:
      tags: [Chassi]
      summary: Download do snapshot completo em SQLite
      description: |
        Retorna um arquivo SQLite autocontido com o catálogo.
        Mesmo conteúdo do snapshot JSON, em formato indexado.
      responses:
        '200':
          description: Arquivo SQLite
          content:
            application/octet-stream:
              schema:
                type: string
                format: binary

# =========================================================
# COMPONENTES
# =========================================================
components:
  parameters:
    ReguladorId:
      in: path
      name: id
      required: true
      schema: { type: string, example: REG_BCB }

  responses:
    NotFound:
      description: Recurso não encontrado
      content:
        application/json:
          schema: { $ref: '#/components/schemas/Erro' }

  schemas:
    Erro:
      type: object
      properties:
        error: { type: string }
        message: { type: string }
        request_id: { type: string }

    Regulador:
      type: object
      properties:
        id: { type: string, example: REG_BCB }
        nome: { type: string, example: Banco Central do Brasil }
        natureza:
          type: string
          enum: [normativo_superior, normativo_supervisao, auto_regulador, associativo, uif, autoridade_dados]
        instrumento: { type: string, example: 'Resolução BCB / Circular / Carta-Circular' }
        descricao: { type: string }
        site: { type: string, format: uri }

    TipoEntidade:
      type: object
      properties:
        id: { type: string, example: ENT_BANCO_MULTIPLO }
        nome: { type: string, example: Banco Múltiplo }
        grupo:
          type: string
          enum: [bancario, mercado_capitais, seguros, previdencia, capitalizacao, outros, conglomerado]
        descricao: { type: string }
        reguladores:
          type: array
          items:
            type: object
            properties:
              regulador_id: { type: string }
              papel:
                type: string
                enum: [primario, secundario]

    Segmento:
      type: object
      properties:
        id: { type: string, example: S2 }
        regulador_id: { type: string }
        nome: { type: string }
        descricao: { type: string }
        ordem: { type: integer }

    Atividade:
      type: object
      properties:
        id: { type: string, example: ATV_CAMBIO_COMERCIAL }
        nome: { type: string }
        grupo: { type: string }
        descricao: { type: string }

    Norma:
      type: object
      properties:
        id: { type: string, example: RES_CMN_4557_17 }
        tipo: { type: string }
        numero: { type: string, example: '4.557' }
        ano: { type: integer, example: 2017 }
        regulador_id: { type: string }
        titulo: { type: string }
        ementa: { type: string }
        status: { type: string }
        vigencia_inicio: { type: string, format: date }
        vigencia_fim: { type: string, format: date, nullable: true }

    NormaDetalhe:
      allOf:
        - $ref: '#/components/schemas/Norma'
        - type: object
          properties:
            artigos:
              type: array
              items: { $ref: '#/components/schemas/Artigo' }
            aplicabilidade:
              type: object
              properties:
                tipos_entidade: { type: array, items: { type: string } }
                segmentos: { type: array, items: { type: string } }
                atividades: { type: array, items: { type: string } }
            processos_vinculados:
              type: array
              items: { $ref: '#/components/schemas/VinculoNormaProcesso' }
            riscos_vinculados:
              type: array
              items: { $ref: '#/components/schemas/VinculoNormaRisco' }

    Artigo:
      type: object
      properties:
        numero: { type: string, example: '38' }
        secao: { type: string, nullable: true }
        tema: { type: string }
        descricao: { type: string, nullable: true }

    Processo:
      type: object
      properties:
        id: { type: string, example: P0.B.2 }
        codigo: { type: string }
        nome: { type: string }
        nivel: { type: integer, minimum: 0, maximum: 4 }
        nucleo:
          type: string
          enum: [U, B, MC, S, P, C, CG]
        parent_id: { type: string, nullable: true }
        descricao: { type: string, nullable: true }
        owner_tipico: { type: string, nullable: true }

    ProcessoDetalhe:
      allOf:
        - $ref: '#/components/schemas/Processo'
        - type: object
          properties:
            filhos:
              type: array
              items: { $ref: '#/components/schemas/Processo' }
            normas_vinculadas:
              type: array
              items: { $ref: '#/components/schemas/VinculoNormaProcesso' }
            riscos_vinculados:
              type: array
              items: { $ref: '#/components/schemas/VinculoProcessoRisco' }

    Risco:
      type: object
      properties:
        id: { type: string, example: R0.U.4 }
        codigo: { type: string }
        nome: { type: string }
        nivel: { type: integer, minimum: 0, maximum: 4 }
        nucleo:
          type: string
          enum: [U, B, MC, S, P, C, CG]
        parent_id: { type: string, nullable: true }
        categoria_basileia: { type: string, nullable: true }

    RiscoDetalhe:
      allOf:
        - $ref: '#/components/schemas/Risco'
        - type: object
          properties:
            filhos:
              type: array
              items: { $ref: '#/components/schemas/Risco' }
            processos_vinculados:
              type: array
              items: { $ref: '#/components/schemas/VinculoProcessoRisco' }

    VinculoNormaProcesso:
      type: object
      properties:
        norma_id: { type: string }
        processo_id: { type: string }
        artigo_ref: { type: string, nullable: true }
        tipo_vinculo:
          type: string
          enum: [primaria, secundaria, informativa]
        notas: { type: string, nullable: true }

    VinculoNormaRisco:
      type: object
      properties:
        norma_id: { type: string }
        risco_id: { type: string }
        tipo_vinculo:
          type: string
          enum: [primaria, secundaria, informativa]

    VinculoProcessoRisco:
      type: object
      properties:
        processo_id: { type: string }
        risco_id: { type: string }
        materialidade_default:
          type: integer
          minimum: 1
          maximum: 5
          description: '1 = baixíssima, 5 = crítica. Sugestão default — cada instituição faz override em sua própria instância.'

    Instancia:
      type: object
      properties:
        cartao:
          type: object
          properties:
            tipo_entidade: { type: string }
            segmento: { type: string, nullable: true }
            atividades: { type: array, items: { type: string } }
        chassi_version: { type: string }
        normas_aplicaveis:
          type: array
          items: { $ref: '#/components/schemas/Norma' }
        processos_relevantes:
          type: array
          items: { $ref: '#/components/schemas/Processo' }
        matriz_processo_risco:
          type: array
          items: { $ref: '#/components/schemas/VinculoProcessoRisco' }
        meta:
          type: object
          properties:
            qtd_normas: { type: integer }
            qtd_processos: { type: integer }
            calculado_em: { type: string, format: date-time }

    ChassiVersao:
      type: object
      properties:
        version: { type: string, example: 0.1.0 }
        released_at: { type: string, format: date-time }
        notas: { type: string }

    ChangelogEntry:
      type: object
      properties:
        version: { type: string }
        change_type:
          type: string
          enum: [add, remove, modify, deprecate]
        entity_type: { type: string }
        entity_id: { type: string }
        description: { type: string }
        created_at: { type: string, format: date-time }
