diff --git a/contracts/openapi.yaml b/contracts/openapi.yaml index 6248eef..cce8ea8 100644 --- a/contracts/openapi.yaml +++ b/contracts/openapi.yaml @@ -368,6 +368,117 @@ paths: "401": $ref: "#/components/responses/Unauthorized" + # --------------------------------------------------------------------------- + # Internal service-to-service (Python-engine bridge) — P-002 internal OpenAPI. + # Declared 2026-09-09 after the cross-product parity gate proved these two + # routes + credential LIVE in services/api/workers/{resolve,quality_bridge}.py + # while the contract never shipped them (E_PATH_NOT_DECLARED + + # E_AUTH_SCHEME_UNDECLARED). The wire is truth; the contract now matches it. + # --------------------------------------------------------------------------- + /api/0pt/internal/er/candidates: + post: + operationId: 0pt.internal.erCandidates + summary: Candidate generation for the Python ER worker. Blocking-key buckets, similarity scoring, company/work review boundary. X-Internal-Token required (verifyInternalServiceToken). + x-siax-status: target + tags: [EntityResolution, Internal] + security: + - internalToken: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [tenant_id, project_id, records, blocking_fields, compare_fields] + properties: + tenant_id: { type: string, minLength: 1 } + project_id: { type: string, minLength: 1 } + records: + type: array + minItems: 2 + maxItems: 5000 + items: + type: object + required: [record_id, fields] + properties: + record_id: { type: string, minLength: 1 } + fields: + type: object + maxProperties: 200 + additionalProperties: + type: [string, number, "null"] + blocking_fields: + type: array + minItems: 1 + maxItems: 20 + items: { type: string, minLength: 1 } + compare_fields: + type: array + minItems: 1 + maxItems: 50 + items: + type: object + required: [field] + properties: + field: { type: string, minLength: 1 } + weight: { type: number, minimum: 0, maximum: 100 } + auto_match_threshold: { type: number, minimum: 0, maximum: 1 } + review_threshold: { type: number, minimum: 0, maximum: 1 } + correlation_id: { type: string } + responses: + "200": + description: Candidate pairs (status auto_match/review/abstain) + review queue. + content: + application/json: + schema: + type: object + required: [pairs, review_queue, blocked_comparisons, total_possible_comparisons] + properties: + pairs: + type: array + items: + type: object + required: [candidate_id, record_a, record_b, score, status, decided_by, blocking_key] + properties: + candidate_id: { type: string } + record_a: { type: string } + record_b: { type: string } + score: { type: number } + status: { type: string, enum: [auto_match, review, abstain, force_match, force_non_match] } + decided_by: { type: string } + blocking_key: { type: string } + explanation: + type: array + items: { type: object } + "401": + $ref: "#/components/responses/Unauthorized" + + /api/0pt/quality/bridge-run: + post: + operationId: 0pt.internal.qualityBridgeRun + summary: Advisory quality bridge — auto-provisions baseline rules and runs QualityService; the Python quality worker calls through here with X-Internal-Token. Fail-open by design. + x-siax-status: target + tags: [Quality, Internal] + security: + - internalToken: [] + requestBody: + required: true + content: + application/json: + schema: + type: object + required: [tenant_id, dataset_id] + properties: + tenant_id: { type: string, minLength: 1 } + dataset_id: { type: string, minLength: 1 } + dataset_version: { type: integer } + correlation_id: { type: string } + responses: + "200": + description: Run + any open issues (advisory). + "401": + $ref: "#/components/responses/Unauthorized" + # --------------------------------------------------------------------------- # Quality — P-002 internal OpenAPI (0pt quality delegation to N0D) # --------------------------------------------------------------------------- @@ -404,26 +515,6 @@ paths: "200": description: List of quality runs. - /api/0pt/quality/bridge-run: - post: - operationId: 0pt.quality.bridge_run - summary: Advisory quality bridge — auto-provisions baseline rules, runs QualityService.runQuality; Python engine calls through here. Fail-open. - x-siax-status: target - tags: [Quality] - requestBody: - required: true - content: - application/json: - schema: - type: object - required: [tenant_id, dataset_id] - properties: - tenant_id: { type: string } - dataset_id: { type: string } - responses: - "200": - description: Run + any open issues. - /api/0pt/quality/checks: get: operationId: 0pt.quality.checks @@ -472,6 +563,11 @@ components: type: http scheme: bearer description: Zitadel-utfärdad token; verifieras i middleware mot ZITADEL_ISSUER + internalToken: + type: apiKey + in: header + name: X-Internal-Token + description: Internal service-to-service credential (verifyInternalServiceToken). Endast för service-worker-bryggor; aldrig exponerat utåt. parameters: OrderId: name: id