consultation-des-entites
Interface synchrone (OpenAPI) — version 0.6.0. Producteur : tenue-de-compte. Consommateurs déclarés : operations, backoffice.
La consultation des entités que la tenue de compte détient : la recherche des comptes (par épargnant, par couple épargnant × entreprise, par dispositif porté), la liste et la fiche des CRE, la fiche d’un compte (type, sous-type, cadre légal, rattachement, politique temporelle, positions courantes), les écritures d’un compte (le journal filtré, paginé, marques de contrepassation comprises) et l’historique d’un compte (la chronologie de ses états). Lecture sans effet de bord. Le tenant n’est pas dans le chemin : il est résolu à l’assemblage — la muraille de Chine tient au routage, une ressource d’un autre tenant est un 404.
La spécification
Section intitulée « La spécification »openapi: 3.1.0info: title: tenue-de-compte — consultation des entités version: 0.6.0 summary: La lecture des entités principales du domaine — CRE, compte, écritures, historique — et la recherche des comptes. x-ruptures: >- 0.6.0 (2026-08-07) — RUPTURE DÉCLARÉE en 0.x : la propriété et le filtre `etat` du compte deviennent `statut` (valeurs inchangées : en-preparation, ouvert, suspendu, en-cloture, clos, abandonne) ; le jalon du cycle de vie sert `statut` au lieu d'`etat`. 0.5.0 (2026-08-07) — RUPTURE DÉCLARÉE en 0.x : le compte servi reflète le plan de comptes remanié. La propriété et le filtre « type de compte » deviennent `type` et changent de valeurs (parts-epargnant, especes, titres, mixte, droits-contractuels — les suffixes « -technique » disparaissent) ; le SOUS-TYPE s'ajoute (propriété et filtre `sous_type` : epargnant, entreprise, fonds, societe-de-gestion, banque, organisme, erreurs) ; la propriété « portée » (avoirs/passage) DISPARAÎT ; `cadre_legal` reste servi mais devient une lecture dérivée du compte général, absente pour un compte hors cadre. Le rattachement se sert en couples génériques clé / référence — `rattachement_cle`/`rattachement_ref` et `origine_cle`/`origine_ref` remplacent les propriétés « épargnant » et « entreprise d'origine » ; à la recherche, les filtres du même nom sont remplacés par `rattachement_cle`, `rattachement_ref` et `origine_ref`. 0.4.0 (2026-08-07) — RUPTURE DÉCLARÉE en 0.x : le vocabulaire du compte est renommé en langage comptable — la propriété et le filtre `categorie` deviennent « type de compte », `enveloppe` devient `cadre_legal` (valeurs inchangées) ; le rattachement remplace la borne dans la sémantique servie. Ajouts compatibles : le LIBELLÉ et le COMPTE GÉNÉRAL du plan sur la fiche et les lignes de compte. 0.3.0 (2026-08-07) — RUPTURE DÉCLARÉE en 0.x. Le préfixe `/tenants/{tenant}` DISPARAÎT de tous les chemins : le tenant est résolu à l'assemblage ; la propriété `tenant` quitte la fiche de compte. Ajouts compatibles : la RECHERCHE des comptes (`GET /comptes` — entrée épargnant, entrée salarié par le couple épargnant × entreprise, filtre par dispositif au travers des lots vivants) et le CADRE LÉGAL à la fiche et aux lignes de compte (épargne salariale ou plan d'épargne retraite — l'unicité du compte s'apprécie par couple, type et cadre). 0.2.0 — RUPTURE DÉCLARÉE en 0.x. Sur la fiche de compte : `categorie` (avoirs/passage) est RENOMMÉE « portée » — « catégorie » désigne désormais la qualification structurelle du compte (compte-titres d'épargnant, espèces, technique…), qui détermine la POLITIQUE TEMPORELLE remplaçant le booléen `historise` (une politique se déduit de ce que le compte est, elle ne se choisit pas) ; la fiche gagne la BORNE (épargnant, entreprise d'origine, justification de séparation) et l'état du cycle à six valeurs. Sur la fiche de CRE : le verdict connaît les états `recu`, `valide` et `interprete`, la cause d'un blocage ou d'un rejet est servie, et le décompte des effets couvre les quatre familles. Deux lectures s'ajoutent (compatibles) : la LISTE des CRE, filtrée et paginée, et l'HISTORIQUE d'un compte. description: >- La consultation des entités que la tenue de compte détient : la recherche des comptes (par épargnant, par couple épargnant × entreprise, par dispositif porté), la liste et la fiche des CRE, la fiche d'un compte (type, sous-type, cadre légal, rattachement, politique temporelle, positions courantes), les écritures d'un compte (le journal filtré, paginé, marques de contrepassation comprises) et l'historique d'un compte (la chronologie de ses états). Lecture sans effet de bord. Le tenant n'est pas dans le chemin : il est résolu à l'assemblage — la muraille de Chine tient au routage, une ressource d'un autre tenant est un 404. x-producteurs: - tenue-de-compte x-consommateurs: - composant: operations - composant: backoffice statut: réel — module Tenue de compte (surveillance des CRE, fiche CRE, comptes, fiche compte)paths: /comptes: get: operationId: rechercherLesComptes summary: La recherche des comptes — entrée épargnant, entrée salarié, filtre par dispositif. description: >- Le rattachement se cherche en couples clé / référence. L'entrée « épargnant » : `rattachement_cle=EPG` et `rattachement_ref` (l'identifiant publié de l'épargnant) servent TOUS les comptes du porteur chez ce tenant, toutes entreprises confondues. L'entrée « salarié » : le même rattachement, plus `origine_ref` (l'entreprise d'origine), sert le ou les comptes du couple — le couple étant la projection durable de cette qualité (un identifiant de lien d'emploi se résout chez le domaine Entreprise avant d'interroger ici). Le filtre `dispositif` sélectionne les comptes dont des LOTS VIVANTS portent ce dispositif — un compte n'est jamais rattaché à un dispositif : « le compte titres du PEE de ce salarié » est le compte du couple portant des droits vivants du PEE. Nuance qui compte : « le compte où un versement de ce dispositif S'INSCRIRAIT » est le compte du couple dans le cadre légal adéquat, SANS le filtre — un compte jamais alimenté par le dispositif n'est pas servi par le filtre. Au moins l'un de `rattachement_ref` ou `origine_ref` est requis — la recherche sans entrée discriminante est refusée. security: - authentification: [tenue-de-compte:consultation] parameters: - name: rattachement_cle in: query required: false description: >- La clé du rattachement cherché — EPG pour les comptes d'un épargnant, ENT pour ceux rattachés à une entreprise, et ainsi de suite. schema: type: string enum: [EPG, ENT, FDS, SGP, BNK, ORG] - name: rattachement_ref in: query required: false description: >- La référence du rattachement — un identifiant publié. Avec la clé EPG, l'entrée « épargnant » : tous les comptes du porteur. schema: { type: string, minLength: 1 } - name: origine_ref in: query required: false description: >- L'identifiant publié de l'entreprise d'origine des avoirs (comptes de parts d'épargnant) — avec le rattachement d'un épargnant, l'entrée « salarié » (le couple). schema: { type: string, minLength: 1 } - name: dispositif in: query required: false description: >- L'identifiant publié d'un dispositif : seuls les comptes portant des lots vivants de ce dispositif sont servis. schema: { type: string, minLength: 1 } - name: cadre_legal in: query required: false schema: type: string enum: [epargne-salariale, plan-epargne-retraite] - name: type in: query required: false schema: type: string enum: [parts-epargnant, especes, titres, mixte, droits-contractuels] - name: sous_type in: query required: false schema: type: string enum: [epargnant, entreprise, fonds, societe-de-gestion, banque, organisme, erreurs] - name: statut in: query required: false schema: type: string enum: [en-preparation, ouvert, suspendu, en-cloture, clos, abandonne] - $ref: '#/components/parameters/page' - $ref: '#/components/parameters/taille' responses: '200': description: La page demandée — vide si aucun compte ne répond (une recherche vide n'est pas une erreur). content: application/json: schema: type: object required: [lignes, total] properties: lignes: type: array items: { $ref: '#/components/schemas/LigneDeCompte' } total: type: [integer, 'null'] description: Le nombre total de comptes du filtre — null quand on ne sait pas compter à coût raisonnable. '400': { description: "Aucune entrée discriminante — ni référence de rattachement, ni entreprise d'origine." } '401': { description: Aucune identité présentée. } '403': { description: L'identité présentée n'a pas la famille tenue-de-compte:consultation. } /cre: get: operationId: rechercherLesCre summary: La liste des CRE, filtrée et paginée — la file de surveillance. security: - authentification: [tenue-de-compte:consultation] parameters: - name: type in: query required: false description: Le code du type de CRE (catalogue des types). schema: { type: string } - name: verdict in: query required: false schema: type: string enum: [recu, valide, interprete, comptabilise, bloque, rejete, extourne] - name: periode in: query required: false description: La période comptable de comptabilisation (identifiant de la période). schema: { type: string } - name: cree_depuis in: query required: false schema: { type: string, format: date } - $ref: '#/components/parameters/page' - $ref: '#/components/parameters/taille' responses: '200': description: La page demandée. content: application/json: schema: type: object required: [lignes, total] properties: lignes: type: array items: { $ref: '#/components/schemas/LigneDeCre' } total: type: [integer, 'null'] description: Le nombre total de CRE du filtre — null quand on ne sait pas compter à coût raisonnable. '401': { description: Aucune identité présentée. } '403': { description: L'identité présentée n'a pas la famille tenue-de-compte:consultation. } /cre/{identifiant}: get: operationId: consulterUnCre summary: La fiche d'un CRE — son verdict, son enveloppe, les effets qu'il a produits. description: >- Le minimum dû au producteur d'un CRE : savoir ce qu'il est devenu. Les effets ne sont présents que pour une comptabilisation ; la cause n'est servie que pour un blocage ou un rejet. security: - authentification: [tenue-de-compte:consultation] parameters: - name: identifiant in: path required: true description: L'identifiant du CRE (celui du producteur amont). schema: { type: string, minLength: 1 } responses: '200': description: La fiche du CRE. content: application/json: schema: { $ref: '#/components/schemas/FicheDeCre' } '401': { description: Aucune identité présentée. } '403': { description: L'identité présentée n'a pas la famille tenue-de-compte:consultation. } '404': { description: Le CRE est inconnu du livre de ce tenant. } /comptes/{compte}: get: operationId: consulterUnCompte summary: La fiche d'un compte — type, sous-type, cadre légal, rattachement, politique temporelle, positions courantes. description: >- Le type, le sous-type et le cadre légal viennent du compte général du plan ; le rattachement vient de l'ouverture ; les positions courantes viennent du livre. Un compte au plan sans mouvement a une fiche aux positions vides. « Gelé » n'est pas un état : les restrictions en vigueur se lisent à la consultation des positions. security: - authentification: [tenue-de-compte:consultation] parameters: - $ref: '#/components/parameters/compte' responses: '200': description: La fiche du compte. content: application/json: schema: { $ref: '#/components/schemas/FicheDeCompte' } '401': { description: Aucune identité présentée. } '403': { description: L'identité présentée n'a pas la famille tenue-de-compte:consultation. } '404': { description: Le compte est inconnu de ce tenant. } /comptes/{compte}/ecritures: get: operationId: consulterLesEcritures summary: Les écritures d'un compte, dans l'ordre du journal, paginées. description: >- Le journal filtré sur le compte : chaque écriture identifiée (le CRE qui l'a produite et son rang), avec sa marque de contrepassation si elle a été corrigée. Une liste vide pour un compte au plan sans mouvement. security: - authentification: [tenue-de-compte:consultation] parameters: - $ref: '#/components/parameters/compte' - $ref: '#/components/parameters/page' - $ref: '#/components/parameters/taille' responses: '200': description: La page demandée du journal du compte. content: application/json: schema: type: object required: [lignes, total] properties: lignes: type: array items: { $ref: '#/components/schemas/Ecriture' } total: type: [integer, 'null'] '401': { description: Aucune identité présentée. } '403': { description: L'identité présentée n'a pas la famille tenue-de-compte:consultation. } '404': { description: Le compte est inconnu de ce tenant. } /comptes/{compte}/historique: get: operationId: consulterLHistoriqueDuCompte summary: La chronologie des états d'un compte — ouverture, suspensions, clôture. description: >- La suite datée et attribuée des changements d'état du compte, en append-only — le compte ne se supprime jamais. Les mouvements se lisent au journal, pas ici. security: - authentification: [tenue-de-compte:consultation] parameters: - $ref: '#/components/parameters/compte' responses: '200': description: La chronologie du compte. content: application/json: schema: type: array items: { $ref: '#/components/schemas/JalonDeCompte' } '401': { description: Aucune identité présentée. } '403': { description: L'identité présentée n'a pas la famille tenue-de-compte:consultation. } '404': { description: Le compte est inconnu de ce tenant. }components: securitySchemes: authentification: type: http scheme: bearer description: >- L'exigence : tout appel est authentifié. Le mécanisme cible est OIDC ; sa déclinaison relève de l'assemblage. Le tenant est porté par l'assemblage, jamais par le chemin. parameters: compte: name: compte in: path required: true description: L'identifiant public du compte chez ce tenant. schema: { type: string, minLength: 1 } page: name: page in: query required: false schema: { type: integer, minimum: 1, default: 1 } taille: name: taille in: query required: false schema: { type: integer, minimum: 1, maximum: 200, default: 50 } schemas: LigneDeCompte: type: object required: [compte, libelle, type, sous_type, statut] properties: compte: { type: string, description: L'identifiant public du compte. } libelle: { type: string } compte_general: { type: string, description: Le numéro du compte général du plan. } type: type: string enum: [parts-epargnant, especes, titres, mixte, droits-contractuels] description: Le type, tenu du compte général — ce que le compte enregistre. sous_type: type: string enum: [epargnant, entreprise, fonds, societe-de-gestion, banque, organisme, erreurs] description: Le sous-type, tenu du compte général — l'entité que le compte reflète. cadre_legal: type: string enum: [epargne-salariale, plan-epargne-retraite] description: >- Le cadre légal, dérivé du compte général — absent pour un compte hors cadre (banque, organisme, erreurs). statut: type: string enum: [en-preparation, ouvert, suspendu, en-cloture, clos, abandonne] rattachement_cle: type: string enum: [EPG, ENT, FDS, SGP, BNK, ORG] description: >- La clé du rattachement — l'entité dont le compte porte les avoirs ou qu'il reflète ; absente pour un poste sans entité propre (suspens, collectif). rattachement_ref: type: string description: La référence du rattachement — un identifiant publié, immuable. origine_cle: type: string enum: [ENT] description: La clé du second couple — comptes de parts d'épargnant seulement. origine_ref: type: string description: L'entreprise d'origine des avoirs, immuable. justification_separation: type: string description: Le motif documenté d'un compte supplémentaire dans le même cadre légal ; absent pour un compte unique. dispositifs_presents: type: array description: >- Les identifiants publiés des dispositifs portés par des lots vivants du compte — ce qui explique pourquoi le compte répond à un filtre `dispositif`. Vide pour un compte jamais alimenté. items: { type: string } LigneDeCre: type: object required: [identifiant, type, statut, date_valeur] properties: identifiant: { type: string } type: { type: string, description: Le code du type (catalogue des types de CRE). } statut: type: string enum: [recu, valide, interprete, comptabilise, bloque, rejete, extourne] date_valeur: { type: string, format: date } nombre_ecritures: { type: integer, description: Présent après comptabilisation. } cause: { type: string, description: Présente pour un blocage ou un rejet — le motif précis conservé. } FicheDeCre: type: object required: [identifiant, type, version_type, statut, cle_idempotence, date_fait_generateur, date_valeur, effets] properties: identifiant: { type: string } type: { type: string, description: Le code du type (catalogue des types de CRE). } version_type: { type: string, description: La version du schéma de charge utile. } producteur: type: string description: >- Le domaine autorité du fait (operations, carnet-ordres, banque-flux-financiers…). Facultatif : le nom du producteur se déclare type par type au catalogue des types de CRE, que la tenue de compte ne détient pas — l'enveloppe reçue ne le porte pas. statut: type: string enum: [recu, valide, interprete, comptabilise, bloque, rejete, extourne] description: >- L'état du cycle de vie, tel que le livre le prononce. « Rejeté » est un terminus ; « bloqué » se reprend. Les états intermédiaires (reçu, validé, interprété) se consultent ici ; ils ne se publient pas sur le bus. cle_idempotence: { type: string } date_fait_generateur: { type: string, format: date } date_valeur: { type: string, format: date } comptabilise_le: { type: string, format: date-time, description: Présent après comptabilisation. } periode: { type: string, description: "La période comptable d'inscription, présente après comptabilisation." } schema_applique: { type: string, description: "La version du schéma comptable appliquée (piste d'audit), présente après interprétation." } cause: type: string description: >- Pour un blocage ou un rejet : le motif précis conservé — période close, entreprise incompatible avec le rattachement, lot insuffisant, réservation expirée, conflit de version d'un état lu en amont… reference_extourne: { type: string, description: "Le CRE extourné, sur un CRE compensateur." } effets: type: object required: [ecritures] description: Le décompte des effets inscrits, par famille. properties: ecritures: type: array items: { $ref: '#/components/schemas/Ecriture' } nombre_mouvements_lots: { type: integer } nombre_ajustements_fiscaux: { type: integer } nombre_affectations: { type: integer } FicheDeCompte: type: object required: [compte, libelle, type, sous_type, politique_temporelle, statut, positions] properties: compte: { type: string } libelle: { type: string } compte_general: { type: string, description: Le numéro du compte général du plan. } type: type: string enum: [parts-epargnant, especes, titres, mixte, droits-contractuels] description: >- Le type, tenu du compte général du plan : ce que le compte enregistre. Il détermine les instruments admis, le rattachement exigé et la politique temporelle. sous_type: type: string enum: [epargnant, entreprise, fonds, societe-de-gestion, banque, organisme, erreurs] description: >- Le sous-type, tenu du compte général : l'entité que le compte reflète. cadre_legal: type: string enum: [epargne-salariale, plan-epargne-retraite] description: >- Le cadre légal, dérivé du compte général — il se décide au plan, jamais au compte ; absent pour un compte hors cadre (banque, organisme, erreurs). Le compte-titres d'un plan d'épargne retraite relève d'un compte général propre par la loi (L. 224-1) — jamais une dérogation ; un compte de droits contractuels est toujours en cadre plan-epargne-retraite. politique_temporelle: type: string enum: [bitemporelle, double-axe-de-solde, position-courante, observations-attestees] description: >- La politique DÉCOULE du type, un paramétrage ne la choisit pas. statut: type: string enum: [en-preparation, ouvert, suspendu, en-cloture, clos, abandonne] rattachement_cle: type: string enum: [EPG, ENT, FDS, SGP, BNK, ORG] description: >- La clé du rattachement — l'entité dont le compte porte les avoirs ou qu'il reflète (EPG épargnant, ENT entreprise, FDS fonds, SGP société de gestion, BNK compte bancaire reflété, ORG organisme) ; absente pour un poste sans entité propre (suspens, collectif). rattachement_ref: type: string description: La référence du rattachement — un identifiant publié, immuable. origine_cle: type: string enum: [ENT] description: La clé du second couple — comptes de parts d'épargnant seulement. origine_ref: type: string description: >- L'entreprise d'origine des avoirs, immuable : les avoirs de deux entreprises ne coexistent dans aucun compte. justification_separation: type: string description: Le motif documenté d'un compte de parts supplémentaire pour le même couple dans le même cadre légal ; absent pour un compte unique. dispositifs_presents: type: array description: >- Les identifiants publiés des dispositifs portés par des lots vivants du compte. Vide pour un compte jamais alimenté. items: { type: string } positions: type: array description: Les positions courantes, par instrument (les positions nulles ne sont pas servies). items: type: object required: [instrument, quantite] properties: instrument: { type: string } quantite: type: integer description: Un entier, l'unité est celle de l'instrument — jamais de flottant. JalonDeCompte: type: object required: [survenu_le, statut] properties: survenu_le: { type: string, format: date-time } statut: type: string enum: [en-preparation, ouvert, suspendu, en-cloture, clos, abandonne] description: Le statut atteint à cet instant. acteur: { type: string, description: Qui a produit le changement (piste d'audit). } commentaire: { type: string } Ecriture: type: object required: [identifiant, compte, sens, quantite, instrument, date_comptable] properties: identifiant: type: string description: L'identifiant déterministe — le CRE qui l'a produite et son rang (« cre/rang »). compte: { type: string } sens: { type: string, enum: [debit, credit] } quantite: type: integer description: La quantité mue — un entier, l'unité est celle de l'instrument. instrument: { type: string } date_comptable: type: string format: date description: La date comptable de l'écriture (verrou de période). date_valeur: { type: string, format: date, description: Présente quand elle diffère (comptes espèces). } contrepassee_par: type: string description: >- La marque de correction : l'identifiant du miroir qui a contrepassé cette écriture — absente si l'écriture n'a pas été corrigée.