diff --git a/src/openapi/servicediscovery.yaml b/src/openapi/servicediscovery.yaml new file mode 100644 index 00000000..999b70ff --- /dev/null +++ b/src/openapi/servicediscovery.yaml @@ -0,0 +1,200 @@ +openapi: 3.1.0 +info: + title: TI Service Discovery + description: | + Statische JSON-Ressource (`catalog.json`) zur Lokalisierung der krankenkassenspezifischen + FQDN (und damit des Diensteanbieters) für den ZETA (TI 2.0) Request-Flow. + + Dieses API-Dokument spezifiziert den Vertrag zwischen einem Primärsystem und dem + Endpunkt des TI-Service-Discovery-Dienstes. + + Der Abruf der `catalog.json` ist Voraussetzung für die in der VSDM-2-OpenAPI-Definition + beschriebenen Ressourcen-Anfragen sowie Auth-/Token-Flows. + contact: + name: gematik GmbH + url: https://www.gematik.de + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0 + version: 1.0.0 +externalDocs: + description: JSON Schema für catalog.json + url: https://github.com/gematik/spec-VSDM2/tree/main/src/schemas/catalog.schema.json +servers: + - url: https://service-discovery.prod.ti-platform.de + description: Produktivinstanz (PU) + - url: https://service-discovery.ref.ti-platform.de + description: Referenzinstanz (RU) + - url: https://service-discovery.test.ti-platform.de + description: Testinstanz (TU) + - url: https://service-discovery.dev.ti-platform.de + description: Entwicklungsinstanz (DEV) +tags: + - name: Service Discovery + description: Endpunkt zur Lokalisierung von TI-Fachdiensten. +paths: + /catalog.json: + get: + tags: + - Service Discovery + summary: TI Service Catalog abrufen + description: | + Liefert ein Mapping von IK-Nummern auf krankenkassenspezifische FQDNs + sowie die zugehörigen Service-Instanzen der TI. + + Das Dokument ist eine statische JSON-Ressource und kann über `ETag` + und `Cache-Control` Header effizient gecacht werden. + operationId: getServiceCatalog + responses: + "200": + description: OK + headers: + ETag: + description: Revisionsnummer als Entity-Tag für Caching. + schema: + type: string + example: '"rev-47"' + Cache-Control: + description: Caching-Direktive. + schema: + type: string + example: max-age=3600 + content: + application/json: + schema: + $ref: "#/components/schemas/Catalog" + example: + format_version: "1.0.0" + revision: 47 + env: prod + service_instances: + vsdm-1: + type: vsdm + url: https://prod.vsdm.ti-dienste.tk.de + erp: + type: erp + url: https://erp.ti-dienste.de + idp: + type: idp + url: https://idp.ti-dienste.de/.well-known/openid-configuration + vzd: + type: vzd + url: https://fhir-directory.ti-dienste.de/fhir + routing: + vsdm: + "101575519": vsdm-1 + "500": + description: Internal Server Error + content: + application/problem+json: + schema: + $ref: "#/components/schemas/Problem" + example: + type: https://service-discovery.ti-platform.de/errors/internal + title: Internal Server Error + status: 500 + detail: Failed to retrieve TI service discovery document. + instance: /catalog.json +components: + schemas: + Catalog: + type: object + description: TI Service Catalog — Verzeichnis aller Service-Instanzen und IK-basiertes Routing. + required: + - format_version + - revision + - env + - service_instances + additionalProperties: false + properties: + format_version: + type: string + pattern: '^[0-9]+\.[0-9]+\.[0-9]+$' + description: Semantische Versionsnummer des Formats. + examples: + - "1.0.0" + revision: + type: integer + minimum: 1 + description: Fortlaufend steigende Nummer. Wird bei jeder Änderung erhöht. + examples: + - 47 + env: + type: string + enum: + - dev + - test + - ref + - prod + description: Zielumgebung. Pro Stage/Umgebung existiert eine eigene Datei. + service_instances: + type: object + description: Map von Service-Instanz-ID auf Service-Definition. + minProperties: 1 + additionalProperties: + $ref: "#/components/schemas/ServiceInstance" + routing: + type: object + description: | + Map von Diensttyp auf Routing-Tabelle. + Jede Routing-Tabelle bildet IK-Nummern auf Service-Instanz-IDs ab. + Nur nötig wenn mehrere Instanzen eines Diensttyps existieren. + additionalProperties: + $ref: "#/components/schemas/RoutingTable" + ServiceInstance: + type: object + description: Einzelne Service-Instanz. + required: + - type + - url + additionalProperties: false + properties: + type: + type: string + pattern: '^[a-z][a-z0-9-]*$' + description: Diensttyp-Bezeichner. + examples: + - vsdm + - epa + - erp + - idp + - vzd + url: + type: string + format: uri + description: URL der Service-Instanz. + examples: + - https://dev.vsdm.ti-dienste.tk.de + RoutingTable: + type: object + description: | + Routing-Tabelle für einen Diensttyp. + Schlüssel ist eine IK-Nummer, Wert ist eine Service-Instanz-ID + die als Schlüssel in `service_instances` existieren muss. + minProperties: 1 + additionalProperties: + type: string + examples: + - "109519005": vsdm-1 + "108310400": vsdm-1 + "101575519": vsdm-2 + Problem: + type: object + description: Fehlerobjekt gemäß RFC 9457 (Problem Details for HTTP APIs). + properties: + type: + type: string + format: uri + description: URI-Referenz die den Problemtyp identifiziert. + title: + type: string + description: Kurze, menschenlesbare Zusammenfassung des Problemtyps. + status: + type: integer + description: HTTP-Statuscode für dieses Auftreten des Problems. + detail: + type: string + description: Menschenlesbare Erklärung spezifisch für dieses Auftreten. + instance: + type: string + description: Referenz die das spezifische Auftreten identifiziert. \ No newline at end of file diff --git a/src/openapi/vsdm2.yaml b/src/openapi/vsdm2.yaml index 98cbfa42..e40a3be7 100644 --- a/src/openapi/vsdm2.yaml +++ b/src/openapi/vsdm2.yaml @@ -21,34 +21,16 @@ externalDocs: description: FHIR Specification VSDM 2 url: https://simplifier.net/vsdm2 servers: - - url: https://101575519.prod.vsdm2.ti-dienste.de - description: TK Production server (PU) - - url: https://109723913.prod.vsdm2.ti-dienste.de - description: BKK VBU Production server (PU) - - url: https://{iknummer}.prod.vsdm2.ti-dienste.de - description: address schema vsdm backends - productive environment - variables: - iknummer: - default: "111111111" - description: Institutional identifier for a specific health insurer. - - url: https://{iknummer}.ref.vsdm2.ti-dienste.de - description: address schema vsdm backends - reference environment - variables: - iknummer: - default: "111111111" - description: Institutional identifier for a specific health insurer. - - url: https://{iknummer}.test.vsdm2.ti-dienste.de - description: address schema vsdm backends - test environment - variables: - iknummer: - default: "111111111" - description: Institutional identifier for a specific health insurer. - - url: https://{iknummer}.dev.vsdm2.ti-dienste.de - description: address schema vsdm backends - development environment - variables: - iknummer: - default: "111111111" - description: Institutional identifier for a specific health insurer. + - url: https://vsdm2.prod.anbieter-123.de + description: Beispieladresse zum Fachdienst VSDM 2 + - url: https://prod.vsdm.ti-dienste.tk.de + description: Techniker Krankenkasse Produktivumgebung + - url: https://ref.vsdm.ti-dienste.tk.de + description: Techniker Krankenkasse Referenzumgebung + - url: https://test.vsdm.ti-dienste.tk.de + description: Techniker Krankenkasse Testumgebung + - url: https://dev.vsdm.ti-dienste.tk.de + description: Techniker Krankenkasse Entwicklungsumgebung tags: - name: Vsdm description: Endpoint of the application "Versichertenstammdatenmanagement" (VSDM) to retrieve a VSDMBundle FHIR-Resource (Versichertenstammdaten; VSD) of a specific patient. @@ -62,6 +44,12 @@ paths: description: | Returns a VSDMBundle with VSD about a specific patient that is addressed within the PoPP-Token in the request header. + To localize the corresponding health service providers fqdn, clients are required to query + the gematik service discovery service beforehand using https://service-discovery.prod.ti-platform.de. + The service discovery document must be fetched before calling this API, this can happen completely + asynchronous and unrelated to the actual vsdm usecase. + Reference: #/src/openapi/servicediscovery.yaml + **FHIR DEVIATION NOTICE:** This endpoint deviates from standard FHIR REST patterns: - Standard FHIR: GET /Bundle/{id} @@ -134,12 +122,6 @@ paths: application/json: schema: $ref: '#/components/schemas/VSDMOperationOutcome' - '403': - description: Forbidden - content: - application/json: - schema: - $ref: '#/components/schemas/VSDMOperationOutcome' '404': description: Not Found content: @@ -152,31 +134,24 @@ paths: application/json: schema: $ref: '#/components/schemas/VSDMOperationOutcome' - '428': - description: Precondition Required - content: - application/json: - schema: - $ref: '#/components/schemas/VSDMOperationOutcome' - '500': - description: Internal Server Error + '406': + description: Not Acceptable content: application/json: schema: $ref: '#/components/schemas/VSDMOperationOutcome' - '502': - description: Bad Gateway + '428': + description: Precondition Required content: application/json: schema: $ref: '#/components/schemas/VSDMOperationOutcome' - '504': - description: Gateway Timeout + '500': + description: Internal Server Error content: application/json: schema: $ref: '#/components/schemas/VSDMOperationOutcome' - components: parameters: ETag: @@ -192,7 +167,7 @@ components: description: Base64URL encoded "Pruefziffer" schema: type: string - example: VDAyMzU5MDA1MDE3MjY3Mzc2MDFVVDLYyBOm-EDF0oe1aW_ndQe2p36MGAzvyBk + example: RGllcy1pc3QtZWluZS1CZWlzcGllbC1QcsO8ZnppZmZlci1uYWNoLUFfMjY3OTAh schemas: GetVSDMBundleResponse: description: Response including the requested VSDMBundle @@ -202,265 +177,247 @@ components: $ref: '#/components/schemas/VSDMBundle' VSDMBundle: type: object - description: 'https://gematik.de/fhir/vsdm2/StructureDefinition/VSDMBundle' - examples: - [ - { - "resourceType": "Bundle", - "id": "9b6ac30d-246d-4eab-af83-544564792089", - "meta": { - "profile": [ - "https://gematik.de/fhir/vsdm2/StructureDefinition/VSDMBundle" - ] - }, - "type": "document", - "identifier": { - "system": "urn:ietf:rfc:3986", - "value": "urn:uuid:9b6ac30d-246d-4eab-af83-544564792089" - }, - "signature": { - "sigFormat": "application/pkcs7-mime", - "who": { - "identifier": { - "system": "https://fhir.de/sid/arge-ik/iknr", - "value": "12345678" - } - }, - "type": [ - { - "system": "urn:iso-astm:E1762-95:2013", - "code": "1.2.840.10065.1.12.1.7", - "display": "Consent Signature" - } - ], - "when": "2023-11-03T12:02:23.157+01:00", - "data": "dGhpcyBibG9iIGlzIHNuaXBwZWQ=" - }, - "timestamp": "2023-11-03T12:02:23.157+01:00", - "entry": [ - { - "fullUrl": "https://gematik.de/fhir/Composition/c624cf47-e235-4624-af71-0a09dc9254dc", - "resource": { - "resourceType": "Composition", - "id": "c624cf47-e235-4624-af71-0a09dc9254dc", - "meta": { - "profile": [ - "https://gematik.de/fhir/vsdm2/StructureDefinition/VSDMComposition" - ] - }, - "status": "final", - "author": [ - { - "identifier": { - "system": "https://fhir.de/sid/arge-ik/iknr", - "value": "12345678" - } - } - ], - "type": { - "coding": [ - { - "code": "not-applicable", - "system": "https://terminology.hl7.org/CodeSystem/data-absent-reason" - } - ] - }, - "date": "2023-11-03T12:02:23.157+01:00", - "title": "VSDM 2 data", - "section": [ - { - "entry": [ + description: 'https://gematik.de/fhir/vsdm2/StructureDefinition/VSDMBundle|1.0.0-rc8' + examples: [ + { + "resourceType": "Bundle", + "id": "019aa690-d14a-79a3-a078-3807df1b87f4", + "meta": { + "profile": [ + "https://gematik.de/fhir/vsdm2/StructureDefinition/VSDMBundle|1.0.0-rc8" + ], + "lastUpdated": "2025-07-14T15:16:17.890+01:00" + }, + "type": "collection", + "timestamp": "2025-07-14T15:16:17.890+01:00", + "entry": [ + { + "fullUrl": "https://gematik.de/fhir/Patient/019aa694-9c4e-7540-be3c-0ef324476863", + "resource": { + "resourceType": "Patient", + "id": "019aa694-9c4e-7540-be3c-0ef324476863", + "meta": { + "profile": [ + "https://gematik.de/fhir/vsdm2/StructureDefinition/VSDMPatient|1.0.0-rc8" + ] + }, + "identifier": [ + { + "system": "http://fhir.de/sid/gkv/kvid-10", + "value": "A123456780" + } + ], + "name": [ + { + "use": "official", + "text": "Andrea Amsel", + "family": "Amsel", + "_family": { + "extension": [ { - "reference": "Patient/437f2555-2396-4c64-a656-e9553161ca3c" + "url": "http://hl7.org/fhir/StructureDefinition/humanname-own-name", + "valueString": "Amsel" } ] }, - { - "entry": [ - { - "reference": "Coverage/2d4da53a-413a-48fe-b908-2e67b5761523" - } - ] - } - ] - } - }, - { - "fullUrl": "https://gematik.de/fhir/Patient/437f2555-2396-4c64-a656-e9553161ca3c", - "resource": { - "resourceType": "Patient", - "id": "437f2555-2396-4c64-a656-e9553161ca3c", - "meta": { - "profile": [ - "https://gematik.de/fhir/vsdm2/StructureDefinition/VSDMPatient" + "given": [ + "Andrea" ] - }, - "name": [ - { - "use": "official", - "family": "Königstein", - "_family": { + } + ], + "address": [ + { + "type": "physical", + "line": [ + "Amselweg 1" + ], + "_line": [ + { "extension": [ { - "url": "https://hl7.org/fhir/StructureDefinition/humanname-own-name", - "valueString": "Königstein" + "url": "http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-houseNumber", + "valueString": "1" + }, + { + "url": "http://hl7.org/fhir/StructureDefinition/iso21090-ADXP-streetName", + "valueString": "Amselweg" } ] - }, - "given": [ - "Ludger" - ] - } - ], - "identifier": [ - { - "system": "https://fhir.de/sid/gkv/kvid-10", - "value": "T024791905" - } - ], - "address": [ - { - "line": [ - "Blumenweg 14" - ], - "_line": [ + } + ], + "city": "Aachen", + "postalCode": "52070", + "country": "Deutschland", + "_country": { + "extension": [ { - "extension": [ - { - "url": "https://hl7.org/fhir/StructureDefinition/iso21090-ADXP-houseNumber", - "valueString": "14" - }, - { - "url": "https://hl7.org/fhir/StructureDefinition/iso21090-ADXP-streetName", - "valueString": "Blumenweg" - } - ] + "url": "http://hl7.org/fhir/StructureDefinition/iso21090-codedString", + "valueCoding": { + "code": "DE", + "system": "urn:iso:std:iso:3166" + } + }, + { + "url": "http://hl7.org/fhir/StructureDefinition/iso21090-codedString", + "valueCoding": { + "code": "D", + "system": "http://fhir.de/CodeSystem/deuev/anlage-8-laenderkennzeichen" + } } - ], - "type": "both", - "city": "Esens", - "postalCode": "26427", - "country": "D" - } - ], - "birthDate": "1935-06-22", - "telecom": [ - { - "system": "url", - "value": "matrix:@T024791905:aok-nord.de" - } - ], - "photo": [ - { - "contentType": "image/gif", - "data": "R0lGODlhEwARAPcAAAAAAAAA/+" + ] } + } + ], + "birthDate": "1997-12-28", + "gender": "female" + } + }, + { + "fullUrl": "https://gematik.de/fhir/Coverage/019aa696-775a-7062-8e34-ad28ac640060", + "resource": { + "resourceType": "Coverage", + "id": "019aa696-775a-7062-8e34-ad28ac640060", + "meta": { + "profile": [ + "https://gematik.de/fhir/vsdm2/StructureDefinition/VSDMCoverageGKV|1.0.0-rc8" ] - } - }, - { - "fullUrl": "https://gematik.de/fhir/Coverage/2d4da53a-413a-48fe-b908-2e67b5761523", - "resource": { - "resourceType": "Coverage", - "id": "2d4da53a-413a-48fe-b908-2e67b5761523", - "meta": { - "profile": [ - "https://gematik.de/fhir/vsdm2/StructureDefinition/VSDMCoverage" - ] - }, - "status": "active", - "payor": [ + }, + "type": { + "coding": [ { - "identifier": { - "system": "https://fhir.de/sid/arge-ik/iknr", - "value": "12345678" - }, - "display": "Test GKV Krankenkasse" + "code": "GKV", + "system": "http://fhir.de/CodeSystem/versicherungsart-de-basis", + "display": "gesetzliche Krankenversicherung" } - ], - "extension": [ - { - "url": "https://gematik.de/fhir/vsdm2/StructureDefinition/VSDMFestzuschusshoeheEX", - "valueCoding": { - "code": "1", - "system": "https://gematik.de/fhir/vsdm2/CodeSystem/VSDMFestzuschusshoeheCS", - "display": "70 % / fünf Jahre durchgehend" - } + ] + }, + "extension": [ + { + "url": "http://fhir.de/StructureDefinition/gkv/wop", + "valueCoding": { + "system": "https://fhir.kbv.de/CodeSystem/KBV_CS_SFHIR_ITA_WOP", + "code": "38", + "display": "Nordrhein" } - ], - "type": { - "coding": [ - { - "system": "https://fhir.de/CodeSystem/versicherungsart-de-basis", - "code": "GKV", - "display": "Gesetzliche Krankenversicherung" - } - ] - }, - "period": { - "start": "2022-04-01", - "end": "2027-07-31" }, - "beneficiary": { - "reference": "Patient/437f2555-2396-4c64-a656-e9553161ca3c" + { + "url": "http://fhir.de/StructureDefinition/gkv/versichertenart", + "valueCoding": { + "code": "1", + "system": "https://fhir.kbv.de/CodeSystem/KBV_CS_SFHIR_KBV_VERSICHERTENSTATUS", + "display": "Mitglieder" + } } + ], + "payor": [ + { + "identifier": { + "system": "http://fhir.de/sid/arge-ik/iknr", + "value": "104178397" + }, + "reference": "https://gematik.de/fhir/Organization/019aa692-9527-7cd9-8a94-0370d748ead9", + "display": "Beispielkostenträger Aachen" + } + ], + "status": "active", + "beneficiary": { + "reference": "https://gematik.de/fhir/Patient/019aa694-9c4e-7540-be3c-0ef324476863" + }, + "period": { + "start": "1997-12-28" } } - ] - } - ] + }, + { + "fullUrl": "https://gematik.de/fhir/Organization/019aa692-9527-7cd9-8a94-0370d748ead9", + "resource": { + "resourceType": "Organization", + "id": "019aa692-9527-7cd9-8a94-0370d748ead9", + "meta": { + "profile": [ + "https://gematik.de/fhir/vsdm2/StructureDefinition/VSDMPayorOrganization|1.0.0-rc8" + ] + }, + "identifier": [ + { + "system": "http://fhir.de/sid/arge-ik/iknr", + "value": "104178397" + } + ], + "address": [ + { + "country": "Deutschland", + "_country": { + "extension": [ + { + "url": "http://hl7.org/fhir/StructureDefinition/iso21090-codedString", + "valueCoding": { + "code": "DE", + "system": "urn:iso:std:iso:3166" + } + }, + { + "url": "http://hl7.org/fhir/StructureDefinition/iso21090-codedString", + "valueCoding": { + "code": "D", + "system": "http://fhir.de/CodeSystem/deuev/anlage-8-laenderkennzeichen" + } + } + ] + } + } + ], + "name": "Beispielkostenträger Aachen" + } + } + ] + } + ] VSDMOperationOutcome: type: object - description: 'https://gematik.de/fhir/vsdm2/StructureDefinition/VSDMOperationOutcome' - examples: - [ - { - "resourceType": "OperationOutcome", - "id": "example-vsdm-operationoutcome", - "meta": { - "profile": [ - "https://gematik.de/fhir/vsdm2/StructureDefinition/VSDMOperationOutcome" - ] - }, - "issue": [ + description: 'https://gematik.de/fhir/vsdm2/StructureDefinition/VSDMOperationOutcome|1.0.0-rc8' + examples: [ + { + "resourceType": "OperationOutcome", + "id": "VSDMOperationOutcome-UnknownIK", + "meta": { + "profile": [ + "https://gematik.de/fhir/vsdm2/StructureDefinition/VSDMOperationOutcome|1.0.0-rc8" + ] + }, + "text": { + "status": "generated", + "div": "
Der von Ihrem Anwendungssystem vorgelegte elektronische Nachweis des Versorgungskontexts ist fehlerhaft. Bitte wenden Sie sich an Ihren Systemhersteller.
" + }, + "issue": [ + { + "severity": "error", + "code": "not-found", + "details": { + "coding": [ { - "severity": "fatal", - "code": "invalid", - "details": { - "coding": [ - { - "system": "https://gematik.de/fhir/vsdm2/CodeSystem/VSDMErrorcodeCS", - "code": "VSDSERVICE_INVALID_IK", - "display": "Ungültige oder nicht bekannte Institutionskennung ." - } - ], - "text": "Nachweis zum Versorgungskontext mittels eGK oder GesundheitsID am PoPP-Service 1 x erneuern. Bei erneutem Fehler: Abbruch, da wahrscheinlich ein Implementierungsfehler vorliegt (Clientsystem oder PoPP-Service) oder die KTR gar nicht bei diesem FD-Anbieter ist (fehlerhafter DNS-Eintrag)." - } + "code": "VSDSERVICE_UNKNOWN_IK", + "system": "https://gematik.de/fhir/vsdm2/CodeSystem/VSDMErrorcodeCS", + "display": "Institutionskennung [ik] aus dem PoPP-Token ist dem Fachdienst nicht bekannt." } + ], + "text": "Institutionskennung 103456789 aus dem PoPP-Token ist dem Fachdienst nicht bekannt." + }, + "diagnostics": "Die im PoPP-Token angegebene IK der Versicherung ist dem angesprochenen VSDM 2.0-Fachdienst nicht bekannt.\nFordern Sie ein neues PoPP-Token an. Wiederholen Sie die Dienstlokalisierung, um den korrekten zuständigen Fachdienst zu ermitteln und wiederholen Sie die Abfrage.\nBei erneutem Fehler wiederholen Sie die Abfrage mit größerem zeitlichen Abstand, um eventuell geänderte DNS-Einstellungen wirksam werden zu lassen. Halten Sie die Anwender über den Status informiert.\nBei Andauern des Fehlers über 24 h liegt möglicherweise ein Fehler in der Implementierung des Clientsystems oder des Fachdients vor.", + "expression": [ + "http.ZETA-PoPP-Token-Content.insurerId" ] - } - ] - ErrorType: - description: Error object with additional information about the occurred error - type: object - properties: - errorCode: - description: Error condition specifier - type: string - examples: [unauthorized, forbidden, internalError] - errorDetail: - description: Additional details regarding the error condition (if applicable) - type: string - examples: [User is not authorized, Request is forbidden, Server cannot handle request for now] - required: - - errorCode + } + ] + } + ] securitySchemes: oAuthVsdm: type: oauth2 description: This API uses OAuth 2, to gain access clients need an Access-Token and to proof "Versorgungskontext" with a PoPP-Token in addition flows: authorizationCode: - authorizationUrl: https://101575519.prod.vsdm2.ti-dienste.de/auth - tokenUrl: https://101575519.prod.vsdm2.ti-dienste.de/token + authorizationUrl: https://vsdm2.prod.anbieter-123.de/auth + tokenUrl: https://vsdm2.prod.anbieter-123.de/token scopes: vsdservice: allows practitioners to access the VSDService API of the "Versichertenstammdatendienst" \ No newline at end of file diff --git a/src/schemas/catalog.schema.json b/src/schemas/catalog.schema.json new file mode 100644 index 00000000..d5648778 --- /dev/null +++ b/src/schemas/catalog.schema.json @@ -0,0 +1,80 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://service-discovery.prod.ti-platform.de/schema/catalog.schema.json", + "title": "TI Service Catalog Version 0.9.2", + "description": "Machine-readable catalog of Telematikinfrastruktur service instances and routing rules. Last updated 26.03.2026", + "type": "object", + "required": ["format_version", "updated_at", "env", "service_instances"], + "additionalProperties": false, + "properties": { + "format_version": { + "type": "string", + "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$", + "description": "Semantic version of the catalog format.", + "examples": ["1.0.0"] + }, + "updated_at": { + "type": "integer", + "minimum": 1774508400, + "description": "Unix Epoch Timestamp from the moment this file was last generated. Shall be updated when higher than previous value." + }, + "env": { + "type": "string", + "enum": ["gemdev","dev", "test", "ref", "prod"], + "description": "Target instance. One catalog file per instance." + }, + "service_instances": { + "type": "object", + "description": "Map of service instance ID to service definition.", + "minProperties": 1, + "additionalProperties": { + "$ref": "#/$defs/service_instance" + } + }, + "routing": { + "type": "object", + "description": "Map of service type to routing table. Each routing table maps a selector value (e.g. IK-Nr) to a service instance ID.", + "additionalProperties": { + "$ref": "#/$defs/routing_table" + } + } + }, + "$defs": { + "service_instance": { + "type": "object", + "required": ["type", "url"], + "additionalProperties": false, + "properties": { + "type": { + "type": "string", + "pattern": "^[a-z][a-z0-9-]*$", + "description": "Service type identifier.", + "examples": [ + "epa", + "erp", + "vsdm", + "idp", + "vzd", + "federation-master", + "tsl-download", + "fhir-directory" + ] + }, + "url": { + "type": "string", + "format": "uri", + "description": "Service URL. Base URL or full endpoint depending on service type." + } + } + }, + "routing_table": { + "type": "object", + "description": "Maps selector values to service instance IDs. Keys are selector values (e.g. IK-Nr), values are service instance IDs that must exist in service_instances.", + "minProperties": 1, + "additionalProperties": { + "type": "string", + "description": "Service instance ID. Must be a key in service_instances." + } + } + } +} \ No newline at end of file