Aller au contenu

instruction-des-dossiers

Interface synchrone (OpenAPI) — version 0.2.0. Producteur : conformite. Consommateurs déclarés : backoffice.

Le modèle est mixte — une grande part des modifications vient des utilisateurs : ouvrir un dossier, annoter le journal, qualifier une alerte, relier des dossiers, consigner une décision. Toute interface est authentifiée (401) ; le refus (403) est prononcé par le point d’application de la politique, dont le modèle peut évoluer sans toucher au contrat.

openapi: 3.1.0
info:
title: conformite — instruction des dossiers
version: 0.2.0
x-ruptures:
- version: 0.2.0
rupture: "chemins déplacés : le préfixe /tenants/{tenant} disparaît de tous les chemins"
motif: >-
Le tenant n'entre jamais dans le chemin d'une interface : il est résolu à l'assemblage —
routage par l'hôte, audience du jeton — jamais par une donnée d'appel. Le paramètre de
chemin tenant disparaît avec le préfixe.
summary: >-
Consulter et conduire l'instruction : dossiers, journal typé, alertes et leur
qualification, liaisons, décisions.
description: >-
Le modèle est mixte — une grande part des modifications vient des utilisateurs :
ouvrir un dossier, annoter le journal, qualifier une alerte, relier des dossiers,
consigner une décision. Toute interface est authentifiée (401) ; le refus (403) est
prononcé par le point d'application de la politique, dont le modèle peut évoluer
sans toucher au contrat.
x-producteurs:
- conformite
x-consommateurs:
- backoffice
paths:
/dossiers:
get:
operationId: rechercherDesDossiers
summary: Rechercher des dossiers par attributs du domaine.
security: [ { authentification: [conformite:dossiers] } ]
parameters:
- name: finalite
in: query
schema: { $ref: '#/components/schemas/Finalite' }
- name: etat
in: query
schema: { $ref: '#/components/schemas/EtatDossier' }
- name: sujet
in: query
description: Identifiant publié d'un sujet référencé par le dossier.
schema: { type: string }
- name: ouvert_depuis
in: query
schema: { type: string, format: date }
- $ref: '#/components/parameters/page'
responses:
'200':
description: La page de dossiers visibles de l'appelant (filtrage par le PEP).
content:
application/json:
schema: { $ref: '#/components/schemas/PageDeDossiers' }
'400': { $ref: '#/components/responses/Irrecevable' }
'401': { $ref: '#/components/responses/NonAuthentifie' }
'403': { $ref: '#/components/responses/NonAutorise' }
post:
operationId: ouvrirUnDossier
summary: Ouvrir un dossier — motif, finalité, périmètre par références.
description: >-
Un dossier ne change jamais de finalité : pour une finalité nouvelle sur les
mêmes faits, on ouvre un second dossier et on le relie. Idempotent par
demande_id.
security: [ { authentification: [conformite:dossiers] } ]
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/OuvertureDeDossier' }
responses:
'201':
description: Le dossier est ouvert.
content:
application/json:
schema: { $ref: '#/components/schemas/Dossier' }
'400': { $ref: '#/components/responses/Irrecevable' }
'401': { $ref: '#/components/responses/NonAuthentifie' }
'403': { $ref: '#/components/responses/NonAutorise' }
/dossiers/{dossier}:
get:
operationId: consulterUnDossier
summary: Le détail d'un dossier — identité, périmètre, compteurs, épisode courant.
description: >-
Les dossiers liés n'apparaissent que par référence et état : une liaison ne
propage aucun accès. Un dossier hors périmètre de l'appelant répond 404.
security: [ { authentification: [conformite:dossiers] } ]
parameters:
- $ref: '#/components/parameters/dossier'
responses:
'200':
description: Le dossier.
content:
application/json:
schema: { $ref: '#/components/schemas/Dossier' }
'401': { $ref: '#/components/responses/NonAuthentifie' }
'403': { $ref: '#/components/responses/NonAutorise' }
'404': { $ref: '#/components/responses/Inconnu' }
/dossiers/{dossier}/journal:
get:
operationId: consulterLeJournal
summary: Le journal d'instruction, chronologique et typé.
security: [ { authentification: [conformite:dossiers] } ]
parameters:
- $ref: '#/components/parameters/dossier'
- $ref: '#/components/parameters/page'
responses:
'200':
description: La page d'éléments, du plus récent au plus ancien.
content:
application/json:
schema: { $ref: '#/components/schemas/PageDeJournal' }
'401': { $ref: '#/components/responses/NonAuthentifie' }
'403': { $ref: '#/components/responses/NonAutorise' }
'404': { $ref: '#/components/responses/Inconnu' }
post:
operationId: ajouterUnElementAuJournal
summary: Ajouter un élément typé — jamais réécrire.
description: >-
L'élément déclare sa nature (fait source avec provenance, déclaration attribuée,
résultat de contrôle, hypothèse, conclusion) et le serveur la conserve telle
quelle. Une correction est un élément RECTIFICATIF qui pointe l'original
(rectifie) ; l'original reste lisible. Idempotent par demande_id.
security: [ { authentification: [conformite:dossiers] } ]
parameters:
- $ref: '#/components/parameters/dossier'
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/NouvelElement' }
responses:
'201':
description: L'élément est au journal.
content:
application/json:
schema: { $ref: '#/components/schemas/ElementDeJournal' }
'400': { $ref: '#/components/responses/Irrecevable' }
'401': { $ref: '#/components/responses/NonAuthentifie' }
'403': { $ref: '#/components/responses/NonAutorise' }
'404': { $ref: '#/components/responses/Inconnu' }
/dossiers/{dossier}/liaisons:
post:
operationId: relierDeuxDossiers
summary: Relier ce dossier à un autre — qualifié, daté, sans rien propager.
description: >-
La liaison porte sa nature et son motif ; elle n'ouvre pas le dossier lié, ne
propage ni mesure, ni conclusion, ni conservation. Idempotent par demande_id.
security: [ { authentification: [conformite:dossiers] } ]
parameters:
- $ref: '#/components/parameters/dossier'
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/NouvelleLiaison' }
responses:
'201':
description: La liaison est établie.
content:
application/json:
schema: { $ref: '#/components/schemas/Liaison' }
'400': { $ref: '#/components/responses/Irrecevable' }
'401': { $ref: '#/components/responses/NonAuthentifie' }
'403': { $ref: '#/components/responses/NonAutorise' }
'404': { $ref: '#/components/responses/Inconnu' }
/dossiers/{dossier}/liaisons/{liaison}/revocation:
post:
operationId: revoquerUneLiaison
summary: Révoquer une liaison par fait rectificatif — elle reste visible, inactive.
security: [ { authentification: [conformite:dossiers] } ]
parameters:
- $ref: '#/components/parameters/dossier'
- name: liaison
in: path
required: true
schema: { type: string }
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/Revocation' }
responses:
'201':
description: La liaison est révoquée ; son historique demeure.
content:
application/json:
schema: { $ref: '#/components/schemas/Liaison' }
'400': { $ref: '#/components/responses/Irrecevable' }
'401': { $ref: '#/components/responses/NonAuthentifie' }
'403': { $ref: '#/components/responses/NonAutorise' }
'404': { $ref: '#/components/responses/Inconnu' }
/dossiers/{dossier}/decisions:
post:
operationId: consignerUneDecision
summary: Consigner une décision d'instruction — datée, motivée, signée.
description: >-
Classement, réouverture (nouvel épisode, conclusion précédente intacte), examen
renforcé, demande de pièce, escalade. Selon la politique en vigueur, une
décision peut rester SUSPENDUE à une seconde validation (réponse 202) — la
politique appartient au PEP et au cœur, pas au contrat. Idempotent par
demande_id.
security: [ { authentification: [conformite:dossiers] } ]
parameters:
- $ref: '#/components/parameters/dossier'
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/NouvelleDecision' }
responses:
'201':
description: La décision est consignée.
content:
application/json:
schema: { $ref: '#/components/schemas/Decision' }
'202':
description: La décision est suspendue à une seconde validation.
content:
application/json:
schema: { $ref: '#/components/schemas/Decision' }
'400': { $ref: '#/components/responses/Irrecevable' }
'401': { $ref: '#/components/responses/NonAuthentifie' }
'403': { $ref: '#/components/responses/NonAutorise' }
'404': { $ref: '#/components/responses/Inconnu' }
/alertes:
get:
operationId: rechercherDesAlertes
summary: Les alertes — dont celles à trier (sans dossier).
security: [ { authentification: [conformite:dossiers] } ]
parameters:
- name: etat
in: query
schema: { $ref: '#/components/schemas/EtatAlerte' }
- name: dossier
in: query
description: Restreindre aux alertes d'un dossier ; absent = toutes les visibles.
schema: { type: string }
- $ref: '#/components/parameters/page'
responses:
'200':
description: La page d'alertes visibles de l'appelant.
content:
application/json:
schema: { $ref: '#/components/schemas/PageDAlertes' }
'400': { $ref: '#/components/responses/Irrecevable' }
'401': { $ref: '#/components/responses/NonAuthentifie' }
'403': { $ref: '#/components/responses/NonAutorise' }
/alertes/{alerte}/qualification:
post:
operationId: qualifierUneAlerte
summary: Qualifier une alerte — vers un dossier, classée motivée, ou annulée.
description: >-
Une alerte ne se supprime jamais. QUALIFIEE exige un dossier (existant ou ouvert
dans le même geste, dossier_a_ouvrir) ; CLASSEE exige son motif codifié ;
ANNULEE (créée par erreur) conserve le déclenchement et se compte à part des
faux positifs. Idempotent par demande_id.
security: [ { authentification: [conformite:dossiers] } ]
parameters:
- name: alerte
in: path
required: true
schema: { type: string }
requestBody:
required: true
content:
application/json:
schema: { $ref: '#/components/schemas/Qualification' }
responses:
'201':
description: La qualification est enregistrée ; l'alerte et, le cas échéant, le dossier sont rendus.
content:
application/json:
schema: { $ref: '#/components/schemas/ResultatDeQualification' }
'400': { $ref: '#/components/responses/Irrecevable' }
'401': { $ref: '#/components/responses/NonAuthentifie' }
'403': { $ref: '#/components/responses/NonAutorise' }
'404': { $ref: '#/components/responses/Inconnu' }
'409':
description: L'alerte n'est plus qualifiable (déjà classée ou annulée).
content:
application/json:
schema: { $ref: '#/components/schemas/Erreur' }
components:
parameters:
dossier:
name: dossier
in: path
required: true
description: Référence publiée du dossier.
schema: { type: string }
page:
name: page
in: query
description: Curseur de pagination opaque, rendu par la page précédente.
schema: { type: string }
responses:
NonAuthentifie:
description: L'appelant n'est pas authentifié.
content: { application/json: { schema: { $ref: '#/components/schemas/Erreur' } } }
NonAutorise:
description: Le point d'application de la politique refuse cette action sur ce périmètre.
content: { application/json: { schema: { $ref: '#/components/schemas/Erreur' } } }
Irrecevable:
description: La demande est irrecevable — le motif nomme le champ.
content: { application/json: { schema: { $ref: '#/components/schemas/Erreur' } } }
Inconnu:
description: L'objet est inconnu — ou hors du périmètre de l'appelant, sans distinction.
content: { application/json: { schema: { $ref: '#/components/schemas/Erreur' } } }
securitySchemes:
authentification:
type: openIdConnect
openIdConnectUrl: https://exemple.invalid/.well-known/openid-configuration
description: Exigence déclarée ici ; mécanisme décliné à l'assemblage.
schemas:
Finalite:
type: string
enum: [LCBFT, FRAUDE, SANCTIONS_GEL, REQUISITION, ECHANGE_REGLEMENTAIRE, CONTROLE]
EtatDossier:
type: string
enum: [OUVERT, EN_INSTRUCTION, DECLARE, CLOTURE]
EtatAlerte:
type: string
enum: [OUVERTE, A_AFFECTER, EN_ANALYSE, EN_ATTENTE_INFORMATION, QUALIFIEE, CLASSEE, ANNULEE]
ReferenceVersionnee:
type: object
required: [domaine, type, identifiant, version]
properties:
domaine: { type: string }
type: { type: string }
identifiant: { type: string, description: "Identifiant publié — jamais une valeur (ni nom, ni IBAN)." }
version: { type: integer, minimum: 1 }
OuvertureDeDossier:
type: object
required: [demande_id, finalite, motif, sujets]
properties:
demande_id: { type: string, description: Clé d'idempotence du client. }
finalite: { $ref: '#/components/schemas/Finalite' }
motif: { type: string }
sujets:
type: array
minItems: 1
items: { $ref: '#/components/schemas/ReferenceVersionnee' }
echeance: { type: string, format: date }
Dossier:
type: object
required: [reference, finalite, etat, motif, ouvert_le, sujets, episode]
properties:
reference: { type: string }
finalite: { $ref: '#/components/schemas/Finalite' }
etat: { $ref: '#/components/schemas/EtatDossier' }
motif: { type: string }
ouvert_le: { type: string, format: date-time }
echeance: { type: string, format: date }
sujets:
type: array
items: { $ref: '#/components/schemas/ReferenceVersionnee' }
episode:
type: integer
minimum: 1
description: Une réouverture ouvre un nouvel épisode ; la conclusion précédente reste.
liaisons:
type: array
description: Les dossiers liés, par référence et état seulement — rien ne se propage.
items: { $ref: '#/components/schemas/Liaison' }
compteurs:
type: object
properties:
alertes: { type: integer }
elements_journal: { type: integer }
mesures: { type: integer }
NouvelElement:
type: object
required: [demande_id, nature, texte]
properties:
demande_id: { type: string }
nature:
type: string
enum: [FAIT_SOURCE, DECLARATION, RESULTAT_CONTROLE, HYPOTHESE, CONCLUSION]
description: >-
Le typage est la garde : une déclaration est attribuée et non tenue pour
vérifiée, une hypothèse est à vérifier, une conclusion est validée selon la
délégation. Un FAIT_SOURCE porte sa provenance.
texte: { type: string }
provenance:
type: string
description: Obligatoire pour un FAIT_SOURCE — le domaine ou la source qui atteste.
references:
type: array
items: { $ref: '#/components/schemas/ReferenceVersionnee' }
pieces:
type: array
description: Références de pièces à l'archive probatoire — jamais leur contenu.
items: { type: string }
rectifie:
type: string
description: Identifiant de l'élément corrigé, le cas échéant — l'original reste lisible.
ElementDeJournal:
allOf:
- $ref: '#/components/schemas/NouvelElement'
- type: object
required: [element_id, auteur, consigne_le]
properties:
element_id: { type: string }
auteur: { type: string, description: L'utilisateur ou l'agent nommé — jamais un compte partagé. }
consigne_le: { type: string, format: date-time }
NouvelleLiaison:
type: object
required: [demande_id, dossier_lie, nature, motif]
properties:
demande_id: { type: string }
dossier_lie: { type: string }
nature:
type: string
description: Nature codifiée (sujet commun, corrélation bancaire, tiers, mode opératoire, temporalité…).
motif: { type: string }
Liaison:
allOf:
- $ref: '#/components/schemas/NouvelleLiaison'
- type: object
required: [liaison_id, etablie_le, par, etat]
properties:
liaison_id: { type: string }
etablie_le: { type: string, format: date-time }
par: { type: string }
etat: { type: string, enum: [ACTIVE, REVOQUEE] }
etat_dossier_lie: { $ref: '#/components/schemas/EtatDossier' }
Revocation:
type: object
required: [demande_id, motif]
properties:
demande_id: { type: string }
motif: { type: string }
NouvelleDecision:
type: object
required: [demande_id, type, motif]
properties:
demande_id: { type: string }
type:
type: string
enum: [CLASSEMENT, REOUVERTURE, EXAMEN_RENFORCE, DEMANDE_PIECE, ESCALADE]
description: >-
Les décisions qui engagent l'extérieur ont leurs contrats propres : les
mesures (administration des mesures), la déclaration (déclaratif, à
naître).
motif: { type: string }
Decision:
allOf:
- $ref: '#/components/schemas/NouvelleDecision'
- type: object
required: [decision_id, etat, prise_le, decideur]
properties:
decision_id: { type: string }
etat:
type: string
enum: [CONSIGNEE, SUSPENDUE_A_VALIDATION]
prise_le: { type: string, format: date-time }
decideur: { type: string }
Alerte:
type: object
required: [reference, scenario, explication, sujet, survenue_le, etat, priorite_reglementaire]
properties:
reference: { type: string }
scenario:
type: object
required: [identifiant, version]
properties:
identifiant: { type: string }
version: { type: string }
explication:
type: string
description: L'explication déterministe, autoportée — jamais nulle.
sujet: { $ref: '#/components/schemas/ReferenceVersionnee' }
survenue_le: { type: string, format: date-time }
etat: { $ref: '#/components/schemas/EtatAlerte' }
priorite_reglementaire: { type: integer }
priorite_assistee:
type: integer
description: >-
Absente quand l'apprentissage est débranché — champ séparé de la priorité
réglementaire, jamais fusionné.
echeance: { type: string, format: date-time }
dossier: { type: string, description: "Référence du dossier de rattachement, le cas échéant." }
Qualification:
type: object
required: [demande_id, decision]
properties:
demande_id: { type: string }
decision:
type: string
enum: [QUALIFIEE, CLASSEE, ANNULEE]
dossier:
type: string
description: Pour QUALIFIEE — le dossier de rattachement existant.
dossier_a_ouvrir:
$ref: '#/components/schemas/OuvertureDeDossier'
description: Pour QUALIFIEE — ouvrir le dossier dans le même geste.
motif:
type: string
description: Obligatoire pour CLASSEE (motif codifié) et ANNULEE.
ResultatDeQualification:
type: object
required: [alerte]
properties:
alerte: { $ref: '#/components/schemas/Alerte' }
dossier: { $ref: '#/components/schemas/Dossier' }
PageDeDossiers:
type: object
required: [elements, servi_le]
properties:
elements:
type: array
items: { $ref: '#/components/schemas/Dossier' }
page_suivante: { type: string }
servi_le: { type: string, format: date-time }
PageDAlertes:
type: object
required: [elements, servi_le]
properties:
elements:
type: array
items: { $ref: '#/components/schemas/Alerte' }
page_suivante: { type: string }
servi_le: { type: string, format: date-time }
PageDeJournal:
type: object
required: [elements, servi_le]
properties:
elements:
type: array
items: { $ref: '#/components/schemas/ElementDeJournal' }
page_suivante: { type: string }
servi_le: { type: string, format: date-time }
Erreur:
type: object
required: [code, message]
properties:
code: { type: string }
message:
type: string
description: >-
Nomme le champ ou la condition en cause. Ne révèle ni un critère de
détection, ni l'existence d'un objet hors du périmètre de l'appelant.