Le modèle de données

27 Menregistrements publics, en 21 tables

Chaque table, son volume, et la nature exacte de ce qui la relie aux autres.

La distinction qui compte n’est pas de savoir si deux tables sont liées, mais par quoi. Un trait plein est une clé étrangère : la base en garantit la validité. Un trait pointillé est un rapprochement par nom : une déduction, exposée comme telle plutôt que présentée comme un fait.

Clé étrangère

Contrainte garantie par la base : la ligne référencée existe.

Rattachement par identifiant

Jointure sur le SIREN ou l’uid, sans contrainte — les deux bases sont distinctes. La couverture indique la part réellement rattachée.

Rapprochement par nom

Aucun identifiant commun : on rapproche sur (nom, prénom) normalisés. C’est une déduction, pas une preuve — les homonymes restent possibles.

Dérivation

Table ou vue recalculée à partir d’une autre. Ne contient aucune donnée propre.

Molette pour zoomer, glisser pour déplacer, clic sur une table pour le détail.

entities24 M lignesdepartments101 lignessubsidies663 k lignespublic_finances800 k ligneselus527 k ligneselus_mandats643 k lignespublic_officials12 k lignesofficial_declarations10 k ligneslobbyists4 k lignescategory_stats10 lignescategory_subtype_stats190 lignespurpose_stats21 k lignesmv_* (9 vues)24 k lignesusersvolume variablereportsvolume variablearticlesvolume variableentitySitesvolume variablecapturesvolume variablesitesvolume variablesessionsvolume variablestripe_* (5 collections)volume variable

Les 21 tables, en clair

Volumes exacts, clés primaires et sources. Chaque ligne mène à la page qui explore la donnée.

Tables du modèle de données : domaine, volume, clé primaire, source et lien d’exploration
TableDomaineLignesClé primaireSourceExplorer
Référentiel24 377 820siren (char 9)INSEE SIRENEOuvrir →
Référentiel101code (char 3)Modèle Prisma
Argent public663 219id (cuid)PLF Jaune + EU TransparencyOuvrir →
Argent public799 508id (cuid)DGFiP / OFGLOuvrir →
Personnes526 624idRépertoire national des élus (DGCL)Ouvrir →
Personnes642 925idRépertoire national des élus (DGCL)Ouvrir →
Personnes11 951idHATVPOuvrir →
Personnes10 207idHATVP (XML)Ouvrir →
Personnes3 926idHATVP — représentants d’intérêtsOuvrir →
Couche dérivée10categoryAgrégat de entitiesOuvrir →
Couche dérivée190(category, subType)Agrégat de entitiesOuvrir →
Couche dérivée21 000idAgrégat de subsidiesOuvrir →
Couche dérivée24 000Vues matérialisées sur subsidiesOuvrir →
Applicationuid (Firebase Auth)FirestoreOuvrir →
ApplicationidFirestoreOuvrir →
ApplicationidFirestoreOuvrir →
Applicationsiren_urlHashFirestoreOuvrir →
ApplicationidFirestore + Cloud StorageOuvrir →
Applicationuid_domainFirestoreOuvrir →
Applicationuid_originFirestore
Applicationid StripeFirestore (webhook Stripe)Ouvrir →
Total (hors couche dérivée)27 036 281

Les 25 liens, et ce qu’ils valent

Une clé étrangère est garantie par la base. Un rapprochement par nom est une déduction.

Liens entre tables : origine, cible, nature, clé de jointure et couverture
DeVersNatureCléCouverture
subsidiesentitiesClé étrangère · N–1beneficiaryId → siren100 %
subsidiesentitiesClé étrangère · N–1grantorId → sirenfacultatif
public_financesentitiesRattachement par identifiant · N–1siren81 %
public_financesentitiesRapprochement par nom · N–1UPPER("entityName") ↔ nom d’entité nettoyérepli des 19 % restants
elus_mandatselusClé étrangère · N–1elu_id → id100 %
elus_mandatsentitiesRattachement par identifiant · N–1siren84,8 %
elus_mandatspublic_financesRattachement par identifiant · N–Nsirensitue un mandat dans un budget
lobbyistsentitiesRattachement par identifiant · 1–1siren92 %
official_declarationspublic_officialsRapprochement par nom · N–N(lastName, firstName) sans accentsapproximatif
public_officialselusRapprochement par nom · N–N(nom, prénom) en majusculesapproximatif
entitiesdepartmentsRattachement par identifiant · N–1hqDepartment → codejamais interrogé
category_statsentitiesDérivation · 1–NGROUP BY category
category_subtype_statsentitiesDérivation · 1–NGROUP BY (category, subType)
purpose_statssubsidiesDérivation · 1–NGROUP BY purposeNorm
mv_* (9 vues)subsidiesDérivation · 1–Nvues matérialisées
subsidiespurpose_statsRattachement par identifiant · N–1purposeSlug / purposeNormrésolution d’un objectif
reportsusersRattachement par identifiant · N–1uid
articlesusersRattachement par identifiant · N–1uid
entitySitesusersRattachement par identifiant · N–1uid
capturesusersRattachement par identifiant · N–1uid
sitesusersRattachement par identifiant · N–1uid
sessionsusersRattachement par identifiant · N–1uid
stripe_* (5 collections)usersRattachement par identifiant · N–1userId
entitySitesentitiesRattachement par identifiant · N–1sireninter-base
usersentitiesRattachement par identifiant · N–Nfollowing.{siren}inter-base

Quel point d’API lit quelle table

Une page vide se diagnostique en partant de l’appel qu’elle fait. 38 points d’entrée recensés.

