Release chain (G17, ADR-W16-003) / Build, push, G17 (SBOM/scan/attest/verify/evidence) (push) Failing after 5s
CI (SIAX Cloud) / integration (push) Skipped
masterplan-lock / check (push) Successful in 7s
CI (SIAX Cloud) / security (push) Successful in 17s
Security Scan (SIAX Cloud) / security (push) Successful in 21s
CI (SIAX Cloud) / quality (push) Successful in 47s
Deploy to Coolify / deploy (push) Failing after 10m25s
956 lines
31 KiB
YAML
956 lines
31 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: 0pt Data OS API
|
|
version: 1.0.0
|
|
description: >
|
|
SIAX Cloud Data OS — order-, estimat- och capability-API (0pt).
|
|
Single Source of Truth för HTTP-kontraktet (SSOT). Routehandlers i
|
|
app/api/* realiserar dessa kontrakt; se x-siax-status för vad som är
|
|
live vs kontrakt-first (target).
|
|
x-siax:
|
|
appId: 0PT
|
|
capabilityPrefix: 0pt
|
|
tenantBinding: header X-Tenant-Id (live), session (target — se BACKLOG P0-2)
|
|
servers:
|
|
- url: https://0pt.app
|
|
description: Production (edge plane)
|
|
- url: https://api.0pt.app
|
|
description: Target API-host (Caddy, EJ verifierad live)
|
|
security:
|
|
- bearerAuth: []
|
|
paths:
|
|
/api/health:
|
|
get:
|
|
operationId: 0pt.health
|
|
summary: Liveness + real per-dependency state
|
|
x-siax-status: live
|
|
security: []
|
|
responses:
|
|
"200":
|
|
description: Process is alive. Body reports honest per-dependency status (ok/error/not_configured/not_integrated) — see HealthResponse.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/HealthResponse"
|
|
/api/ready:
|
|
get:
|
|
operationId: 0pt.ready
|
|
summary: Readiness — fails closed when a load-bearing dependency is down
|
|
x-siax-status: live
|
|
security: []
|
|
responses:
|
|
"200":
|
|
description: Ready to serve real traffic.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ReadyResponse"
|
|
"503":
|
|
description: Not ready — a load-bearing dependency is not configured/reachable.
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ReadyResponse"
|
|
/api/estimates:
|
|
post:
|
|
operationId: 0pt.estimate_order
|
|
summary: Prisestimat för en datajob-konfiguration
|
|
x-siax-status: live
|
|
security: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/EstimateRequest"
|
|
responses:
|
|
"200":
|
|
description: Estimat (öre)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/EstimateResponse"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
/api/orders:
|
|
post:
|
|
operationId: 0pt.create_order
|
|
summary: Skapa draft-order (50 % deposition startar jobbet)
|
|
x-siax-status: live
|
|
security: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/CreateOrderRequest"
|
|
responses:
|
|
"201":
|
|
description: Order skapad
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/OrderSummary"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
get:
|
|
operationId: 0pt.list_orders
|
|
summary: Lista ordrar (org-scoping saknas — se BACKLOG P0-3)
|
|
x-siax-status: live
|
|
x-siax-gap: S3 — ingen auth/org-scoping
|
|
security: []
|
|
responses:
|
|
"200":
|
|
description: Orderlista
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/OrderSummary"
|
|
/api/orders/{id}:
|
|
get:
|
|
operationId: 0pt.get_order
|
|
summary: Hämta order
|
|
x-siax-status: live
|
|
security: []
|
|
parameters:
|
|
- $ref: "#/components/parameters/OrderId"
|
|
responses:
|
|
"200":
|
|
description: Order
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Order"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
patch:
|
|
operationId: 0pt.update_order
|
|
summary: Uppdatera order
|
|
x-siax-status: live
|
|
security: []
|
|
parameters:
|
|
- $ref: "#/components/parameters/OrderId"
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
responses:
|
|
"200":
|
|
description: Uppdaterad order
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/Order"
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
/api/0pt:
|
|
get:
|
|
operationId: 0pt.capability_index
|
|
summary: Capability-index
|
|
x-siax-status: live
|
|
responses:
|
|
"200":
|
|
description: Index med endpoints
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
additionalProperties: true
|
|
/api/0pt/sources/{sourceId}/query:
|
|
post:
|
|
operationId: 0pt.query_source
|
|
summary: Bunden källfråga (enrich-primitiv)
|
|
x-siax-status: live
|
|
x-siax-gap: S10 — connection_config ur body (SSRF-primitiv, BACKLOG P0-7)
|
|
parameters:
|
|
- name: sourceId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/SourceQueryRequest"
|
|
responses:
|
|
"200":
|
|
description: Källdata med provenance per fält
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: array
|
|
items:
|
|
$ref: "#/components/schemas/EnrichedRecord"
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
/api/0pt/documents/capture:
|
|
post:
|
|
operationId: 0pt.capture_document
|
|
summary: Ta emot dokument (PII) för extraktion
|
|
x-siax-status: live
|
|
x-siax-gap: S2 — tenant_id från body (BACKLOG P0-2)
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
type: object
|
|
additionalProperties: true
|
|
responses:
|
|
"201":
|
|
description: Dokument registrerat
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
get:
|
|
operationId: 0pt.list_documents
|
|
summary: Lista dokument
|
|
x-siax-status: live
|
|
x-siax-gap: S2 — tenant_id från query (BACKLOG P0-2)
|
|
responses:
|
|
"200":
|
|
description: Dokumentlista
|
|
/api/0pt/documents/{documentId}/extraction:
|
|
post:
|
|
operationId: 0pt.extract_document
|
|
summary: Extrahera dokument (OCR/AI — env-guardad, 501 utan konfig)
|
|
x-siax-status: live
|
|
parameters:
|
|
- name: documentId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Extraktion — aldrig fabricerade värden
|
|
"404":
|
|
$ref: "#/components/responses/NotFound"
|
|
"501":
|
|
$ref: "#/components/responses/NotConfigured"
|
|
/api/0pt/lakehouse/mappings:
|
|
post:
|
|
operationId: 0pt.map_dataset_to_iceberg
|
|
summary: Registrera dataset↔Iceberg-mappning
|
|
x-siax-status: live
|
|
x-siax-gap: S2 — tenant_id från body (BACKLOG P0-2)
|
|
responses:
|
|
"201":
|
|
description: Mappning registrerad
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
get:
|
|
operationId: 0pt.list_iceberg_mappings
|
|
summary: Lista mappningar
|
|
x-siax-status: live
|
|
x-siax-gap: S2 — tenant_id från query (BACKLOG P0-2)
|
|
responses:
|
|
"200":
|
|
description: Mappningslista
|
|
/api/0pt/lakehouse/mappings/{mappingId}/writes:
|
|
post:
|
|
operationId: 0pt.request_iceberg_write
|
|
summary: Iceberg-write (L4) — tung variant delegeras till N0D-jobb
|
|
x-siax-status: live
|
|
x-siax-gap: S5 — CL0UD fail-open (BACKLOG P0-5)
|
|
parameters:
|
|
- name: mappingId
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"202":
|
|
description: Skrivning begärd (job_id eller synkront snapshot)
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
/api/0pt/sources/rate-policies:
|
|
post:
|
|
operationId: 0pt.create_rate_policy
|
|
summary: Registrera käll-rate-policy
|
|
x-siax-status: live
|
|
x-siax-gap: S2 — tenant_id från body (BACKLOG P0-2)
|
|
responses:
|
|
"201":
|
|
description: Rate-policy skapad
|
|
get:
|
|
operationId: 0pt.list_rate_policies
|
|
summary: Lista rate-policies
|
|
x-siax-status: live
|
|
x-siax-gap: S2 — tenant_id från query (BACKLOG P0-2)
|
|
responses:
|
|
"200":
|
|
description: Rate-policylista
|
|
/api/screen:
|
|
get:
|
|
operationId: 0pt.screen_entity
|
|
summary: Sanktions-/PEP-screening via OpenSanctions
|
|
x-siax-status: live
|
|
security: []
|
|
parameters:
|
|
- name: q
|
|
in: query
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Screeningträffar
|
|
"400":
|
|
$ref: "#/components/responses/BadRequest"
|
|
/v1/0pt/enrichment/company-lists:
|
|
post:
|
|
operationId: 0pt.enrich_company_list
|
|
summary: >
|
|
(TARGET) Capability-formen av enrichment: lista → enrichade poster med
|
|
bridge_provenance. Kontrakt-first — implementeras av 0pt-motor/edge
|
|
via N0D-jobb (job_type 0pt.enrichment.company_list).
|
|
x-siax-status: target
|
|
security: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/EnrichCompanyListRequest"
|
|
responses:
|
|
"202":
|
|
description: Jobb begärt — poll via /v1/0pt/jobs/{id} (target)
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/v1/0pt/resolve/entities:
|
|
post:
|
|
operationId: 0pt.resolve_entities
|
|
summary: (TARGET) Entity resolution/dedupe (rapidfuzz idag, spaCy planerat)
|
|
x-siax-status: target
|
|
security: []
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ResolveEntitiesRequest"
|
|
responses:
|
|
"200":
|
|
description: Kluster med konfidens
|
|
"401":
|
|
$ref: "#/components/responses/Unauthorized"
|
|
/v1/0pt/provenance/records/{entityType}/{entityKey}:
|
|
get:
|
|
operationId: 0pt.get_provenance
|
|
summary: (TARGET) Provenance per fält — bridge_provenance (källa, färskhet, konfidens, level)
|
|
x-siax-status: target
|
|
security: []
|
|
parameters:
|
|
- name: entityType
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
enum: [company, contact, vehicle, ubo]
|
|
- name: entityKey
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
"200":
|
|
description: Provenance per fält
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$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.
|
|
# 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)
|
|
# ---------------------------------------------------------------------------
|
|
/api/0pt/quality/runs:
|
|
post:
|
|
operationId: 0pt.quality.run
|
|
summary: Execute quality checks for a dataset; delegates to N0D via n0dRunDataQuality when any rule needs the GE backend.
|
|
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 }
|
|
dataset_version: { type: integer }
|
|
responses:
|
|
"201":
|
|
description: Quality run accepted (status=delegated when offloaded to N0D).
|
|
"404":
|
|
description: No active rules for the dataset.
|
|
get:
|
|
operationId: 0pt.quality.list_runs
|
|
summary: List quality runs for a tenant.
|
|
x-siax-status: target
|
|
tags: [Quality]
|
|
parameters:
|
|
- { name: tenant_id, in: query, required: true, schema: { type: string } }
|
|
responses:
|
|
"200":
|
|
description: List of quality runs.
|
|
|
|
/api/0pt/quality/checks:
|
|
get:
|
|
operationId: 0pt.quality.checks
|
|
summary: List active quality checks/rules for a tenant+dataset.
|
|
x-siax-status: target
|
|
tags: [Quality]
|
|
parameters:
|
|
- { name: tenant_id, in: query, required: true, schema: { type: string } }
|
|
- { name: dataset_id, in: query, required: true, schema: { type: string } }
|
|
responses:
|
|
"200":
|
|
description: Active quality rules.
|
|
|
|
/api/0pt/quality/reports:
|
|
get:
|
|
operationId: 0pt.quality.reports
|
|
summary: Retrieve quality reports / Great Expectations results for a run.
|
|
x-siax-status: target
|
|
tags: [Quality]
|
|
parameters:
|
|
- { name: run_id, in: query, required: true, schema: { type: string } }
|
|
responses:
|
|
"200":
|
|
description: Quality report.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# N0D interop — 0pt consumption of N0D owner operations (P-001 owner-seam)
|
|
# ---------------------------------------------------------------------------
|
|
/api/0pt/n0d/results/{jobId}:
|
|
get:
|
|
operationId: 0pt.n0dGetJobResult
|
|
summary: Retrieve the result of an N0D-delegated quality job (n0dGetJobResult). Polls N0D after the quality run is delegated.
|
|
x-siax-status: target
|
|
tags: [Quality, N0D]
|
|
parameters:
|
|
- { name: jobId, in: path, required: true, schema: { type: string } }
|
|
responses:
|
|
"200":
|
|
description: N0D job result (outcome, metrics, ST0RE artifact refs).
|
|
"404":
|
|
description: Job not found or foreign-tenant probe.
|
|
|
|
components:
|
|
securitySchemes:
|
|
bearerAuth:
|
|
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
|
|
in: path
|
|
required: true
|
|
schema:
|
|
type: string
|
|
responses:
|
|
BadRequest:
|
|
description: Ogiltig input
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorEnvelope"
|
|
Unauthorized:
|
|
description: Saknad/ogiltig Bearer-token
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorEnvelope"
|
|
NotFound:
|
|
description: Resursen finns inte
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorEnvelope"
|
|
NotConfigured:
|
|
description: Integration ej konfigurerad (501)
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: "#/components/schemas/ErrorEnvelope"
|
|
schemas:
|
|
ErrorEnvelope:
|
|
type: object
|
|
required: [error]
|
|
properties:
|
|
error:
|
|
type: object
|
|
required: [code]
|
|
properties:
|
|
code:
|
|
type: string
|
|
description: error.code-envelope (t.ex. bad_json, storage_not_configured)
|
|
message:
|
|
type: string
|
|
HealthResponse:
|
|
type: object
|
|
description: >
|
|
db/engine/stripe report a real dependency probe (BACKLOG P0-3): "ok"
|
|
means a live round trip succeeded, "error" means it was configured
|
|
but unreachable (see `detail`), "not_configured" means the env var
|
|
is unset. `queue` can only ever be "not_configured" or
|
|
"not_integrated" -- no Redis client is wired in this repo, so
|
|
presence of REDIS_URL is reported honestly rather than faking a
|
|
connectivity check. `ok` is true only when no configured dependency
|
|
is in "error". This is a LIVENESS check: HTTP status stays 200
|
|
whenever the process can respond, regardless of dependency state --
|
|
see /api/ready for the readiness gate that fails closed.
|
|
required: [ok, service, db, queue, engine, stripe, ts]
|
|
properties:
|
|
ok:
|
|
type: boolean
|
|
service:
|
|
type: string
|
|
db:
|
|
type: string
|
|
enum: [ok, error, not_configured]
|
|
queue:
|
|
type: string
|
|
enum: [not_configured, not_integrated]
|
|
engine:
|
|
type: string
|
|
enum: [ok, error, not_configured]
|
|
stripe:
|
|
type: string
|
|
enum: [ok, error, not_configured]
|
|
detail:
|
|
type: object
|
|
description: Present only when `ok` is false -- one-line error message per failing dependency.
|
|
additionalProperties:
|
|
type: string
|
|
ts:
|
|
type: string
|
|
format: date-time
|
|
ReadyResponse:
|
|
type: object
|
|
description: >
|
|
Readiness (BACKLOG P0-3: "no /ready route existed"). Fails closed --
|
|
503 whenever a load-bearing dependency (today: only `db`) is not
|
|
both configured and reachable. Point a load balancer / Coolify
|
|
readiness probe here, not at /api/health.
|
|
required: [ready, service, db, queue, engine, stripe, ts]
|
|
properties:
|
|
ready:
|
|
type: boolean
|
|
service:
|
|
type: string
|
|
db:
|
|
type: string
|
|
enum: [ok, error, not_configured]
|
|
queue:
|
|
type: string
|
|
enum: [not_configured, not_integrated]
|
|
engine:
|
|
type: string
|
|
enum: [ok, error, not_configured]
|
|
stripe:
|
|
type: string
|
|
enum: [ok, error, not_configured]
|
|
ts:
|
|
type: string
|
|
format: date-time
|
|
EstimateRequest:
|
|
type: object
|
|
properties:
|
|
flow:
|
|
type: string
|
|
config:
|
|
type: object
|
|
additionalProperties: true
|
|
EstimateResponse:
|
|
type: object
|
|
properties:
|
|
estimate:
|
|
type: object
|
|
additionalProperties: true
|
|
CreateOrderRequest:
|
|
type: object
|
|
properties:
|
|
flow:
|
|
type: string
|
|
default: custom
|
|
config:
|
|
type: object
|
|
additionalProperties: true
|
|
OrderSummary:
|
|
type: object
|
|
required: [order_id, status]
|
|
properties:
|
|
order_id:
|
|
type: string
|
|
status:
|
|
type: string
|
|
deposit_ore:
|
|
type: integer
|
|
description: Deposition i öre
|
|
total_ore:
|
|
type: integer
|
|
description: Totalsumma i öre
|
|
Order:
|
|
type: object
|
|
properties:
|
|
order_id:
|
|
type: string
|
|
status:
|
|
type: string
|
|
config:
|
|
type: object
|
|
additionalProperties: true
|
|
SourceQueryRequest:
|
|
type: object
|
|
required: [tenant_id, source_id, query]
|
|
properties:
|
|
tenant_id:
|
|
type: string
|
|
description: (GAP) ska komma från session — BACKLOG P0-2
|
|
project_id:
|
|
type: string
|
|
source_id:
|
|
type: string
|
|
query:
|
|
type: string
|
|
connection_config:
|
|
type: object
|
|
additionalProperties: true
|
|
description: (GAP) SSRF-primitiv — BACKLOG P0-7
|
|
EnrichedRecord:
|
|
type: object
|
|
properties:
|
|
fields:
|
|
type: object
|
|
additionalProperties: true
|
|
provenance:
|
|
type: object
|
|
additionalProperties:
|
|
$ref: "#/components/schemas/FieldProvenance"
|
|
FieldProvenance:
|
|
type: object
|
|
required: [source_id, freshness, confidence, level]
|
|
properties:
|
|
source_id:
|
|
type: string
|
|
freshness:
|
|
type: string
|
|
format: date-time
|
|
confidence:
|
|
type: number
|
|
minimum: 0
|
|
maximum: 1
|
|
level:
|
|
type: integer
|
|
minimum: 0
|
|
maximum: 3
|
|
description: 0=ej tillgänglig · 1=licensierad · 2=authorized web · 3=officiell API/bulk
|
|
EnrichCompanyListRequest:
|
|
type: object
|
|
required: [market, entities]
|
|
properties:
|
|
market:
|
|
type: string
|
|
entities:
|
|
type: array
|
|
items:
|
|
type: object
|
|
additionalProperties: true
|
|
fields:
|
|
type: array
|
|
items:
|
|
type: string
|
|
output_artifact_type:
|
|
type: string
|
|
default: st0re.artifact
|
|
ResolveEntitiesRequest:
|
|
type: object
|
|
required: [records]
|
|
properties:
|
|
records:
|
|
type: array
|
|
items:
|
|
type: object
|
|
additionalProperties: true
|
|
threshold:
|
|
type: number
|
|
default: 0.85
|
|
algorithm:
|
|
type: string
|
|
enum: [rapidfuzz, target_spacy]
|
|
default: rapidfuzz
|
|
ProvenanceRecord:
|
|
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
|