From 2ddb21e56880ff213f9e353a41a9851ab1715460 Mon Sep 17 00:00:00 2001 From: Simon Axelsson Date: Sat, 26 Sep 2026 13:17:58 +0200 Subject: [PATCH] feat(contract): add routing + normalization operationIds per ADR-027 0pt.structure.* registered 5 of ADR-027's 7 areas yesterday (cl0ud PR#270, grounded at this repo's main@ec48774): entity resolution, lineage, quality (x4) and parsing-orchestration. routing and normalization were left out because this repo's own contract had no operationId/path for either yet, even though both have real, INTEGRATION_TESTED code in sax3l/0pt-motor (motor/parsing/routing.py, motor/normalization/{amounts,identifiers}.py) that is simply not deployed behind an HTTP route. Adds the two target-status operationIds, following the exact pattern of 0pt.resolve_entities / 0pt.get_provenance already in this file (TARGET summary prefix, x-siax-status: target, security: [], dedicated request/response schemas): - POST /v1/0pt/parsing/route -> 0pt.route_parsing (BTI-DOC-02/03/04/05 parser-routing / selective-OCR decision) - POST /v1/0pt/normalize -> 0pt.normalize_value (BTI-NLP-02/03 amount/percent/date normalization + identifier checksum validation, one operationId per ADR-027's "normalization" being a single area) Contract-only change; no route handler exists yet (correctly reflected by x-siax-status: target). Registering these in cl0ud's capability registry is deliberately deferred to a follow-up PR in that repo. projections is NOT touched here -- no code exists anywhere for it, so it stays unregistered rather than becoming an empty stub. Co-Authored-By: Claude Sonnet 5 --- contracts/openapi.yaml | 142 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/contracts/openapi.yaml b/contracts/openapi.yaml index cce8ea8..de31ab1 100644 --- a/contracts/openapi.yaml +++ b/contracts/openapi.yaml @@ -367,6 +367,60 @@ paths: $ref: "#/components/schemas/ProvenanceRecord" "401": $ref: "#/components/responses/Unauthorized" + /v1/0pt/parsing/route: + post: + operationId: 0pt.route_parsing + summary: > + (TARGET) Parser-routing/selektiv OCR-beslut (BTI-DOC-02/03/04/05). + Kontrakt-first — real kod i 0pt-motor/motor/parsing/routing.py + (route_parser m.fl.), INTEGRATION_TESTED men ej driftsatt bakom + denna route. + x-siax-status: target + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/RouteParsingRequest" + responses: + "200": + description: Routingbeslut (parser/OCR-gren) + ev. nyckeltalskonflikter mellan parsers + content: + application/json: + schema: + $ref: "#/components/schemas/RouteParsingResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" + /v1/0pt/normalize: + post: + operationId: 0pt.normalize_value + summary: > + (TARGET) Lokal-medveten normalisering — belopp/skala/datum (BTI-NLP-03) + och identifierare/checksummor (BTI-NLP-02). Kontrakt-first — real kod + i 0pt-motor/motor/normalization/{amounts,identifiers}.py, + INTEGRATION_TESTED men ej driftsatt bakom denna route. + x-siax-status: target + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: "#/components/schemas/NormalizeValueRequest" + responses: + "200": + description: Normaliserat värde — format_valid/review, aldrig en påhittad korrigering + content: + application/json: + schema: + $ref: "#/components/schemas/NormalizeValueResponse" + "400": + $ref: "#/components/responses/BadRequest" + "401": + $ref: "#/components/responses/Unauthorized" # --------------------------------------------------------------------------- # Internal service-to-service (Python-engine bridge) — P-002 internal OpenAPI. @@ -811,3 +865,91 @@ components: type: object additionalProperties: $ref: "#/components/schemas/FieldProvenance" + RouteParsingRequest: + type: object + required: [digital_text_page] + properties: + digital_text_page: + type: boolean + description: True om sidan har ett digitalt textlager (ej scannad). + ocr_available: + type: boolean + default: false + parser_result: + type: object + description: Föregående parser-försök, om något (tom text = kandidat för OCR-gren). + properties: + parser: + type: string + text: + type: string + key_figures: + type: object + additionalProperties: + type: number + compare_with: + type: object + description: (Valfritt) ett andra parser-resultat att stämma av mot — avvikande nyckeltal blir en konflikt, aldrig en tyst ersättning. + properties: + parser: + type: string + text: + type: string + key_figures: + type: object + additionalProperties: + type: number + RouteParsingResponse: + type: object + required: [routing] + properties: + routing: + type: string + enum: [text_parser, ocr_branch, explicit_unavailable] + conflicts: + type: object + description: Fält där de två parser-resultatens nyckeltal skiljer sig (present endast om compare_with skickades). + additionalProperties: true + NormalizeValueRequest: + type: object + required: [kind, value] + properties: + kind: + type: string + enum: [amount, percent, date, identifier] + description: amount/percent/date = motor/normalization/amounts.py. identifier = motor/normalization/identifiers.py. + value: + type: string + description: Rå textsträng att normalisera (belopp, procentsats, datum eller identifierare). + locale: + type: string + description: (kind=amount, valfritt) comma_decimal|dot_decimal — auto-detekteras annars. + unit: + type: string + description: (kind=amount|percent) t.ex. SEK/KSEK/MSEK/GSEK eller "%"/"pp". + identifier_kind: + type: string + enum: [orgnr, cvr, vat, ocr] + description: (kind=identifier, krävs) vilken identifierartyp som ska valideras. + country: + type: string + description: (kind=identifier, krävs) ISO-3166 alpha-2, t.ex. SE/NO/DK. + description: > + Ett fält, en normalisering. amount/percent/date har alltid en explicit + precision/skala (aldrig en påhittad dag eller sammanblandad enhet). + identifier ger format_valid eller review — aldrig en tyst korrigerad + checksumma; existens i register verifieras inte här. + NormalizeValueResponse: + type: object + required: [kind, status] + properties: + kind: + type: string + enum: [amount, percent, date, identifier] + status: + type: string + enum: [ok, format_valid, format_invalid, review, unparseable] + result: + type: object + description: Normaliserat resultat, formen beror på kind (se motor/normalization/{amounts,identifiers}.py). + additionalProperties: true -- 2.54.0