Files
Investidor-V2/api/openapi.yaml
T
nala 4f35313d06
tests / ci (push) Canceled after 0s
novas funcionalidades dos formulario
2026-10-02 11:13:37 +02:00

865 lines
35 KiB
YAML

openapi: 3.1.0
info:
title: InvestMoz API
version: 1.0.0
summary: Contrato consolidado da API do InvestMoz
description: |
Contrato consolidado para catálogos, oportunidades, manifestações de interesse,
simulações, legislação, jobs, relatórios e administração. Valores de taxas,
reduções e parâmetros de simulação são fornecidos pelo utilizador; não são
taxas oficiais nem decisões de elegibilidade.
contact:
name: Equipa InvestMoz
license:
name: MIT
identifier: MIT
servers:
- url: /
description: Mesmo host da aplicação
security:
- sessionCookie: []
tags:
- name: Catálogos
description: Referências versionadas, estáveis e localizadas em pt-MZ.
- name: Oportunidades
description: Consulta pública de oportunidades de investimento.
- name: Manifestações
description: Submissão de interesse em oportunidades.
- name: Simulações
description: Execuções indicativas com snapshots e controlo de concorrência.
- name: Jobs
description: Estado dos trabalhos assíncronos associados a uma simulação.
- name: Relatórios
description: Leitura de snapshots imutáveis de relatórios.
- name: Legislação
description: Fontes legais publicadas e versionadas.
- name: Administração
description: Operações administrativas protegidas por sessão e autorização.
paths:
/api/v1/catalogs/{catalog}:
get:
tags: [Catálogos]
operationId: listReferenceCatalog
summary: Consultar catálogo versionado
security: []
parameters:
- $ref: '#/components/parameters/CatalogName'
- $ref: '#/components/parameters/Version'
- $ref: '#/components/parameters/CatalogType'
- $ref: '#/components/parameters/ParentId'
- $ref: '#/components/parameters/JurisdictionId'
- $ref: '#/components/parameters/Page'
- $ref: '#/components/parameters/PerPage'
- $ref: '#/components/parameters/Search'
- $ref: '#/components/parameters/CorrelationId'
responses:
'200':
description: Página do catálogo na versão solicitada
headers:
ETag: {$ref: '#/components/headers/ETag'}
X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}
content:
application/json:
schema: {$ref: '#/components/schemas/CatalogPage'}
'404': {$ref: '#/components/responses/NotFound'}
'422': {$ref: '#/components/responses/ValidationError'}
'429': {$ref: '#/components/responses/RateLimited'}
'500': {$ref: '#/components/responses/ServerError'}
/api/v1/questionnaires/{code}:
get:
tags: [Simulações]
operationId: getPublishedQuestionnaire
summary: Consultar questionário publicado e versão imutável
security: []
parameters:
- $ref: '#/components/parameters/QuestionnaireCode'
- $ref: '#/components/parameters/CorrelationId'
responses:
'200':
description: Questionário publicado em pt-MZ
headers:
ETag: {$ref: '#/components/headers/ETag'}
X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}
content:
application/json:
schema: {$ref: '#/components/schemas/QuestionnaireResponse'}
'404': {$ref: '#/components/responses/NotFound'}
'429': {$ref: '#/components/responses/RateLimited'}
'500': {$ref: '#/components/responses/ServerError'}
/api/v1/simulations:
post:
tags: [Simulações]
operationId: createSimulation
summary: Criar simulação rastreável
description: Requer Idempotency-Key. Acesso anónimo requer token opaco gerado pelo cliente.
x-implementation-status: implemented
security:
- sessionCookie: []
- {}
parameters:
- $ref: '#/components/parameters/IdempotencyKey'
- $ref: '#/components/parameters/SimulationToken'
- $ref: '#/components/parameters/CorrelationId'
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/SimulationInput'}
examples:
BoundaryValues:
summary: Exemplo técnico nos limites mínimos
description: Valores mínimos para demonstrar a forma do payload; não são valores fiscais recomendados.
value: {base: 0, rate: 0, reduction: 0}
responses:
'202':
description: Simulação aceite para processamento
headers:
ETag: {$ref: '#/components/headers/ETag'}
Location: {$ref: '#/components/headers/Location'}
X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}
content:
application/json:
schema: {$ref: '#/components/schemas/SimulationAccepted'}
'200':
description: Repetição idempotente da resposta original
headers:
ETag: {$ref: '#/components/headers/ETag'}
X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}
content:
application/json:
schema: {$ref: '#/components/schemas/SimulationAccepted'}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {$ref: '#/components/responses/Forbidden'}
'409': {$ref: '#/components/responses/Conflict'}
'422': {$ref: '#/components/responses/ValidationError'}
'428': {$ref: '#/components/responses/PreconditionRequired'}
'429': {$ref: '#/components/responses/RateLimited'}
'500': {$ref: '#/components/responses/ServerError'}
/api/v1/simulations/{id}:
get:
tags: [Simulações]
operationId: getSimulation
summary: Consultar simulação, cenários e estado de execução
x-implementation-status: implemented
security:
- sessionCookie: []
- {}
parameters:
- $ref: '#/components/parameters/SimulationId'
- $ref: '#/components/parameters/SimulationToken'
- $ref: '#/components/parameters/CorrelationId'
responses:
'200':
description: Simulação dentro do âmbito autorizado
headers:
ETag: {$ref: '#/components/headers/ETag'}
X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}
content:
application/json:
schema: {$ref: '#/components/schemas/SimulationResponse'}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {$ref: '#/components/responses/Forbidden'}
'404': {$ref: '#/components/responses/NotFound'}
'429': {$ref: '#/components/responses/RateLimited'}
'500': {$ref: '#/components/responses/ServerError'}
/api/v1/simulations/{id}/scenarios/{scenarioId}:
patch:
tags: [Simulações]
operationId: updateSimulationScenario
summary: Actualizar cenário com controlo optimista de concorrência
x-implementation-status: implemented
security:
- sessionCookie: []
- {}
parameters:
- $ref: '#/components/parameters/SimulationId'
- $ref: '#/components/parameters/ScenarioId'
- $ref: '#/components/parameters/IfMatch'
- $ref: '#/components/parameters/SimulationToken'
- $ref: '#/components/parameters/CorrelationId'
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/UpdateScenarioInput'}
responses:
'202':
description: Alteração aceite e reexecução colocada em fila
headers:
ETag: {$ref: '#/components/headers/ETag'}
X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}
content:
application/json:
schema: {$ref: '#/components/schemas/Scenario'}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {$ref: '#/components/responses/Forbidden'}
'404': {$ref: '#/components/responses/NotFound'}
'412': {$ref: '#/components/responses/PreconditionFailed'}
'422': {$ref: '#/components/responses/ValidationError'}
'428': {$ref: '#/components/responses/PreconditionRequired'}
'429': {$ref: '#/components/responses/RateLimited'}
'500': {$ref: '#/components/responses/ServerError'}
/api/v1/simulations/{id}/jobs:
get:
tags: [Jobs]
operationId: listSimulationJobs
summary: Consultar jobs de execução e geração de relatórios
description: Contrato reservado para consulta dos jobs associados à simulação.
x-implementation-status: contract-only
security:
- sessionCookie: []
- {}
parameters:
- $ref: '#/components/parameters/SimulationId'
- $ref: '#/components/parameters/SimulationToken'
- $ref: '#/components/parameters/CorrelationId'
responses:
'200':
description: Jobs visíveis no âmbito autorizado
headers:
X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}
content:
application/json:
schema: {$ref: '#/components/schemas/JobCollection'}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {$ref: '#/components/responses/Forbidden'}
'404': {$ref: '#/components/responses/NotFound'}
'429': {$ref: '#/components/responses/RateLimited'}
'500': {$ref: '#/components/responses/ServerError'}
/api/v1/simulations/{id}/reports/{reportId}:
get:
tags: [Relatórios]
operationId: getSimulationReport
summary: Obter snapshot imutável de relatório
x-implementation-status: implemented
security:
- sessionCookie: []
- {}
parameters:
- $ref: '#/components/parameters/SimulationId'
- $ref: '#/components/parameters/ReportId'
- $ref: '#/components/parameters/SimulationToken'
- $ref: '#/components/parameters/CorrelationId'
responses:
'200':
description: Snapshot e hash do relatório
headers:
X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}
content:
application/json:
schema: {$ref: '#/components/schemas/ReportResponse'}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {$ref: '#/components/responses/Forbidden'}
'404': {$ref: '#/components/responses/NotFound'}
'429': {$ref: '#/components/responses/RateLimited'}
'500': {$ref: '#/components/responses/ServerError'}
/api/v1/legislation/sources:
get:
tags: [Legislação]
operationId: listLegislationSources
summary: Consultar fontes legais publicadas e versionadas
description: Contrato reservado para catálogo público de fontes; administração usa a API v2 existente.
x-implementation-status: contract-only
security: []
parameters:
- $ref: '#/components/parameters/Page'
- $ref: '#/components/parameters/PerPage'
- $ref: '#/components/parameters/Search'
- $ref: '#/components/parameters/CorrelationId'
responses:
'200':
description: Fontes legais publicadas
headers:
ETag: {$ref: '#/components/headers/ETag'}
X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}
content:
application/json:
schema: {$ref: '#/components/schemas/LegislationPage'}
'404': {$ref: '#/components/responses/NotFound'}
'422': {$ref: '#/components/responses/ValidationError'}
'429': {$ref: '#/components/responses/RateLimited'}
'500': {$ref: '#/components/responses/ServerError'}
/api/v2/investment/admin/legal-sources:
get:
tags: [Administração, Legislação]
operationId: adminListLegalSources
summary: Listar fontes legais para administração
x-implementation-status: implemented
security: [{sessionCookie: []}]
parameters:
- $ref: '#/components/parameters/CorrelationId'
responses:
'200':
description: Lista de fontes legais
headers:
X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}
content:
application/json:
schema: {$ref: '#/components/schemas/AdminLegalSourcePage'}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {$ref: '#/components/responses/Forbidden'}
'429': {$ref: '#/components/responses/RateLimited'}
'500': {$ref: '#/components/responses/ServerError'}
post:
tags: [Administração, Legislação]
operationId: adminCreateLegalSource
summary: Registar fonte legal para validação
x-implementation-status: implemented
security: [{sessionCookie: []}]
parameters:
- $ref: '#/components/parameters/CorrelationId'
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/LegalSourceInput'}
responses:
'201':
description: Fonte legal registada
headers:
Location: {$ref: '#/components/headers/Location'}
X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}
content:
application/json:
schema: {$ref: '#/components/schemas/LegalSource'}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {$ref: '#/components/responses/Forbidden'}
'409': {$ref: '#/components/responses/Conflict'}
'422': {$ref: '#/components/responses/ValidationError'}
'429': {$ref: '#/components/responses/RateLimited'}
'500': {$ref: '#/components/responses/ServerError'}
/api/v2/investment/admin/legal-sources/{id}/{action}:
post:
tags: [Administração, Legislação]
operationId: adminTransitionLegalSource
summary: Validar ou revogar uma fonte legal
x-implementation-status: implemented
security: [{sessionCookie: []}]
parameters:
- $ref: '#/components/parameters/SourceId'
- name: action
in: path
required: true
schema: {type: string, enum: [validate, revoke]}
- $ref: '#/components/parameters/CorrelationId'
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/LegalSourceTransitionInput'}
responses:
'200':
description: Estado actualizado
headers:
X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}
content:
application/json:
schema: {$ref: '#/components/schemas/LegalSource'}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {$ref: '#/components/responses/Forbidden'}
'404': {$ref: '#/components/responses/NotFound'}
'409': {$ref: '#/components/responses/Conflict'}
'429': {$ref: '#/components/responses/RateLimited'}
'500': {$ref: '#/components/responses/ServerError'}
/api/v1/interest-requests:
post:
tags: [Manifestações]
operationId: submitInterestRequest
summary: Submeter manifestação de interesse
x-implementation-status: implemented
security: []
parameters:
- $ref: '#/components/parameters/IdempotencyKeyOptional'
- $ref: '#/components/parameters/CorrelationId'
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/InterestRequestInput'}
responses:
'201':
description: Manifestação submetida
headers:
X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}
content:
application/json:
schema: {$ref: '#/components/schemas/InterestRequestResponse'}
'401': {$ref: '#/components/responses/Unauthorized'}
'403': {$ref: '#/components/responses/Forbidden'}
'409': {$ref: '#/components/responses/Conflict'}
'422': {$ref: '#/components/responses/ValidationError'}
'429': {$ref: '#/components/responses/RateLimited'}
'500': {$ref: '#/components/responses/ServerError'}
/api/v1/opportunities/{slug}:
get:
tags: [Oportunidades]
operationId: getOpportunity
summary: Consultar oportunidade publicada
x-implementation-status: implemented
security: []
parameters:
- name: slug
in: path
required: true
schema: {type: string, minLength: 1, maxLength: 180}
- $ref: '#/components/parameters/CorrelationId'
responses:
'200':
description: Oportunidade publicada
headers:
X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}
content:
application/json:
schema: {$ref: '#/components/schemas/OpportunityResponse'}
'404': {$ref: '#/components/responses/NotFound'}
'429': {$ref: '#/components/responses/RateLimited'}
'500': {$ref: '#/components/responses/ServerError'}
components:
securitySchemes:
sessionCookie:
type: apiKey
in: cookie
name: laravel-session
description: Sessão Laravel; o nome pode ser substituído por SESSION_COOKIE. Rotas públicas e simulações anónimas substituem explicitamente este requisito.
parameters:
CatalogName:
name: catalog
in: path
required: true
schema: {type: string, enum: [authorities, jurisdictions, economic-activities]}
Version:
name: version
in: query
required: false
description: Versão estável publicada do catálogo
schema: {type: integer, minimum: 1}
CatalogType:
name: type
in: query
required: false
description: Obrigatório para jurisdictions.
schema: {type: string, enum: [country, province, district, admin_post, locality]}
ParentId:
name: parent_id
in: query
schema: {type: string, format: uuid}
JurisdictionId:
name: jurisdiction_id
in: query
schema: {type: string, format: uuid}
Page:
name: page
in: query
schema: {type: integer, minimum: 1, default: 1}
PerPage:
name: per_page
in: query
schema: {type: integer, minimum: 1, maximum: 100, default: 20}
Search:
name: q
in: query
schema: {type: string, maxLength: 100}
QuestionnaireCode:
name: code
in: path
required: true
schema: {type: string, pattern: '^[a-z0-9][a-z0-9-]{0,79}$'}
SimulationId:
name: id
in: path
required: true
schema: {type: string, format: uuid}
ScenarioId:
name: scenarioId
in: path
required: true
schema: {type: string, format: uuid}
ReportId:
name: reportId
in: path
required: true
schema: {type: string, format: uuid}
SourceId:
name: id
in: path
required: true
schema: {type: string, format: uuid}
IdempotencyKey:
name: Idempotency-Key
in: header
required: true
description: Repetições com a mesma chave e payload devolvem a resposta original; payload diferente produz conflito.
schema: {type: string, minLength: 16, maxLength: 128}
IdempotencyKeyOptional:
name: Idempotency-Key
in: header
required: false
description: Se fornecida, deve ser UUID; uma chave repetida com outro payload produz conflito.
schema: {type: string, format: uuid}
SimulationToken:
name: X-Simulation-Token
in: header
required: false
description: Obrigatório para acesso anónimo; token opaco do cliente, guardado apenas como hash.
schema: {type: string, minLength: 32, maxLength: 256}
IfMatch:
name: If-Match
in: header
required: true
description: ETag forte da representação lida previamente.
schema: {type: string, minLength: 1, maxLength: 128}
CorrelationId:
name: X-Correlation-ID
in: header
required: false
description: UUID opcional propagado pela aplicação; quando ausente, a aplicação cria um identificador.
schema: {type: string, format: uuid}
headers:
ETag:
description: Validador da representação; usado com If-Match em alterações concorrentes.
schema: {type: string}
Location:
description: URI relativa do recurso criado ou aceite.
schema: {type: string, format: uri-reference}
RetryAfter:
description: Segundos até à próxima tentativa.
schema: {type: integer, minimum: 0}
CorrelationId:
description: Identificador de correlação da operação.
schema: {type: string, format: uuid}
responses:
Unauthorized:
description: Autenticação necessária ou sessão inválida
headers: {X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}}
content: {application/json: {schema: {$ref: '#/components/schemas/Problem'}}}
Forbidden:
description: Actor autenticado sem autorização para a operação
headers: {X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}}
content: {application/json: {schema: {$ref: '#/components/schemas/Problem'}}}
NotFound:
description: Recurso inexistente ou fora do âmbito visível
headers: {X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}}
content: {application/json: {schema: {$ref: '#/components/schemas/Problem'}}}
Conflict:
description: Conflito de estado, versão ou chave idempotente
headers: {X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}}
content:
application/json:
schema: {$ref: '#/components/schemas/Problem'}
example: {message: A chave foi reutilizada com conteúdo diferente., code: idempotency_conflict}
PreconditionFailed:
description: If-Match não corresponde ao ETag actual
headers:
ETag: {$ref: '#/components/headers/ETag'}
X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}
content:
application/json:
schema: {$ref: '#/components/schemas/Problem'}
example: {message: A representação mudou; volte a consultar o recurso., code: stale_etag}
ValidationError:
description: Dados inválidos
headers: {X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}}
content: {application/json: {schema: {$ref: '#/components/schemas/ValidationProblem'}}}
RateLimited:
description: Limite de pedidos excedido
headers:
Retry-After: {$ref: '#/components/headers/RetryAfter'}
X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}
content: {application/json: {schema: {$ref: '#/components/schemas/Problem'}}}
ServerError:
description: Erro interno; resposta não contém detalhes sensíveis
headers: {X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}}
content: {application/json: {schema: {$ref: '#/components/schemas/Problem'}}}
PreconditionRequired:
description: Header obrigatório em falta, como If-Match ou Idempotency-Key
headers: {X-Correlation-ID: {$ref: '#/components/headers/CorrelationId'}}
content: {application/json: {schema: {$ref: '#/components/schemas/Problem'}}}
schemas:
Problem:
type: object
required: [message]
properties:
message: {type: string}
code: {type: string}
correlation_id: {type: string, format: uuid}
additionalProperties: true
ValidationProblem:
allOf:
- $ref: '#/components/schemas/Problem'
- type: object
properties:
errors:
type: object
additionalProperties:
type: array
items: {type: string}
CatalogItem:
type: object
required: [id, value, code, name, label, locale, version_no]
properties:
id: {type: string, format: uuid}
value: {type: string}
code: {type: string}
name: {type: string, description: Rótulo apresentado em português de Moçambique.}
label: {type: string}
locale: {type: string, const: pt-MZ}
parent_id: {type: [string, 'null']}
type: {type: [string, 'null'], enum: [country, province, district, admin_post, locality, 'null']}
authority_type: {type: [string, 'null']}
organization_id: {type: [string, 'null'], format: uuid}
jurisdiction_id: {type: [string, 'null'], format: uuid}
jurisdiction_name: {type: [string, 'null']}
source_code: {type: [string, 'null']}
sector_id: {type: [string, 'null']}
version_no: {type: integer}
CatalogPage:
type: object
required: [data, meta]
properties:
data: {type: array, items: {$ref: '#/components/schemas/CatalogItem'}}
links:
type: object
properties:
next: {type: [string, 'null'], format: uri-reference}
previous: {type: [string, 'null'], format: uri-reference}
next_page_url: {type: [string, 'null'], format: uri-reference}
prev_page_url: {type: [string, 'null'], format: uri-reference}
current_page: {type: integer}
per_page: {type: integer}
total: {type: integer}
last_page: {type: integer}
meta:
allOf:
- $ref: '#/components/schemas/Pagination'
- type: object
properties:
catalog: {type: string}
version: {type: [integer, 'null']}
locale: {type: string, const: pt-MZ}
source_version: {type: [string, 'null']}
status: {type: string, enum: [published, not_published]}
Pagination:
type: object
required: [current_page, per_page, total]
properties:
current_page: {type: integer, minimum: 1}
per_page: {type: integer, minimum: 1}
total: {type: integer, minimum: 0}
version: {type: string}
QuestionnaireResponse:
type: object
required: [data]
properties:
data:
type: object
required: [id, code, version_no, locale, schema_snapshot, status]
properties:
id: {type: string, format: uuid}
code: {type: string}
version_no: {type: integer, minimum: 1}
locale: {type: string, const: pt-MZ}
schema_snapshot: {type: object, additionalProperties: true}
status: {type: string, const: published}
valid_from: {type: [string, 'null'], format: date}
valid_to: {type: [string, 'null'], format: date}
SimulationInput:
type: object
required: [base, rate]
properties:
base: {type: number, minimum: 0, description: Valor de entrada sem moeda inferida.}
rate: {type: number, minimum: 0, maximum: 100, description: Parâmetro fornecido pelo utilizador; não representa taxa oficial.}
reduction: {type: number, minimum: 0, maximum: 100, default: 0}
organization_id: {type: [string, 'null'], format: uuid}
additionalProperties: false
UpdateScenarioInput:
type: object
required: [label, base, rate]
properties:
label: {type: string, minLength: 1, maxLength: 100}
base: {type: number, minimum: 0}
rate: {type: number, minimum: 0, maximum: 100}
reduction: {type: number, minimum: 0, maximum: 100, default: 0}
additionalProperties: false
SimulationAccepted:
type: object
required: [data, replayed]
properties:
data: {$ref: '#/components/schemas/Simulation'}
replayed: {type: boolean}
access_token: {type: string, minLength: 32, maxLength: 256, description: Devolvido apenas para execução anónima.}
SimulationResponse:
type: object
required: [data]
properties:
data: {$ref: '#/components/schemas/Simulation'}
Simulation:
type: object
required: [id, status, version_no, created_at, updated_at]
properties:
id: {type: string, format: uuid}
questionnaire_version_id: {type: [string, 'null'], format: uuid}
organization_id: {type: [string, 'null'], format: uuid}
version_no: {type: integer, minimum: 1}
status: {type: string, enum: [queued, running, completed, failed, cancelled]}
input_snapshot: {type: object, additionalProperties: true}
result_snapshot: {type: [object, 'null'], additionalProperties: true}
calculation_snapshot: {type: [object, 'null'], additionalProperties: true}
scenarios: {type: array, items: {$ref: '#/components/schemas/Scenario'}}
created_at: {type: string, format: date-time}
updated_at: {type: string, format: date-time}
Scenario:
type: object
required: [id, code, label, version_no, parameters]
properties:
id: {type: string, format: uuid}
code: {type: string}
label: {type: string}
version_no: {type: integer, minimum: 1}
parameters: {type: object, additionalProperties: true}
JobCollection:
type: object
required: [data]
properties:
data: {type: array, items: {$ref: '#/components/schemas/SimulationJob'}}
SimulationJob:
type: object
required: [id, simulation_id, job_type, status, attempts, available_at]
properties:
id: {type: string, format: uuid}
simulation_id: {type: string, format: uuid}
job_type: {type: string, enum: [execute, report]}
status: {type: string, enum: [pending, running, succeeded, failed]}
attempts: {type: integer, minimum: 0, maximum: 3}
available_at: {type: string, format: date-time}
started_at: {type: [string, 'null'], format: date-time}
finished_at: {type: [string, 'null'], format: date-time}
error_code: {type: [string, 'null']}
ReportResponse:
type: object
required: [data]
properties:
data: {$ref: '#/components/schemas/SimulationReport'}
SimulationReport:
type: object
required: [id, simulation_id, version_no, status]
properties:
id: {type: string, format: uuid}
simulation_id: {type: string, format: uuid}
version_no: {type: integer, minimum: 1}
status: {type: string, enum: [queued, ready, failed]}
report_snapshot: {type: [object, 'null'], additionalProperties: true}
report_sha256: {type: [string, 'null'], pattern: '^[0-9a-f]{64}$'}
LegislationPage:
type: object
required: [data, meta]
properties:
data: {type: array, items: {$ref: '#/components/schemas/LegalSource'}}
meta: {$ref: '#/components/schemas/Pagination'}
AdminLegalSourcePage:
type: object
required: [data]
properties:
data: {type: array, items: {$ref: '#/components/schemas/LegalSource'}}
current_page: {type: integer}
per_page: {type: integer}
total: {type: integer}
last_page: {type: integer}
first_page_url: {type: [string, 'null'], format: uri-reference}
last_page_url: {type: [string, 'null'], format: uri-reference}
next_page_url: {type: [string, 'null'], format: uri-reference}
prev_page_url: {type: [string, 'null'], format: uri-reference}
LegalSourceInput:
type: object
required: [title, url, diploma, article, competent_entity, valid_from]
properties:
title: {type: string, minLength: 1, maxLength: 255}
url: {type: string, format: uri, pattern: '^https://', maxLength: 2000}
diploma: {type: string, maxLength: 255}
article: {type: string, maxLength: 255}
competent_entity: {type: string, maxLength: 255}
valid_from: {type: string, format: date}
valid_until: {type: [string, 'null'], format: date}
additionalProperties: false
LegalSourceTransitionInput:
type: object
required: [version_no]
properties:
version_no: {type: integer, minimum: 1}
additionalProperties: false
LegalSource:
type: object
properties:
id: {type: string, format: uuid}
title: {type: string}
url: {type: string, format: uri}
diploma: {type: string}
article: {type: string}
competent_entity: {type: string}
validation_status: {type: string, enum: [pending, validated, revoked]}
version_no: {type: integer}
valid_until: {type: [string, 'null'], format: date}
validator_id: {type: [integer, 'null']}
validated_at: {type: [string, 'null'], format: date-time}
valid_from: {type: [string, 'null'], format: date}
InterestRequestInput:
type: object
required: [fullName, email, investorType, country, sectorInterest, message, privacyConsent]
properties:
fullName: {type: string, minLength: 3, maxLength: 150, writeOnly: true}
email: {type: string, format: email, maxLength: 150, writeOnly: true}
phone: {type: [string, 'null'], maxLength: 30, writeOnly: true}
investorType: {type: string, enum: [individual, empresa, fundo, entidade_publica, outro]}
country: {type: string, maxLength: 100}
sectorInterest: {type: string, maxLength: 150}
opportunityReference: {type: [string, 'null'], maxLength: 80}
existingBusinessId: {type: [string, 'null'], format: uuid}
modality: {type: [string, 'null'], maxLength: 50}
investmentRange: {type: [string, 'null'], maxLength: 80}
message: {type: string, minLength: 20, maxLength: 2000, writeOnly: true}
privacyConsent: {type: boolean, const: true}
shareWithProponent: {type: boolean, default: false}
additionalProperties: false
not:
allOf:
- required: [opportunityReference]
properties:
opportunityReference: {type: string, minLength: 1}
- required: [existingBusinessId]
properties:
existingBusinessId: {type: string, format: uuid}
allOf:
- if:
required: [existingBusinessId]
properties:
existingBusinessId: {type: string}
then:
required: [modality]
properties:
modality: {type: string, minLength: 1, maxLength: 50}
InterestRequestResponse:
type: object
required: [success, message, data]
properties:
success: {type: boolean, const: true}
message: {type: string}
data:
type: object
required: [reference, status]
properties:
reference: {type: string}
status: {type: string, const: received}
OpportunityResponse:
type: object
required: [success, data]
properties:
success: {type: boolean, const: true}
data:
type: object
required: [id, slug, title]
properties:
id: {type: [string, integer]}
slug: {type: string}
title: {type: string}
summary: {type: [string, 'null']}
status: {type: string}