Aller au contenu

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.

openapi: 3.1.0
info:
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 rupture
paths:
/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 }