Modèle de données
Le tronc commun harmonisé
Section intitulée « Le tronc commun harmonisé »Les six typologies décrivent toutes une identité patient et la même réalité administrative (qui l’a soigné, où, quand). Deux mécanismes mutualisent ces champs. Les traits identifiants du patient (identité, adresse) vivent dans des tables dédiées partagées par toutes les typologies ; les autres champs transverses (source, prescripteur) restent des blocs de colonnes communs réutilisés à l’identique sur chaque table enfant. Dans les deux cas, un data manager réutilise le même mapping quelle que soit la source.
Identité et adresse : tables dédiées
Section intitulée « Identité et adresse : tables dédiées »L’identité et l’adresse du patient vivent dans des tables dédiées (identities,
addresses), partagées par toutes les typologies. À l’import, le pipeline crée (ou retrouve
à l’identique) l’identité et l’adresse du signalement, puis les relie au signalement via
reports.identity_id et reports.address_id. Le détail du cycle est décrit dans
Cycle de vie d’un signalement.
Une adresse transmise plusieurs fois pour la même identité (à la casse et aux accents près)
n’est stockée qu’une fois, mais chaque signalement garde le lien vers l’adresse qu’il a
lui-même transmise : on retrouve donc, pour un signalement, l’adresse de la source, et pour
une adresse, tous les signalements qui l’attestent. L’adresse retient aussi le signalement qui
l’a créée (source_report_id), comme l’identité.
| Table | Champs |
|---|---|
identities | last_name, first_name, birth_name, birth_date, sex, nir_partial, + lieu de naissance (birth_commune, birth_postal_code, birth_insee_code) |
addresses | address, postal_code, city (+ ban_id, réservé à une vérification BAN ultérieure) |
À savoir - le NIR complet n’est jamais stocké : seuls les 10 premiers chiffres
(nir_partial) sont conservés. La troncature est faite par le SI Registres à l’import ; le
data manager peut, par prudence, ne transmettre que ces 10 chiffres.
Blocs partagés (portés par la table enfant)
Section intitulée « Blocs partagés (portés par la table enfant) »| Bloc | Champs |
|---|---|
| Source & structure | source_structure_id, source_structure_label (+ finess pour traçabilité) |
| Prescripteur / médecin | prescriber_name, prescriber_address, prescriber_postal_code, prescriber_city, prescriber_rpps |
patient_ipp (identifiant patient interne à la structure source) est porté par la table
enfant, pas par l’identité : ce n’est pas un trait d’identité partagé - deux structures
peuvent réutiliser les mêmes numéros d’IPP.
Attributs portés par le parent reports
Section intitulée « Attributs portés par le parent reports »Ces familles d’attributs sont les mêmes pour toutes les typologies et vivent donc sur la table parente, jamais dupliquées sur les enfants :
- Lien identité / adresse -
identity_id(→identities, toujours renseigné à l’import) etaddress_id(→addresses, l’adresse portée par la ligne,nullsi elle n’en porte pas). Le patient se lit sur l’identité (identities.patient_id), rempli en aval par l’identito-vigilance,nulltant que le rapprochement n’a pas eu lieu. - Report controls - les décisions d’import par ligne (
can_create_patient,can_create_tumor) - voir Report controls plus bas. - Exclusion -
excluded,exclusion_origin,exclusion_reason_id, etc. - voir Exclusion plus bas. - Date de signalement (
notification_date) - la date pivot du signalement : chaque pipeline la remplit avec la date clinique la plus pertinente de sa source, ce qui donne à toutes les typologies une seule colonne pour trier et paginer, indépendamment de la source.- ACP : prélèvement → enregistrement → validation (1ʳᵉ non nulle)
- PMSI : entrée en hospitalisation
- ALD : date d’ouverture
- RCP : date de la RCP
- Dépistage : date du test
- Générique : la date saisie dans la colonne
report_dateà l’import
Codage cancer
Section intitulée « Codage cancer »Le registre vise un codage CIM-O-3 (oncologie), composé d’une topographie (le site,
Cxx.x) et d’une morphologie (l’histologie + le comportement, ex. 8140/3). Les
sources, elles, arrivent dans des codages différents - d’où des transcodages distincts
par typologie.
| Typologie | Codage source | Transcodage vers CIM-O-3 |
|---|---|---|
| ACP | ADICAP, SNOMED, ou texte libre | Éclatement du code (organe → topo, lésion → morpho) via tables de référence ; fallback code générique C80.9 / 8000/3 |
| PMSI, ALD | CIM-10 (administratif) | Topo = recopie du CIM-10 ; morpho dérivée par règle de préfixe (voir ci-dessous) |
| RCP | CIM-O-3 natif (topo issue du CIM-10, morpho déjà en CIM-O) | Aucun - codes conservés tels quels (warning si inconnu, jamais de rejet) |
| Dépistage | aucun | Topo grossière dérivée du programme (breast→C50, colorectal→C18, cervix→C53) ; pas de morphologie |
| Générique | CIM-O-3 saisi | Aucun - stocké tel quel ; un code absent du référentiel CIM-O-3 (coquille, code inconnu) n’est pas rejeté à l’import, mais ne produira pas de tumeur |
Règle de préfixe CIM-10 → comportement morphologique (PMSI, ALD) : C* → /3 (malin),
D00–D09 → /2 (in situ), D10–D36 → /0 (bénin), D37–D48 → /1 (incertain).
Code caractérisant (PMSI, ALD) - sur une source transcodée, le code CIM-10 retenu comme code cancer du signalement une fois passé le test « code cancer valide ». Quand le code n’est pas un cancer, le code caractérisant est NULL : le signalement est conservé (audit) mais ne produit pas de tumeur candidate. Pour le PMSI, qui porte plusieurs diagnostics par séjour, le code caractérisant est choisi par priorité DP → DR → DAS.
⚠️ Le périmètre précis des codes cancer valides se consolide encore et peut évoluer.
Groupes IARC
Section intitulée « Groupes IARC »À partir du code CIM-O-3, chaque signalement reçoit deux groupes IARC, qui disent si deux codes désignent le même cancer malgré une variation de codage :
topo_iarc- l’organe (52 groupes : 10 colon, 11 rectum, 30 sein…), fixé par les 3 premiers caractères de la topographie ;morpho_iarc- le type histologique (17 groupes : 3 adénocarcinomes, 17 non précisé…), fixé par les 4 chiffres de l’histologie, quel que soit le comportement.
Un groupe reste vide quand le code manque ou n’appartient pas au référentiel. Le PMSI et l’ALD,
dont la morphologie est déduite du CIM-10, tombent dans le groupe 17 (non précisé) ; le dépistage
n’a qu’un groupe topographique. La localisation FRANCIM (ref_cancer_sites) qui sert aux files
de travail est une autre classification.
Cycle de vie d’un signalement
Section intitulée « Cycle de vie d’un signalement »De l’import à la tumeur
Section intitulée « De l’import à la tumeur »L’import et le rapprochement de l’identité à un patient sont deux étapes distinctes. Le pipeline d’import valide, transcode, met en qualité, puis injecte le signalement en créant (ou retrouvant à l’identique) son identité et son adresse. Un worker d’identito-vigilance distinct, en aval, tente ensuite de rattacher cette identité à un patient et décide de la suite.
flowchart TD
F["Fichier source (CSV/Excel)<br/>au format canonique"] --> V{"Validation<br/>champs requis · formats · identité présente"}
V -->|ligne invalide<br/>ou sans identité| REJ["Ligne rejetée<br/>(anomalies visibles à la pré-validation)"]
V -->|ligne valide| T["Transcodage + mise en qualité<br/>(CIM-O-3, code caractérisant, groupes IARC)"]
T --> INJ["Injection : identité + adresse (dédupliquées)<br/>+ reports (identity_id, address_id) + table enfant"]
INJ --> IV{"Identito-vigilance<br/>(en aval)"}
IV -->|patient rapproché| ATT["Identité rattachée au patient"]
IV -->|aucun patient<br/>+ création autorisée| NEWP["Patient créé"]
IV -->|aucun patient<br/>+ création interdite| ORP["Identité en attente"]
ATT --> TUM{"Rattachement<br/>des tumeurs"}
NEWP --> TUM
TUM -->|création| NEWT["Tumeur créée,<br/>signalement rattaché"]
TUM -->|proposition| PRO["Signalement pré-rattaché<br/>à une tumeur existante"]
TUM -->|sinon| FLO["Signalement à rattacher<br/>(porté par le patient, pas par une tumeur)"]
INJ -. "si excluded renseigné" .-> EXC["Marqué exclu : jamais de tumeur"]
⚠️ Le worker d’identito-vigilance (rattachement de l’identité à un patient, gestion des signalements en attente) est en cours d’implémentation ; cette partie aval peut encore évoluer. Le rattachement des signalements aux tumeurs est décrit dans la page Rattachement des tumeurs.
Report controls : can_create_patient / can_create_tumor
Section intitulée « Report controls : can_create_patient / can_create_tumor »Deux booléens par ligne, fournis par le data manager dans le CSV, pilotent ce que l’identito-vigilance (pour le patient) et le rattachement des tumeurs (pour la tumeur) ont le droit de faire en aval : créer un nouveau patient / lever une nouvelle tumeur, ou seulement rattacher à ce qui existe déjà (sinon l’identité reste en attente). Le rattachement à un patient connu a toujours lieu ; seules les créations sont contrôlées.
Le défaut dépend de la typologie :
| Typologie | can_create_patient | can_create_tumor |
|---|---|---|
| ACP, PMSI, Générique | true | true |
| ALD, Dépistage, RCP | false | false (rattachement seul) |
La logique : pour une source de faible qualité (ALD), non diagnostique (Dépistage) ou souvent mal codée (RCP), le comportement sûr doit être le défaut - sinon on fabrique de faux patients et de fausses tumeurs que l’ARC devra nettoyer. Le data manager surcharge par ligne (ou par fichier) au besoin. Une cellule vide garde le défaut de la typologie.
⚠️ Même quand un data manager force
can_create_tumor = true(ex. sur un dépistage), des garde-fous métier s’appliquent en aval : pas de tumeur sans comportement /2 ou /3, ni sur un dépistage dont le diagnostic final n’est pas « cancer ». Détail dans la page Rattachement des tumeurs.
Exclusion
Section intitulée « Exclusion »Un signalement exclu reste visible sur son patient (sa trace est conservée : dates,
provenance) mais est retiré des tumeurs et de la file d’attachement. Distinct du
signalement en attente (un exclu peut porter un patient). L’exclusion à l’import se fait via une cellule
excluded :
- vide /
0→ non exclu ; 1→ exclu, motif par défaut non précisé (la ligne globale partagée par tous les registres) ;2,3,4… → exclu avec un motif spécifique que le registre a préalablement créé dans son catalogue de motifs ;- toute autre valeur (
oui,non,x,-1,1.5, texte…) → ligne en erreur à la pré-validation : seuls des chiffres sont acceptés.
excluded prime sur can_create_tumor : si les deux sont à true, aucune tumeur n’est
créée - l’exclusion l’emporte et la création automatique de tumeur est ignorée.
Un ARC exclut aussi depuis l’interface : il choisit un motif du catalogue de son registre et
peut ajouter une précision libre (exclusion_comment). Le signalement quitte alors la tumeur
sur laquelle il était rattaché et retombe sur son patient.
Signalements en attente
Section intitulée « Signalements en attente »À l’import, chaque signalement reçoit une identité, mais celle-ci démarre en attente :
tant que l’identito-vigilance ne l’a pas rattachée à un patient, identities.patient_id
reste null. Faute de correspondance et si la création est interdite
(can_create_patient = false), l’identité reste en attente plutôt que d’être jetée : on
pourra relancer l’identito-vigilance plus tard (ex. après correction d’une date de naissance
qui débloque l’appariement) ou forcer la création a posteriori. La gestion fine des signalements en attente
(purge, rétention) reste à construire.
Le format d’import canonique
Section intitulée « Le format d’import canonique »Le SI Registres impose un contrat de colonnes par typologie - le format d’import canonique. C’est au data manager de remapper la source vers ce format avant import. Ce contrat est la source de vérité unique : en-têtes, types, champs obligatoires et nature de chaque champ y sont déclarés une seule fois.
Ce travail de remappage se mutualise entre registres : lorsqu’une même source arrive au même format dans plusieurs départements (un même laboratoire, une même caisse), le script de mapping de l’un pourrait servir aux autres.
Trois natures de champs :
- Fourni - la valeur vient directement du fichier source (nom du patient, code CIM-10…).
- Résolu - déterminé à l’import hors du fichier, déduit d’une valeur fournie (structure résolue depuis le FINESS).
- Calculé - dérivé par le pipeline (code caractérisant, CIM-O-3, groupes IARC). Jamais présent dans le fichier source.
Obligatoire à l’import : l’ensemble minimal de champs fournis qu’une ligne doit porter
pour être acceptée. Une ligne qui en manque un est rejetée (voir Pré-validation ci-dessous). À
distinguer de la nullabilité en base : un champ peut être obligatoire à l’import mais
nullable en stockage. Exemple : le nom du patient (patient_last_name) est obligatoire à
l’import ACP, alors que la colonne correspondante (identities.last_name) reste nullable en
base - l’identité est partagée par toutes les typologies, dont certaines ne l’imposent pas.
Le détail colonne par colonne, le pré-traitement à faire sur chaque source, et un exemple de CSV au format attendu sont dans les fiches pratiques par typologie.
Pré-validation : anomalies et fichier annoté
Section intitulée « Pré-validation : anomalies et fichier annoté »Dès le dépôt du fichier, chaque ligne est examinée contre l’ensemble des règles, et toutes ses fautes sont relevées - une ligne peut porter plusieurs anomalies. Six règles, communes aux six typologies :
| Anomalie | Colonne concernée | Cause |
|---|---|---|
| Champ obligatoire vide | un champ obligatoire à l’import | cellule vide (ou ?) |
| Valeur illisible | toute colonne, obligatoire ou non | contenu que le format attendu ne permet pas de lire : date hors JJ/MM/AAAA, sexe hors M/F, can_create_* hors oui/non, nombre entier avec autre chose que des chiffres… |
| FINESS illisible | structure_finess | FINESS renseigné mais mal formé (un FINESS vide est accepté) |
| Établissement inconnu | structure_finess | FINESS bien formé mais absent du référentiel des structures |
| Motif d’exclusion inconnu | excluded | nombre ≥ 1 absent du catalogue d’exclusion du registre (0 = non exclu ; une valeur non numérique est une valeur illisible) |
| Date dans le futur | patient_birth_date | date de naissance postérieure au jour du dépôt du fichier |
Une ligne portant au moins une anomalie est en erreur et ne sera pas intégrée ; les autres sont valides. Le verdict est figé au dépôt : corriger une ligne se fait en corrigeant le fichier puis en créant un nouvel import.
Pour cela, le fichier annoté reprend le fichier source à l’identique (mêmes colonnes, même séparateur) avec deux colonnes ajoutées en fin de chaque ligne :
statut-valideouerreur;anomalies- la liste des anomalies de la ligne, sous la formeColonne · Cause, séparées par;(vide pour une ligne valide).
Le fichier annoté corrigé peut être redéposé tel quel : ses colonnes statut et anomalies
sont ignorées à l’import et remplacées dans le fichier annoté suivant.
Il se télécharge depuis l’écran de pré-validation (« Exporter le tableau au format CSV » et, dans la fenêtre « Que souhaitez-vous faire ? », le parcours « Corriger les erreurs »). Le fichier est encodé en UTF-8 avec BOM, ce qui permet à Excel de l’ouvrir directement avec les accents.
Une valeur mal formée dans un champ facultatif n’est pas une anomalie : elle est ignorée à l’intégration (le champ reste vide).