Points d’API et tables qu’ils interrogent
Point d’APITables lues
/addEntitySiteFromExtensionentitySites
/adminArticleQueuearticlesentitySites
/adminStatsusers
/api/auth-bridgesessions
/api/stripe/subscription-statusstripe_* (5 collections)
/api/stripe/webhookstripe_* (5 collections)
/api/v1/capturescaptures
/api/v1/mediacaptures
/api/v1/sitessites
/api/v1/sites/**sites
/askDatausers
/generateReportusers
/getActorDetailsentities
/getActorsByCategoryentitiescategory_statscategory_subtype_stats
/getActorsOverviewentitiescategory_stats
/getArticlesarticles
/getEluDetaileluselus_mandats
/getEntityEluspublic_financeseluselus_mandats
/getLobbyistslobbyists
/getOfficialDetailpublic_officialsofficial_declarations
/getOfficialspublic_officials
/getPublicFinancesentitiespublic_finances
/getSubsidiessubsidies
/getSubsidiesByActorsubsidies
/getSubsidiesByPurposeentitiessubsidiespurpose_statsmv_* (9 vues)
/getSubsidiesOverviewsubsidiesmv_* (9 vues)
/getTopBeneficiariessubsidiesmv_* (9 vues)
/getTopOfficialsofficial_declarations
/getTopRankingspublic_finances
/getUserProfileusers
/reportsreports
/reports/confirmreports
/reports/resolvereports
/reports/submitreports
/searchEluseluselus_mandatspublic_officials
/searchEntitiesentitiespublic_finances
/searchSubsidiessubsidies
/submitArticleFromExtensionarticles

24 points d’attention, table par table

Ce qui est connu, imparfait ou en attente. Une limite tue n’en est pas une de moins.

  • Code mort

    Table DÉCLARÉE dans le schéma mais interrogée par AUCUN point d’API. Elle est pourtant annoncée à l’assistant IA comme disponible : il peut donc la citer alors que rien ne l’alimente ni ne la lit.

  • À surveiller

    Reclassification des catégories juridiques en attente : les lignes chargées avant la correction portent encore l’ancienne catégorie.

  • À surveiller

    18,6 M d’entités privées ne sont pas indexées pour la recherche par nom (la recherche par SIREN fonctionne).

  • À surveiller

    Exercices 2013, 2014 et 2016 partiels : les fichiers PLF correspondants manquent à la source.

  • À surveiller

    EPCI : 0 ligne importée — les champs de la source sont incompatibles avec le lecteur actuel.

  • À surveiller

    19 % des exercices n’ont pas de SIREN exploitable ; le rattachement retombe alors sur une comparaison de NOMS en majuscules.

  • À surveiller

    15,2 % des mandats n’ont pas de SIREN exploitable : ils ne peuvent pas être rapprochés d’une commune ni d’un budget.

  • À surveiller

    Aucun identifiant commun avec le répertoire des élus : le rapprochement se fait sur (nom, prénom), avec un risque d’homonymie.

  • À surveiller

    Montants aberrants dans la source (jusqu’à 61,5 M€ pour un mandat parlementaire) : affichés tels quels, documentés dans le rapport sur les données.

  • À surveiller

    Reconstruit à l’import : tant que la reclassification n’a pas tourné, ces compteurs reflètent l’ancienne répartition.

  • À surveiller

    Rafraîchies uniquement à l’import : entre deux imports, elles peuvent diverger de la table source.

  • À surveiller

    Contient des jetons de session de sites TIERS. Chiffrés au repos et jamais lisibles par un client, avec expiration à 30 jours — mais aucune tâche planifiée ne purge encore les documents expirés.

  • Bon à savoir

    Ni code postal ni département pour la majorité des entités : le champ est absent du fichier importé.

  • Bon à savoir

    Espaces insécables dans certains objectifs — nettoyés à la lecture, d’où la colonne purposeNorm.

  • Bon à savoir

    Montants stockés en milliers d’euros, convertis en euros par l’API.

  • Bon à savoir

    Mandats antérieurs à 2020 non encore intégrés (2014 et 2008 à venir).

  • Bon à savoir

    47 déclarations de patrimoine seulement, contre 10 166 déclarations d’intérêts.

  • Bon à savoir

    Existe parce qu’un GROUP BY direct sur la catégorie SECTEUR_PRIVE (19,1 M de lignes) dépassait le délai maximal de requête.

  • Bon à savoir

    Ne couvre que les subventions aux associations : les objectifs des aides d’État vivent dans mv_purposes_stateaid, d’où l’union à la résolution d’un objectif.

  • Bon à savoir

    Les champs qui portent des droits ou de la facturation sont écrits par le serveur uniquement — les règles Firestore les refusent au client depuis le 3 août 2026.

  • Bon à savoir

    cityCode porte un code INSEE mais n’est rattaché à aucune table : la commune d’un signalement n’est pas jointe au référentiel.

  • Bon à savoir

    Seul pont entre l’application et le socle analytique. Le SIREN n’est contraint par rien : les deux bases sont distinctes.

  • Bon à savoir

    Les médias sont privés et servis après vérification de propriété. Les captures déposées avant le 3 août 2026 restent publiques au niveau du stockage : une purge des anciennes autorisations est à faire.

  • Bon à savoir

    stripeEvents sert de verrou d’idempotence : un même événement livré deux fois n’est traité qu’une fois.

Ce que cette carte ne dit pas

Les volumes sont un relevé du 2 août 2026, pas un compteur temps réel. Les rattachements par SIREN ne sont jamais complets : 81 % des comptes publics et 84,8 % des mandats trouvent leur entité, le reste n’a pas de SIREN exploitable dans la source. Enfin, la catégorie juridique des entités fait l’objet d’une reclassification en cours — voir le rapport sur les données.