Skip to content

feat: refonte dynamique de la page Perspectives#504

Merged
cyrilledaily merged 9 commits intomainfrom
feat/perspectives-revamp
Feb 17, 2026
Merged

feat: refonte dynamique de la page Perspectives#504
cyrilledaily merged 9 commits intomainfrom
feat/perspectives-revamp

Conversation

@m4xim1nus
Copy link
Collaborator

Summary

  • Remplace le contenu statique de la page Perspectives par des données temps réel issues de PostgreSQL
  • KPIs dynamiques : collectivités (total vs soumises à la loi), marchés publics, subventions, couverture, scores A/B
  • 3 sections de graphiques Recharts : comparaison par type de collectivité, évolution des scores, volumes
  • Filtre les communes < 3 500 habitants (non soumises à la loi pour une République numérique)
  • Encart sur le classement européen de la France en open data

TODO (prochain commit)

  • La section "Bons et mauvais élèves" (ScoreByTypeChart) apparaît vide — à investiguer
  • Filtrer les montants aberrants de subventions

Test plan

  • Vérifier que la page /perspectives charge correctement avec les données de la BDD
  • Vérifier les KPIs (nombres exacts, couverture < 100%, scores A/B cohérents)
  • Tester les filtres par type de collectivité sur le graphique d'évolution des scores
  • Vérifier que les graphiques de volume s'arrêtent à l'année courante
  • Tester le responsive (mobile / desktop)

🤖 Generated with Claude Code

Remplace le contenu statique par des données temps réel issues de PostgreSQL.

- KPIs dynamiques : collectivités, marchés publics, subventions, couverture, scores
- Graphiques Recharts : distribution des scores par année et par type, volumes
- Filtre des communes < 3500 habitants (non soumises à la loi)
- Encart France championne européenne de l'open data

TODO: la section "Bons et mauvais élèves" (ScoreByTypeChart) apparaît vide,
à investiguer dans un prochain commit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Contributor

:octocat: Preview is deploying...

Please wait while the preview is deploying on Clever Cloud...

ℹ️ Name 🔗 Infos & links
🌱 Deploying commit d069141
👁️ Preview Generating preview app...

m4xim1nus and others added 5 commits February 17, 2026 23:08
pg retourne les BIGINT comme strings en JS. La comparaison stricte
row.annee !== year échouait silencieusement (\"2024\" !== 2024).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…grée

- Intègre le classement France championne dans l'introduction
- Supprime l'encart séparé
- Titres de section porteurs du message principal

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…alyses

Les anciennes mentions "seules 10% le font" / "Anticor a évalué" étaient
une estimation initiale sur échantillon. Reformulé avec le constat actuel
d'Éclaireur Public (majorité ne publie pas, subventions quasi inexistantes).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…alyses

Les mentions "seules 10% le font" / "Anticor a évalué sur un échantillon
que moins de 10%" étaient une estimation initiale. Reformulé en s'appuyant
sur le constat d'Éclaireur Public sans toucher au reste du texte éditorial.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@cyrilledaily
Copy link
Collaborator

Great work @m4xim1nus — this is a big upgrade from the static page. The dynamic KPIs, the Recharts charts, and the editorial rewrite are all well-structured. A few things to address before merging:


🔴 Critical: Outlier amounts will show absurd numbers

The KPI query sums montant_du_marche_public_par_titulaire and montant without any outlier filtering. I checked production data:

Raw total Clean total Ratio
Marchés publics 3 213 T€ 791 Md€ 99.97% from outliers
Subventions 8.78e18 € (!!!) 277 Md€ essentially all outliers

The page would display something like "3 213 T€ de marchés publics" which is nonsensical.

Fix for marchés: filter on montant_aberrant = false (or IS NULL) in mp_stats and mp_yearly:

WHERE (montant_aberrant IS NULL OR montant_aberrant = false)

Fix for subventions: there's no montant_aberrant column on subventions yet, so add a threshold filter:

WHERE montant <= 1000000000  -- 1 Md€

This is the same approach as our insights dashboard — 780 subventions above 1B€ account for 99.997% of the total.


🟡 LATEST_SCORE_YEAR = 2024 is hardcoded

This constant is used for the KPIs and passed as year={2024} to ScoreByTypeChart. It will silently become stale when 2025 data is loaded. Consider fetching it dynamically:

SELECT MAX(annee) FROM bareme WHERE annee <= EXTRACT(YEAR FROM NOW())

🟡 No caching — 4 heavy queries on every page load

The KPIs query alone takes ~1.2s on production. With all 4 queries in Promise.all, the page load is bound by the slowest one. Since this data changes only after ETL runs (not per-request), consider adding:

export const revalidate = 3600; // cache for 1 hour

at the top of page.tsx. This is a standard Next.js pattern for ISR.


🟡 SCORE_COLORS and TYPE_LABELS are duplicated

SCORE_COLORS is defined identically in both ScoreByTypeChart.tsx and ScoreDistributionChart.tsx. TYPE_LABELS is partially duplicated too. Extract these to a shared constants file (e.g., perspectives/constants.ts).


🟢 Minor: montant_du_marche_public_par_titulaire inflates totals

Using the per-titulaire amount means multi-titulaire marchés are summed multiple times. For example, a 1M€ marché with 3 titulaires (each getting 333K) counts correctly. But if you wanted to show the total value of contracts, you'd use montant_du_marche_public grouped by id_mp first. Worth a comment at minimum to explain the choice.


🟢 Minor: Text changes are good

Replacing "seules 10% le font" (old Anticor sample estimate) with "la grande majorité ne le fait pas" is more accurate and defensible. The wording in ProjectDescription.tsx and WhyChallenge.tsx is good.


Overall this is a very nice piece of work — the page will be much more compelling with real data. The outlier filtering is the only blocker IMO; the rest can be follow-ups.

CyrilleDS and others added 3 commits February 18, 2026 00:13
…constants

- Filter montant_aberrant for marchés publics and montant > 1 Md€ for
  subventions in KPI totals and yearly volume charts so that extreme
  outliers no longer skew the displayed amounts.
  TODO: switch subventions filter to montant_aberrant once the column
  is added to the subventions table by the ETL pipeline.
- Replace hardcoded LATEST_SCORE_YEAR = 2024 with a dynamic
  MAX(annee) query from the bareme table so the page stays current
  after each ETL run without code changes.
- Add `export const revalidate = 3600` (ISR) to the perspectives page
  so the 4 heavy DB queries are cached for 1 hour instead of running
  on every page load.
- Extract duplicated SCORE_COLORS, SCORE_ORDER, TYPE_LABELS and
  TYPE_ORDER into a shared constants.ts file used by both
  ScoreByTypeChart and ScoreDistributionChart.

Co-authored-by: Cursor <cursoragent@cursor.com>
The bareme table contains rows up to 2026, but 2025/2026 data is far
too sparse — especially for subventions — to produce meaningful KPIs
or score distributions.  Pin REFERENCE_SCORE_YEAR = 2024 (the latest
year with reasonably complete data) with a clear comment explaining
when and why to bump it.

Co-authored-by: Cursor <cursoragent@cursor.com>
@cyrilledaily cyrilledaily merged commit a29a1a7 into main Feb 17, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants