{ "openapi": "3.1.0", "info": { "title": "InvestMoz Education — contrato proposto do núcleo de procura", "version": "0.1.0-proposal", "description": "Não implementado. Bloqueios B01/B02/B03. Não usar para gerar clientes de produção. Demais endpoints na especificação estão pendentes de contratos detalhados." }, "x-artifact-status": "Proposta", "x-authentication-pending": { "target": "OAuth 2.0 e OpenID Connect", "issuer": "Pendente de validação", "scopes": "Propostos; não configurados", "warning": "Bearer descreve transporte; não demonstra servidor OAuth/OIDC existente." }, "security": [ { "ProposedAccessToken": [] } ], "paths": { "/api/v1/education/labour-demands": { "get": { "operationId": "educationListLabourDemands", "x-rf": ["RF-EDU-002", "RF-EDU-015"], "x-required-scopes": ["education:read"], "parameters": [ { "$ref": "#/components/parameters/Correlation" }, { "name": "cursor", "in": "query", "schema": { "type": "string", "maxLength": 2000 } }, { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 20 } }, { "name": "territory_id", "in": "query", "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Resultado proposto", "headers": { "X-Correlation-Id": { "schema": { "type": "string", "format": "uuid" } }, "ETag": { "schema": { "type": "string" }, "description": "ETag forte e opaco da versão" } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DemandPage" } } } }, "400": { "$ref": "#/components/responses/Problem" }, "401": { "$ref": "#/components/responses/Problem" }, "403": { "$ref": "#/components/responses/Problem" }, "404": { "$ref": "#/components/responses/Problem" }, "409": { "$ref": "#/components/responses/Problem" }, "412": { "$ref": "#/components/responses/Problem" }, "422": { "$ref": "#/components/responses/Problem" }, "428": { "$ref": "#/components/responses/Problem" }, "429": { "$ref": "#/components/responses/Problem" }, "503": { "$ref": "#/components/responses/Problem" } } }, "post": { "operationId": "educationSubmitLabourDemand", "x-rf": ["RF-EDU-002", "RF-EDU-009"], "x-required-scopes": ["education:demand:submit"], "parameters": [ { "$ref": "#/components/parameters/Correlation" }, { "$ref": "#/components/parameters/Idempotency" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DemandInput" } } } }, "responses": { "201": { "description": "Resultado proposto", "headers": { "X-Correlation-Id": { "schema": { "type": "string", "format": "uuid" } }, "ETag": { "schema": { "type": "string" }, "description": "ETag forte e opaco da versão" } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Demand" } } } }, "400": { "$ref": "#/components/responses/Problem" }, "401": { "$ref": "#/components/responses/Problem" }, "403": { "$ref": "#/components/responses/Problem" }, "404": { "$ref": "#/components/responses/Problem" }, "409": { "$ref": "#/components/responses/Problem" }, "412": { "$ref": "#/components/responses/Problem" }, "422": { "$ref": "#/components/responses/Problem" }, "428": { "$ref": "#/components/responses/Problem" }, "429": { "$ref": "#/components/responses/Problem" }, "503": { "$ref": "#/components/responses/Problem" } } } }, "/api/v1/education/labour-demands/{id}": { "parameters": [ { "$ref": "#/components/parameters/Id" } ], "get": { "operationId": "educationGetLabourDemand", "x-rf": ["RF-EDU-002"], "x-required-scopes": ["education:read"], "parameters": [ { "$ref": "#/components/parameters/Correlation" } ], "responses": { "200": { "description": "Resultado proposto", "headers": { "X-Correlation-Id": { "schema": { "type": "string", "format": "uuid" } }, "ETag": { "schema": { "type": "string" }, "description": "ETag forte e opaco da versão" } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Demand" } } } }, "400": { "$ref": "#/components/responses/Problem" }, "401": { "$ref": "#/components/responses/Problem" }, "403": { "$ref": "#/components/responses/Problem" }, "404": { "$ref": "#/components/responses/Problem" }, "409": { "$ref": "#/components/responses/Problem" }, "412": { "$ref": "#/components/responses/Problem" }, "422": { "$ref": "#/components/responses/Problem" }, "428": { "$ref": "#/components/responses/Problem" }, "429": { "$ref": "#/components/responses/Problem" }, "503": { "$ref": "#/components/responses/Problem" } } }, "patch": { "operationId": "educationReviseLabourDemand", "x-rf": ["RF-EDU-009"], "x-required-scopes": ["education:demand:submit"], "description": "Alteração cria nova versão e invalida validação anterior; estado é gerido pelo servidor.", "parameters": [ { "$ref": "#/components/parameters/Correlation" }, { "$ref": "#/components/parameters/Match" }, { "$ref": "#/components/parameters/Idempotency" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DemandPatch" } } } }, "responses": { "200": { "description": "Resultado proposto", "headers": { "X-Correlation-Id": { "schema": { "type": "string", "format": "uuid" } }, "ETag": { "schema": { "type": "string" }, "description": "ETag forte e opaco da versão" } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Demand" } } } }, "400": { "$ref": "#/components/responses/Problem" }, "401": { "$ref": "#/components/responses/Problem" }, "403": { "$ref": "#/components/responses/Problem" }, "404": { "$ref": "#/components/responses/Problem" }, "409": { "$ref": "#/components/responses/Problem" }, "412": { "$ref": "#/components/responses/Problem" }, "422": { "$ref": "#/components/responses/Problem" }, "428": { "$ref": "#/components/responses/Problem" }, "429": { "$ref": "#/components/responses/Problem" }, "503": { "$ref": "#/components/responses/Problem" } } } }, "/api/v1/education/labour-demands/{id}/decisions": { "parameters": [ { "$ref": "#/components/parameters/Id" } ], "post": { "operationId": "educationDecideLabourDemand", "x-rf": ["RF-EDU-009", "RF-EDU-032"], "x-required-scopes": ["education:demand:review"], "description": "Revisor distinto e mandato válido; não confere acreditação. Versão deve coincidir com If-Match.", "parameters": [ { "$ref": "#/components/parameters/Correlation" }, { "$ref": "#/components/parameters/Match" }, { "$ref": "#/components/parameters/Idempotency" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DecisionInput" } } } }, "responses": { "201": { "description": "Resultado proposto", "headers": { "X-Correlation-Id": { "schema": { "type": "string", "format": "uuid" } }, "ETag": { "schema": { "type": "string" }, "description": "ETag forte e opaco da versão" } }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Demand" } } } }, "400": { "$ref": "#/components/responses/Problem" }, "401": { "$ref": "#/components/responses/Problem" }, "403": { "$ref": "#/components/responses/Problem" }, "404": { "$ref": "#/components/responses/Problem" }, "409": { "$ref": "#/components/responses/Problem" }, "412": { "$ref": "#/components/responses/Problem" }, "422": { "$ref": "#/components/responses/Problem" }, "428": { "$ref": "#/components/responses/Problem" }, "429": { "$ref": "#/components/responses/Problem" }, "503": { "$ref": "#/components/responses/Problem" } } } } }, "components": { "securitySchemes": { "ProposedAccessToken": { "type": "http", "scheme": "bearer", "description": "Proposta de access token validado; configuração OAuth/OIDC pendente." } }, "parameters": { "Id": { "name": "id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }, "Correlation": { "name": "X-Correlation-Id", "in": "header", "required": false, "schema": { "type": "string", "format": "uuid" }, "description": "Servidor gera se ausente; nunca confere autorização." }, "Idempotency": { "name": "Idempotency-Key", "in": "header", "required": true, "schema": { "type": "string", "format": "uuid" }, "description": "Escopo actor + operação + recurso; payload diferente com mesma chave devolve 409." }, "Match": { "name": "If-Match", "in": "header", "required": true, "schema": { "type": "string", "minLength": 1 }, "description": "ETag forte exacto; ausente 428, desactualizado 412; wildcard não aceite." } }, "responses": { "Problem": { "description": "Erro sanitizado", "headers": { "X-Correlation-Id": { "schema": { "type": "string", "format": "uuid" } } }, "content": { "application/problem+json": { "schema": { "$ref": "#/components/schemas/Problem" } } } } }, "schemas": { "DemandInput": { "type": "object", "additionalProperties": false, "properties": { "occupation_id": { "type": "string", "format": "uuid" }, "employer_id": { "type": "string", "format": "uuid" }, "territory_id": { "type": "string", "format": "uuid" }, "project_id": { "type": "string", "format": "uuid" }, "cluster_id": { "type": "string", "format": "uuid" }, "corridor_id": { "type": "string", "format": "uuid" }, "value_chain_id": { "type": "string", "format": "uuid" }, "qualification_level_id": { "type": "string", "format": "uuid" }, "skill_ids": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "format": "uuid" } }, "quantity": { "type": "integer", "minimum": 1, "maximum": 2147483647 }, "country_code": { "type": "string", "pattern": "^[A-Z]{2}$", "description": "Validar pertença ISO 3166-1 alpha-2, não apenas regex." }, "activity": { "type": "string", "minLength": 1, "maxLength": 2000 }, "phase": { "type": "string", "minLength": 1, "maxLength": 2000 }, "workplace": { "type": "string", "minLength": 1, "maxLength": 2000 }, "nature": { "type": "string", "enum": ["permanent", "temporary", "seasonal"] }, "hiring_date": { "type": "string", "format": "date" }, "end_date": { "type": ["string", "null"], "format": "date" }, "source_id": { "type": "string", "format": "uuid" }, "reference_date": { "type": "string", "format": "date" }, "valid_until": { "type": "string", "format": "date" }, "evidence_document_id": { "type": "string", "format": "uuid" }, "classification": { "type": "string", "enum": ["internal", "confidential", "restricted"] } }, "required": [ "occupation_id", "employer_id", "territory_id", "qualification_level_id", "skill_ids", "quantity", "country_code", "activity", "phase", "workplace", "nature", "hiring_date", "source_id", "reference_date", "valid_until", "evidence_document_id", "classification" ], "anyOf": [ { "required": ["project_id"] }, { "required": ["cluster_id"] }, { "required": ["corridor_id"] } ], "description": "Proposta; validar datas, mandato, contexto, fontes e taxonomias no serviço. Submissor não fornece estado validado." }, "DemandPatch": { "type": "object", "minProperties": 1, "additionalProperties": false, "properties": { "occupation_id": { "type": "string", "format": "uuid" }, "employer_id": { "type": "string", "format": "uuid" }, "territory_id": { "type": "string", "format": "uuid" }, "project_id": { "type": "string", "format": "uuid" }, "cluster_id": { "type": "string", "format": "uuid" }, "corridor_id": { "type": "string", "format": "uuid" }, "value_chain_id": { "type": "string", "format": "uuid" }, "qualification_level_id": { "type": "string", "format": "uuid" }, "skill_ids": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "type": "string", "format": "uuid" } }, "quantity": { "type": "integer", "minimum": 1, "maximum": 2147483647 }, "country_code": { "type": "string", "pattern": "^[A-Z]{2}$", "description": "Validar pertença ISO 3166-1 alpha-2, não apenas regex." }, "activity": { "type": "string", "minLength": 1, "maxLength": 2000 }, "phase": { "type": "string", "minLength": 1, "maxLength": 2000 }, "workplace": { "type": "string", "minLength": 1, "maxLength": 2000 }, "nature": { "type": "string", "enum": ["permanent", "temporary", "seasonal"] }, "hiring_date": { "type": "string", "format": "date" }, "end_date": { "type": ["string", "null"], "format": "date" }, "source_id": { "type": "string", "format": "uuid" }, "reference_date": { "type": "string", "format": "date" }, "valid_until": { "type": "string", "format": "date" }, "evidence_document_id": { "type": "string", "format": "uuid" }, "classification": { "type": "string", "enum": ["internal", "confidential", "restricted"] } }, "description": "Validar o resultado completo após aplicar PATCH; não aceitar alteração de estado por este contrato." }, "Demand": { "type": "object", "additionalProperties": false, "required": ["id", "version", "state", "data", "updated_at"], "properties": { "id": { "type": "string", "format": "uuid" }, "version": { "type": "integer", "minimum": 1 }, "state": { "type": "string", "enum": [ "submitted", "in_review", "validated", "rejected", "expired", "suspended" ] }, "data": { "$ref": "#/components/schemas/DemandInput" }, "updated_at": { "type": "string", "format": "date-time" } } }, "DemandPage": { "type": "object", "additionalProperties": false, "required": ["data", "next_cursor"], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/Demand" } }, "next_cursor": { "type": ["string", "null"] } } }, "DecisionInput": { "type": "object", "additionalProperties": false, "required": [ "decision", "reason", "evidence_document_id", "authority_id" ], "properties": { "decision": { "type": "string", "enum": ["validate", "reject", "return_for_correction"] }, "reason": { "type": "string", "minLength": 1, "maxLength": 2000 }, "evidence_document_id": { "type": "string", "format": "uuid" }, "authority_id": { "type": "string", "format": "uuid" } } }, "Problem": { "type": "object", "required": ["type", "title", "status", "correlation_id"], "properties": { "type": { "type": "string", "format": "uri-reference" }, "title": { "type": "string" }, "status": { "type": "integer", "minimum": 400, "maximum": 599 }, "detail": { "type": "string" }, "instance": { "type": "string", "format": "uri-reference" }, "correlation_id": { "type": "string", "format": "uuid" }, "errors": { "type": "object", "additionalProperties": { "type": "array", "items": { "type": "string" } } } } } } } }