fix(contract): deklarera internal-er + quality bridge-run + internalToken-scheme #50

Merged
admin merged 1 commits from fix/contract-declare-internal-er-quality into main 2026-09-08 23:31:25 +00:00
+116 -20
View File
@@ -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