Commit Graph

1005 Commits

Author SHA1 Message Date
Colin Maudry 99abdfed0b docs(brevo): plan d'implémentation + maj spec avec l'API v5 vérifiée (#87)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 15:19:42 +02:00
Colin Maudry f41ee64c32 docs(brevo): spec de migration des emails transactionnels vers Brevo (#87)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 15:08:09 +02:00
Colin Maudry afe99ea79f fix(auth): utiliser threading.local() pour les connexions SQLite par thread
La connexion singleton partagée entre threads causait sqlite3.InterfaceError
lors de requêtes concurrentes sur la page compte.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 12:23:55 +02:00
Colin Maudry 7be0332f02 Merge branch 'dev' into feature/73_compte_utilisateur 2026-06-24 05:34:27 +02:00
Colin Maudry 8830b2ac91 fix(test): mettre à jour les assertions de compute_considerations_stats pour le retour en 3-tuple
La fonction retourne désormais (count_ren, count_pos_ren, pct) pour les clés
_renseignees, mais les tests attendaient encore l'ancien format (count_ren, pct).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 05:34:03 +02:00
Colin Maudry b1c33c29ed Env MAIL_SUPPRESS_SEND 2026-06-24 05:29:24 +02:00
Colin Maudry c99f4d970e fix(csrf): centraliser l'injection des tokens CSRF via un dcc.Store et un callback pattern-matching
Remplace les 7 callbacks CSRF individuels (un par formulaire, avec IDs string
page-spécifiques) par un seul dcc.Store(id="csrf-token") dans le layout principal
et un callback pattern-matching Output({"type": "csrf-input", "index": ALL}).
Évite les erreurs Dash "id non trouvé dans le layout" sans recourir à
suppress_callback_exceptions=True.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 05:26:07 +02:00
Colin Maudry c228f7be55 fix(auth): corriger le lien de validation email et l'isolation des tests
Le lien de vérification pointait vers la page Dash /verification-email
(qui se contente de rediriger vers /connexion) au lieu de la route
backend /auth/verify-email qui consomme réellement le token et marque
l'email comme vérifié. Conséquence : l'email n'était jamais validé et le
login renvoyait email_not_verified en boucle.

Ajoute aussi MAIL_SUPPRESS_SEND=true au bloc env de pytest : sans cela,
le load_dotenv() de src.app injectait MAIL_SUPPRESS_SEND=false depuis le
.env local, désactivant la suppression d'envoi et faisant échouer les
tests d'auth qui envoient un email (selon l'ordre d'import).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-24 03:55:52 +02:00
Colin Maudry 4e1c610405 feat(auth): découpler MAIL_SUPPRESS_SEND de DEVELOPMENT et logger les emails supprimés
Ajoute la variable MAIL_SUPPRESS_SEND pour pouvoir tester l'envoi d'emails
en mode développement sans toucher au flag DEVELOPMENT. Un warning est loggé
à chaque tentative d'envoi supprimée avec la cause et les détails du message.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 03:43:55 +02:00
Colin Maudry cbce646fd8 Merge branch 'dev' into feature/73_compte_utilisateur 2026-06-24 03:01:43 +02:00
Colin Maudry a6f60ce3c4 Cache le champ de filtrage pour la colonne 'Marché' 2026-06-24 02:56:42 +02:00
Colin Maudry f9aefb55d8 feat(titulaire): afficher le libellé d'activité NAF en sous-titre gris
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 22:32:12 +02:00
Colin Maudry d99bb00d6c Compactage 2026-06-23 20:16:51 +02:00
Colin Maudry afdd3c8904 Ajout de openpyxl explicite #83 2026-06-23 20:16:24 +02:00
Colin Maudry ad0a220953 feat(tableaux): scroll horizontal ergonomique + barre custom (#82)
- Barre de défilement JS orange (12px) injectée en haut de chaque
  .marches_table, collée avec position:sticky, masquée si le tableau
  tient dans le viewport
- Scroll contenu dans .dash-spreadsheet-container (overflow-x:hidden)
  → plus de scrollbar navigateur en bas de page
- Drag souris + tactile, clic sur le track, molette/trackpad
- Recalcul automatique au resize et aux re-renders Dash (MutationObserver)
- Test Selenium de non-régression (overflow-x:hidden sur le conteneur)

Sticky headers abandonnés (incompatibles avec scroll contenu).
Portée : 4 pages via la classe partagée .marches_table.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 20:12:47 +02:00
Colin Maudry f508c821c2 test(tableaux): adapter test post-abandon sticky headers #82
Le test ne vérifie plus position:sticky sur th (sticky abandonné car
incompatible avec scroll contenu). Vérifie à la place que overflow-x:hidden
est bien en place sur le conteneur Dash — garantit l'absence de scrollbar
navigateur en bas de page.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 20:00:41 +02:00
Colin Maudry 45526f7c7b fix(tableaux): restaurer position:sticky sur la barre, 12px #82
Le retrait de position:sticky sur .dt-hscroll avait cassé le layout
(bouton Remettre à zéro visible au mauvais endroit, z-index perdu).
La barre redevient sticky top:0 z-index:11 — les th.dash-header restent
sans sticky ni z-index (ils ne fonctionnaient de toute façon pas en
scroll contenu).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 19:52:42 +02:00
Colin Maudry 5e64a4553d fix(tableaux): supprimer sticky headers, barre 12px #82
- Retire position:sticky/z-index sur th.dash-header (abandonnés avec
  le scroll contenu : overflow-x:hidden crée un scroll container qui
  empêche le sticky page-level, et le z-index provoquait un recouvrement
  des champs de filtre)
- Retire la règle :has() devenue inutile
- Barre de scroll réduite à 12px

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 19:46:43 +02:00
Colin Maudry 2e22fcabe9 fix(tableaux): scroll contenu dans dashContainer, plus de scrollbar page #82
Remplace le scroll de page (window.scrollTo) par dashContainer.scrollLeft :
- overflow-x:hidden sur .dash-spreadsheet-container → la table ne déborde
  plus la page → scrollbar navigateur en bas éliminée
- overflow-y:clip évite la conversion CSS visible→auto (pas de scrollbar
  vertical parasite sur le conteneur)
- metrics(), syncThumb, drag et clic utilisent tous dashContainer
- wheel handler capture les gestures trackpad horizontaux et les redirige
  vers dashContainer.scrollLeft

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 19:20:41 +02:00
Colin Maudry 3c0cf6bc07 fix(tableaux): barre pleine largeur viewport + masquage par table #82
- adjustBarWidth() brise le padding Bootstrap (margin-left négatif +
  width: 100vw) pour que la barre s'étende jusqu'au bord de la fenêtre
- metrics() utilise window.innerWidth comme largeur de piste (cohérent
  avec la barre pleine largeur)
- hasOverflow mesure la largeur de .cell-table de CETTE table via
  getBoundingClientRect(), plutôt que document.documentElement.scrollWidth
  → les petits tableaux (top10 /acheteur, /titulaire, /observatoire)
  n'affichent pas de barre s'ils ne débordent pas individuellement

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 19:02:36 +02:00
Colin Maudry 9c5fc9257a fix(tableaux): thumb custom toujours visible, drag souris et tactile #82
Remplace le scrollbar natif (invisible en mode overlay sous Linux) par
un thumb div orange toujours visible. Track gris (#e0e0e0) 16px.
Drag souris + toucher + clic sur le track supportés.
Supprime la dépendance aux pseudo-éléments webkit et scrollbar-color.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 18:50:51 +02:00
Colin Maudry 0edca05df5 fix(tableaux): barre 16px toujours visible, headers décalés en dessous #82
- overflow-x:scroll force le thumb orange toujours visible (pas overlay)
- hauteur 16px pour le drag-and-drop
- :has(.dt-hscroll:not(.is-hidden)) décale les th à top:16px quand la
  barre est présente, évitant le recouvrement

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 18:26:36 +02:00
Colin Maudry 099fba58f7 fix(tableaux): option A — sync barre avec window.scrollX + style orange #82
Abandonne le wrapper overflow-x (incompatible avec position:sticky des
en-têtes). La barre contrôle désormais le scroll horizontal de la page
via window.scrollTo/scrollX, ce qui préserve le sticky des th.
Scrollbar orange 12px, styling webkit + Firefox.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 18:22:08 +02:00
Colin Maudry 817aeedc6f fix(tableaux): garde hscrollReady après vérification dashContainer #82
Si la garde est posée avant de vérifier que dashContainer existe, un
déclenchement prématuré de rootObs (avant le rendu Dash) marque le
wrapper comme traité sans jamais injecter le scroll wrapper.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 17:42:50 +02:00
Colin Maudry 1d27d517f3 fix(tableaux): garde hscrollReady avant manipulation DOM #82
Évite la boucle infinie : le rootObs se déclenchait sur les insertions
DOM de setup() avant que la garde ne soit posée, relançant setup() en
boucle et faisant monter le CPU.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 17:33:09 +02:00
Colin Maudry a5e802d20a refactor: use write_styled_excel in all download callbacks #83 2026-06-23 17:14:16 +02:00
Colin Maudry e5ca7d62a3 fix: protect wb.close() with try/finally, strengthen width assertions, declare openpyxl dev dep #83
- I-1: Add explicit lower bounds to width assertions (>= 15 for autre, >= 40 for objet)
- I-2: Wrap write_excel() and close() in try/finally to ensure cleanup even on exception
- M-2: Add openpyxl to dev dependencies in pyproject.toml

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 17:08:32 +02:00
Colin Maudry 35e72645bd feat: add write_styled_excel utility for styled Excel exports #83
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 17:05:55 +02:00
Colin Maudry 39dfa22b0d Plan : amélioration du style des exports Excel #83
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 17:00:28 +02:00
Colin Maudry 96c0b0dd35 fix(tableaux): scroll horizontal via wrapper overflow-x auto #82
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 16:52:22 +02:00
Colin Maudry 10ed9c4c4b Spec : amélioration du style des exports Excel #83
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-23 16:21:20 +02:00
Colin Maudry ce4b06fe3d refactor(tableaux): commentaires et nettoyage table_hscroll.js #82
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 16:14:20 +02:00
Colin Maudry 2413ffb4f0 test(tableaux): barre miroir et en-tête sticky sur /tableau #82
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 16:05:49 +02:00
Colin Maudry cb1685d055 feat(tableaux): barre de défilement horizontale miroir synchronisée #82
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 16:00:45 +02:00
Colin Maudry 4be82ac76b feat(tableaux): en-têtes de colonnes collants #82
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 15:58:49 +02:00
Colin Maudry 83d38f8489 Correction du mode d'emploi sur l'accentuation 2026-06-23 15:48:37 +02:00
Colin Maudry ec2b8389c3 docs: verdict spike DOM tableaux #82
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 15:44:11 +02:00
Colin Maudry 3e305845dd Fix réduction du nombre de colonne, ajoute de lla colonne Marché #84 2026-06-23 15:28:42 +02:00
Colin Maudry 68bd398759 docs: plan d'implémentation scroll horizontal tableaux #82
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 15:14:03 +02:00
Colin Maudry 0ed807f98c docs: design scroll horizontal + en-têtes sticky des tableaux #82
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 15:08:47 +02:00
Colin Maudry f94701207b Fix non split des DISPLAYED_COLUMNS 2026-06-23 14:13:30 +02:00
Colin Maudry fc22eca661 Changelog 2.8.0 v2.8.0 2026-06-23 07:06:44 +02:00
Colin Maudry e591c5500f Petites améliorations du rendu #81 2026-06-22 22:47:37 +02:00
Colin Maudry 074716bc16 feat(observatoire): restructurer tuile en 3 barres
- Barre 1 (grise) : % marchés avec champs considérations renseignés
- Barre 2 (rose)  : % positifs parmi les marchés renseignés — sociales
- Barre 3 (verte) : % positifs parmi les marchés renseignés — env

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 22:21:37 +02:00
Colin Maudry ae8292d68d fix(observatoire): filtre renseignées sur != 'Sans objet' plutôt que regex
Seule 'Sans objet' est considérée négative parmi les marchés renseignés,
cohérent avec le reste des traitements.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 22:02:37 +02:00
Colin Maudry 26455a7616 fix(observatoire): barre renseignée = positifs parmi les marchés renseignés
Dénominateur = marchés non-null ; numérateur = marchés positifs (regex).
Label affiché : "parmi les N marchés renseignés".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 21:18:00 +02:00
Colin Maudry 19e181734c feat(observatoire): ajouter barres 'valeur renseignée' dans tuile considérations
Affiche 4 barres groupées par type (sociales/env) : une pour les marchés
avec au moins une considération, une pour ceux qui ont une valeur renseignée
(non nulle, y compris 'Sans objet').

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 18:55:38 +02:00
Colin Maudry 8efd9b45eb fix(observatoire): texte % blanc sur les barres de considérations
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 18:46:37 +02:00
Colin Maudry eab06eedae fix(observatoire): couleurs barres considérations palette Plotly Safe
Utilise les codes hex #CC6677 (sociales) et #117733 (env) via le prop
color de dbc.Progress, qui accepte les valeurs hex.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 18:45:33 +02:00
Colin Maudry 5586db23aa feat(observatoire): afficher la tuile considérations après Type d'achat
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-22 18:17:27 +02:00