travail-des-demandes
Interface synchrone (OpenAPI) — version 0.1.0. Producteur : relation-tiers. Consommateurs déclarés : back-office, operations, tenue-de-compte.
Quatre objets distincts, jamais confondus : la demande (unité durable de suivi d’une attente adressée au teneur), l’échange (message immuable sur son canal), le dossier (vue commune) et le traitement métier (exécuté par le domaine compétent). La réception ne bloque jamais ; les originaux sont immuables, les corrections sont des ajouts liés ; un dépassement d’échéance n’est jamais supprimé ; le contenu libre ne traverse pas les listes.
La spécification
Section intitulée « La spécification »openapi: 3.1.0info: title: relation-tiers — le travail des demandes version: 0.1.0 summary: >- Les demandes et leurs transitions, les échanges et la chronologie omnicanale, les objets métier liés, les échéances et engagements, les traitements externes et les réponses avec leur preuve de remise. description: >- Quatre objets distincts, jamais confondus : la demande (unité durable de suivi d'une attente adressée au teneur), l'échange (message immuable sur son canal), le dossier (vue commune) et le traitement métier (exécuté par le domaine compétent). La réception ne bloque jamais ; les originaux sont immuables, les corrections sont des ajouts liés ; un dépassement d'échéance n'est jamais supprimé ; le contenu libre ne traverse pas les listes. x-producteurs: - relation-tiers x-consommateurs: - composant: back-office statut: pressenti — files de demandes, dossier relationnel, chronologie omnicanale - composant: operations statut: pressenti — accusé et résultat des traitements demandés - composant: tenue-de-compte statut: pressenti — accusé et résultat des traitements demandés x-ruptures: [] # première version publiée — aucune rupturepaths: /relation-tiers/v1/requests: post: operationId: creerUneDemande summary: >- Créer une demande — référence d'échange source, sentAt, receivedAt, originChannel, demandeur éventuel, classification initiale ; l'absence d'identité ne bloque pas la réception. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreationDeDemande' responses: '201': description: La demande est durablement reçue. content: application/json: schema: $ref: '#/components/schemas/Demande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests/{requestId}: get: operationId: consulterUneDemande summary: Consulter l'état — la réponse porte un ETag (version d'agrégat). security: - authentification: [relation-tiers:consultation] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' responses: '200': description: La demande. content: application/json: schema: $ref: '#/components/schemas/Demande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } /relation-tiers/v1/requests:search: get: operationId: rechercherDesDemandes summary: >- Rechercher par acteurs, objets, canaux, catégories, états, affectations et délais — curseur opaque, tri stable terminé par l'identifiant. security: - authentification: [relation-tiers:consultation] parameters: - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/curseur' - $ref: '#/components/parameters/limite' - name: actorId in: query schema: { type: string } - name: status in: query schema: { type: string } - name: categoryCode in: query schema: { type: string } - name: queueId in: query schema: { type: string } - name: objectDomain in: query schema: { type: string } - name: objectType in: query schema: { type: string } - name: objectId in: query schema: { type: string } - name: originChannel in: query schema: { type: string } - name: receivedFrom in: query schema: { type: string, format: date-time } - name: receivedTo in: query schema: { type: string, format: date-time } - name: breached in: query schema: { type: boolean } responses: '200': description: La page de demandes. content: application/json: schema: $ref: '#/components/schemas/PageDeDemandes' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } /relation-tiers/v1/requests/{requestId}:identify-requester: post: operationId: qualifierLeDemandeur summary: >- Qualifier le demandeur — émetteur matériel, représenté, bénéficiaire ; l'état d'identification passe de NON_IDENTIFIE/DECLARE à RAPPROCHE ou VERIFIE. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' - $ref: '#/components/parameters/versionAttendue' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/QualificationDuDemandeur' responses: '200': description: Le demandeur est qualifié. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests/{requestId}:qualify: post: operationId: qualifierUneDemande summary: >- Catégoriser et prioriser — taxonomie versionnée ; une expression de mécontentement n'est pas reclassée pour éviter un délai ; une requalification ne remplace pas l'événement de départ des échéances. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' - $ref: '#/components/parameters/versionAttendue' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/QualificationDeDemande' responses: '200': description: La qualification est acceptée. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests/{requestId}:assign: post: operationId: affecterUneDemande summary: Affecter — une affectation courante par nature, historique conservé. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' - $ref: '#/components/parameters/versionAttendue' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Affectation' responses: '200': description: L'affectation est active. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests/{requestId}:transfer: post: operationId: transfererUneDemande summary: Transférer — changement de responsabilité motivé, files source et cible. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' - $ref: '#/components/parameters/versionAttendue' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Transfert' responses: '200': description: La responsabilité a changé. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests/{requestId}:escalate: post: operationId: escaladerUneDemande summary: Escalader — niveau relevé, motif ; l'escalade reste après clôture. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' - $ref: '#/components/parameters/versionAttendue' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CommandeMotivee' responses: '200': description: Le niveau d'escalade est relevé. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests/{requestId}:resolve: post: operationId: enregistrerLaResolution summary: >- Enregistrer la résolution — le résultat nécessaire est disponible, ou une décision motivée établit qu'aucune action n'est possible. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' - $ref: '#/components/parameters/versionAttendue' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CommandeMotivee' responses: '200': description: La demande est résolue. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests/{requestId}:close: post: operationId: cloturerUneDemande summary: >- Clôturer — jamais sans résolution, jamais avec un traitement requis encore actif ; les échéances et dépassements sont figés. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' - $ref: '#/components/parameters/versionAttendue' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CommandeMotivee' responses: '200': description: Le suivi est terminé. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests/{requestId}:reopen: post: operationId: rouvrirUneDemande summary: Réouvrir — append-only, le motif est exigé, l'histoire close demeure. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' - $ref: '#/components/parameters/versionAttendue' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CommandeMotivee' responses: '200': description: Le suivi reprend. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests/{requestId}:cancel: post: operationId: annulerUneDemande summary: Annuler avec motif — l'annulation n'efface rien. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' - $ref: '#/components/parameters/versionAttendue' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CommandeMotivee' responses: '200': description: La demande est annulée. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests:merge: post: operationId: regrouperDesDemandes summary: >- Désigner un doublon logique — la secondaire passe à ANNULEE_DOUBLON, référence la principale, garde ses échanges ; la principale retient la contrainte la plus exigeante. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' requestBody: required: true content: application/json: schema: type: object required: [primaryRequestId, secondaryRequestIds, reasonCode] properties: primaryRequestId: { type: string } secondaryRequestIds: type: array items: { type: string } reasonCode: { type: string } responses: '200': description: Le doublon logique est établi. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests/{requestId}:split: post: operationId: dissocierUneDemande summary: >- Créer des demandes dérivées — la source reste consultable, les échanges sont rattachés explicitement, objets et échéances répartis, transition motivée. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' - $ref: '#/components/parameters/versionAttendue' requestBody: required: true content: application/json: schema: type: object required: [derivedRequests, reasonCode] properties: derivedRequests: type: array items: $ref: '#/components/schemas/CreationDeDemande' reasonCode: { type: string } responses: '200': description: Les demandes dérivées sont créées. content: application/json: schema: type: object required: [sourceRequestId, derivedRequestIds] properties: sourceRequestId: { type: string } derivedRequestIds: type: array items: { type: string } '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests/{requestId}/timeline: get: operationId: consulterLaChronologie summary: >- La chronologie autorisée — échanges, transitions, traitements, réponses, échéances, dans l'ordre des faits ; ce qu'elle restitue dépend de l'habilitation et de la finalité, le contenu libre n'y figure jamais. security: - authentification: [relation-tiers:consultation] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/curseur' - $ref: '#/components/parameters/limite' responses: '200': description: La chronologie autorisée. content: application/json: schema: $ref: '#/components/schemas/Chronologie' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } /relation-tiers/v1/interactions: post: operationId: enregistrerUnEchange summary: >- Enregistrer un échange entrant, sortant ou interne — direction, canal, horodatages, participants ou auteur inconnu ; le connecteur fournit transportMessageId, empreinte et référence de contenu ; la clé d'idempotence empêche un second échange. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreationDEchange' responses: '201': description: L'échange est durable — l'original est immuable. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/interactions/{interactionId}: get: operationId: consulterUnEchange summary: Consulter les métadonnées et le contenu autorisé. security: - authentification: [relation-tiers:consultation] parameters: - $ref: '#/components/parameters/interactionId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' responses: '200': description: L'échange. content: application/json: schema: $ref: '#/components/schemas/Echange' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } /relation-tiers/v1/interactions:search: get: operationId: rechercherDesEchanges summary: >- Recherche filtrée — acteur, canal, direction, période ; les valeurs de coordonnées et le contenu libre sont masqués. security: - authentification: [relation-tiers:consultation] parameters: - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/curseur' - $ref: '#/components/parameters/limite' - name: actorId in: query schema: { type: string } - name: channel in: query schema: { type: string } - name: direction in: query schema: { $ref: '#/components/schemas/DirectionDEchange' } - name: businessFrom in: query schema: { type: string, format: date-time } - name: businessTo in: query schema: { type: string, format: date-time } responses: '200': description: La page d'échanges. content: application/json: schema: $ref: '#/components/schemas/PageDEchanges' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } /relation-tiers/v1/interactions/{interactionId}:correct: post: operationId: corrigerUnEchange summary: >- Ajouter une correction — l'original est immuable, la correction est un dérivé relié. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/interactionId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CommandeMotivee' responses: '200': description: La correction est ajoutée, reliée à l'original. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests/{requestId}/interaction-links: post: operationId: rattacherUnEchange summary: >- Rattacher un échange à la demande — l'échange est persisté avant son rattachement, le lien est idempotent. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' requestBody: required: true content: application/json: schema: type: object required: [interactionId, role] properties: interactionId: { type: string } role: { type: string } responses: '201': description: Le lien est actif. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests/{requestId}/interaction-links/{linkId}:detach: post: operationId: detacherUnEchange summary: >- Détacher avec motif — l'ancien lien est clos RATTACHE_PAR_ERREUR, jamais supprimé ; les messages hors ordre ne refusionnent pas. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/linkId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CommandeMotivee' responses: '200': description: Le lien est clos avec son motif. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests/{requestId}/business-object-links: post: operationId: rattacherUnObjetMetier summary: >- Rattacher un objet externe — référence typée {domain, objectType, objectId} et finalité (CONCERNE, FONDE, RESULTAT_DE, PREUVE_DE, A_CORRIGER) ; l'état détaillé de l'objet n'est jamais importé. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/LienDObjetMetier' responses: '201': description: Le lien est accepté. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests/{requestId}/business-object-links/{linkId}: delete: operationId: cloturerUnLienDObjetMetier summary: >- Clôturer un lien, sans effacer l'histoire — le verbe est celui du catalogue, la sémantique est une clôture datée et motivée. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/linkId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' responses: '200': description: Le lien est clos, l'histoire demeure. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } /relation-tiers/v1/requests/{requestId}/deadlines: post: operationId: materialiserUneEcheance summary: >- Matérialiser une échéance — règle et version citées, événement de départ, calendrier versionné ; un dépassement n'est jamais supprimé. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/MaterialisationDEcheance' responses: '201': description: L'échéance est matérialisée. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests/{requestId}/commitments: post: operationId: enregistrerUnEngagement summary: Enregistrer un engagement de service pris envers le demandeur. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' requestBody: required: true content: application/json: schema: type: object required: [commitmentType, dueAt] properties: commitmentType: { type: string } dueAt: { type: string, format: date-time } comment: { type: string } responses: '201': description: L'engagement est enregistré. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/requests/{requestId}/reminders: post: operationId: planifierUneRelance summary: Planifier ou enregistrer une relance — datée, motivée, tracée. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' requestBody: required: true content: application/json: schema: type: object required: [plannedAt] properties: plannedAt: { type: string, format: date-time } executedAt: { type: string, format: date-time } interactionId: { type: string } comment: { type: string } responses: '201': description: La relance est planifiée ou enregistrée. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/business-objects/{domain}/{objectType}/{objectId}/requests: get: operationId: consulterLesDemandesDUnObjet summary: Les demandes liées à un objet métier externe — références typées. security: - authentification: [relation-tiers:consultation] parameters: - name: domain in: path required: true schema: { type: string } - name: objectType in: path required: true schema: { type: string } - name: objectId in: path required: true schema: { type: string } - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/curseur' - $ref: '#/components/parameters/limite' responses: '200': description: Les demandes liées. content: application/json: schema: $ref: '#/components/schemas/PageDeDemandes' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } /relation-tiers/v1/requests/{requestId}/external-treatments: post: operationId: demanderUnTraitement summary: >- Demander un traitement au domaine compétent — commande canonique idempotente ; la Relation tiers suit, elle n'exécute pas ; l'appel au domaine cible n'est pas dans la transaction (outbox). security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DemandeDeTraitement' responses: '201': description: Le traitement est demandé. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/external-treatments/{treatmentId}:acknowledge: post: operationId: accuserUnTraitement summary: L'accusé du domaine cible — acceptation ou rejet motivé. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/treatmentId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' requestBody: required: true content: application/json: schema: type: object required: [accepted] properties: accepted: { type: boolean } sourceTreatmentId: { type: string } reasonCode: { type: string } responses: '200': description: L'accusé est enregistré. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/external-treatments/{treatmentId}:record-result: post: operationId: enregistrerUnResultatDeTraitement summary: >- Le résultat ou l'erreur — un résultat en erreur reste ; une API entrante peut être remplacée par un événement consommé, les invariants sont identiques. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/treatmentId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ResultatDeTraitement' responses: '200': description: Le résultat est enregistré. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/external-treatments/{treatmentId}:record-correction: post: operationId: enregistrerUneRegularisation summary: >- La régularisation liée — un nouveau résultat lié au précédent, jamais une réécriture. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/treatmentId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/ResultatDeTraitement' responses: '200': description: La régularisation est enregistrée, liée au résultat corrigé. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/external-treatments/{treatmentId}: get: operationId: consulterUnTraitement summary: Le suivi canonique — commande, accusés, résultats et régularisations. security: - authentification: [relation-tiers:consultation] parameters: - $ref: '#/components/parameters/treatmentId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' responses: '200': description: Le traitement suivi. content: application/json: schema: $ref: '#/components/schemas/Traitement' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } /relation-tiers/v1/requests/{requestId}/responses: post: operationId: creerUnProjetDeReponse summary: Créer un projet sourcé — les sources sont citées dès le projet. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/requestId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' requestBody: required: true content: application/json: schema: type: object required: [sources] properties: sources: type: array items: type: object required: [sourceType, reference] properties: sourceType: { type: string } reference: { type: string } summaryRef: { type: string } responses: '201': description: Le projet est disponible. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/responses/{responseId}:validate: post: operationId: validerUneReponse summary: >- Valider selon la règle — la validation rend la réponse prête à émettre ; une erreur d'envoi ultérieure ne la ramène pas au brouillon. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/responseId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' - $ref: '#/components/parameters/versionAttendue' responses: '200': description: La validation est acquise. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/responses/{responseId}:reject: post: operationId: rejeterUneReponse summary: Rejeter ou demander correction — motif exigé. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/responseId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' - $ref: '#/components/parameters/versionAttendue' requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CommandeMotivee' responses: '200': description: La réponse est rejetée ou renvoyée en correction. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/responses/{responseId}:send: post: operationId: demanderLEmission summary: >- Demander l'émission — le connecteur envoie puis enregistre l'échange sortant et la preuve ; l'émission suppose la validation exigée par la règle. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/responseId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' - $ref: '#/components/parameters/versionAttendue' responses: '200': description: L'émission est demandée. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/responses/{responseId}:record-delivery: post: operationId: enregistrerLaRemise summary: Enregistrer l'émission ou la remise — échange sortant et preuve liés. security: - authentification: [relation-tiers:demandes] parameters: - $ref: '#/components/parameters/responseId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' - $ref: '#/components/parameters/idempotence' requestBody: required: true content: application/json: schema: type: object required: [deliveryStatus] properties: deliveryStatus: { type: string } interactionId: { type: string } evidenceRef: { type: string } deliveredAt: { type: string, format: date-time } responses: '200': description: L'émission ou la remise est enregistrée. content: application/json: schema: $ref: '#/components/schemas/ResultatDeCommande' '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' } '409': { $ref: '#/components/responses/conflit' } '422': { $ref: '#/components/responses/inapplicable' } /relation-tiers/v1/responses/{responseId}/evidence: get: operationId: restituerLesPreuvesDUneReponse summary: Restituer les sources et preuves — versions citées, remise prouvée. security: - authentification: [relation-tiers:consultation] parameters: - $ref: '#/components/parameters/responseId' - $ref: '#/components/parameters/tenant' - $ref: '#/components/parameters/correlation' responses: '200': description: Les sources et preuves de la réponse. content: application/json: schema: type: object required: [responseId, sources] properties: responseId: { type: string } sources: type: array items: { type: object } deliveryEvidence: type: array items: { type: object } '401': { $ref: '#/components/responses/nonAuthentifie' } '403': { $ref: '#/components/responses/nonAutorise' } '404': { $ref: '#/components/responses/introuvable' }components: securitySchemes: authentification: type: http scheme: bearer description: >- Tout appel est authentifié (401) et autorisé par famille d'accès (403 hors famille) — chaque opération déclare sa famille en portée, sous la forme relation-tiers:famille. Ce contrat ouvre relation-tiers:demandes (écritures du travail de dossier) et relation-tiers:consultation (lectures). Le tenant vient du jeton ; un X-Tenant-Id éventuel doit être identique. Le mécanisme est OIDC ; sa déclinaison relève de l'assemblage. parameters: tenant: name: X-Tenant-Id in: header required: false description: >- Facultatif — le tenant fait foi dans le jeton ; s'il est fourni, il doit être identique, et le corps ne peut jamais le choisir. schema: type: string correlation: name: X-Correlation-Id in: header required: false schema: type: string idempotence: name: Idempotency-Key in: header required: true description: >- La clé d'idempotence de la commande — liée à l'intention métier, pas à la tentative réseau. schema: type: string versionAttendue: name: If-Match in: header required: true description: La version d'agrégat attendue — 409 CONCURRENT_MODIFICATION sinon. schema: type: string curseur: name: cursor in: query required: false schema: type: string limite: name: limit in: query required: false schema: type: integer maximum: 200 requestId: name: requestId in: path required: true schema: { type: string } interactionId: name: interactionId in: path required: true schema: { type: string } linkId: name: linkId in: path required: true schema: { type: string } treatmentId: name: treatmentId in: path required: true schema: { type: string } responseId: name: responseId in: path required: true schema: { type: string } responses: nonAuthentifie: description: Aucune identité présentée (401). nonAutorise: description: >- L'identité présentée n'a pas la famille d'accès requise (403). Les 403 croisés entre familles sont prouvés par les tests d'assemblage. Un écart de tenant sur une ressource produit 404 (ne rien révéler), jamais ce code. introuvable: description: >- Ressource absente ou invisible — y compris une ressource d'un autre tenant (le régime de la muraille). content: application/json: schema: $ref: '#/components/schemas/Probleme' conflit: description: >- Version obsolète, chevauchement interdit ou clé d'idempotence réutilisée avec un contenu différent. content: application/json: schema: $ref: '#/components/schemas/Probleme' inapplicable: description: >- Donnée comprise mais non admissible — règle identifiée, référence externe non résolue ou preuve insuffisante. content: application/json: schema: $ref: '#/components/schemas/Probleme' schemas: Probleme: type: object description: L'enveloppe d'erreur du catalogue (Problem Details). required: [type, title, status, code, correlationId] properties: type: { type: string } title: { type: string } status: { type: integer } code: { type: string } detail: { type: string } instance: { type: string } correlationId: { type: string } retryable: { type: boolean } violations: type: array items: type: object properties: field: { type: string } reason: { type: string } ruleId: { type: string } DirectionDEchange: type: string enum: [INBOUND, OUTBOUND, INTERNAL] CreationDeDemande: type: object required: [originChannel, receivedAt] properties: sourceInteractionId: { type: string } sentAt: { type: string, format: date-time } receivedAt: { type: string, format: date-time } originChannel: { type: string } requester: $ref: '#/components/schemas/Demandeur' initialCategoryCode: { type: string } sensitivityClassification: { type: string } descriptionRef: type: string description: >- Référence documentaire du contenu — le contenu libre ne traverse pas ce contrat. Demandeur: type: object properties: emitterActorId: { type: string } representedActorId: { type: string } beneficiaryActorId: { type: string } identificationStatus: type: string enum: [NON_IDENTIFIE, DECLARE, RAPPROCHE, VERIFIE, CONTESTE] Demande: type: object required: [requestId, status, originChannel, receivedAt, aggregateVersion] properties: requestId: { type: string } readableReference: { type: string } status: { type: string } originChannel: { type: string } sentAt: { type: string, format: date-time } receivedAt: { type: string, format: date-time } requester: $ref: '#/components/schemas/Demandeur' categoryCode: { type: string } taxonomyVersion: { type: string } priority: { type: string } queueId: { type: string } escalationLevel: { type: integer } aggregateVersion: { type: integer } PageDeDemandes: type: object required: [items] properties: items: type: array items: $ref: '#/components/schemas/Demande' nextCursor: { type: string } QualificationDuDemandeur: type: object required: [identificationStatus] properties: identificationStatus: type: string enum: [DECLARE, RAPPROCHE, VERIFIE, CONTESTE] emitterActorId: { type: string } representedActorId: { type: string } beneficiaryActorId: { type: string } verificationLevel: { type: string } QualificationDeDemande: type: object required: [categoryCode, taxonomyVersion] properties: categoryCode: { type: string } taxonomyVersion: { type: string } priority: { type: string } reasonCode: { type: string } Affectation: type: object required: [queueId] properties: queueId: { type: string } assigneeContext: { type: object } reasonCode: { type: string } Transfert: type: object required: [targetQueueId, reasonCode] properties: targetQueueId: { type: string } reasonCode: { type: string } CommandeMotivee: type: object required: [reasonCode] properties: reasonCode: { type: string } effectiveAt: { type: string, format: date-time } comment: { type: string } Chronologie: type: object required: [requestId, entries] properties: requestId: { type: string } entries: type: array items: type: object required: [kind, occurredAt] properties: kind: type: string description: >- ECHANGE, TRANSITION, TRAITEMENT, REPONSE, ECHEANCE, ENGAGEMENT, RELANCE. occurredAt: { type: string, format: date-time } reference: { type: string } detail: { type: object } nextCursor: { type: string } CreationDEchange: type: object required: [direction, channel, businessAt] properties: direction: $ref: '#/components/schemas/DirectionDEchange' channel: { type: string } businessAt: { type: string, format: date-time } receivedAt: { type: string, format: date-time } transportMessageId: { type: string } contentFingerprint: { type: string } contentRef: type: string description: La référence du contenu — jamais le contenu lui-même. participants: type: array items: type: object properties: actorId: { type: string } role: { type: string } unknownAuthor: type: boolean description: Vrai si aucun participant n'est identifiable à la réception. summaryRef: { type: string } Echange: type: object required: [interactionId, direction, channel, businessAt] properties: interactionId: { type: string } direction: $ref: '#/components/schemas/DirectionDEchange' channel: { type: string } businessAt: { type: string, format: date-time } recordedAt: { type: string, format: date-time } participants: type: array items: { type: object } contentRef: { type: string } corrections: type: array items: { type: string } PageDEchanges: type: object required: [items] properties: items: type: array items: $ref: '#/components/schemas/Echange' nextCursor: { type: string } LienDObjetMetier: type: object required: [domain, objectType, objectId, purpose] properties: domain: { type: string } objectType: { type: string } objectId: { type: string } purpose: type: string enum: [CONCERNE, FONDE, RESULTAT_DE, PREUVE_DE, A_CORRIGER] MaterialisationDEcheance: type: object required: [ruleId, ruleVersion, startEvent] properties: ruleId: { type: string } ruleVersion: { type: string } startEvent: { type: string } calendarVersion: { type: string } DemandeDeTraitement: type: object required: [targetDomain, commandType, commandId] properties: targetDomain: { type: string } commandType: { type: string } commandId: type: string description: >- L'identifiant idempotent de la commande — une nouvelle tentative technique le réutilise, une nouvelle intention métier en crée un nouveau, lié. objectReferences: type: array items: type: object properties: domain: { type: string } objectType: { type: string } objectId: { type: string } purpose: { type: string } expectedResult: { type: string } ResultatDeTraitement: type: object required: [resultCode] properties: resultCode: { type: string } sourceVersion: { type: string } correctionOf: { type: string } retryable: { type: boolean } detailRef: { type: string } Traitement: type: object required: [treatmentId, requestId, targetDomain, status] properties: treatmentId: { type: string } requestId: { type: string } targetDomain: { type: string } commandType: { type: string } commandId: { type: string } status: { type: string } results: type: array items: $ref: '#/components/schemas/ResultatDeTraitement' ResultatDeCommande: type: object required: [id, aggregateVersion, status] properties: id: { type: string } aggregateVersion: { type: integer } status: { type: string }