Override CSS scopé aux classes .btn-* (jamais les variables --bs-* racine,
donc alertes/badges inchangés) pour remplacer les couleurs dérivées du thème
Simplex (danger mauve, secondary gris illisible). Trois rôles : la couleur
encode la fonction, le remplissage l'emphase.
- primary terracotta : action principale validante
- secondary gris ardoise : action neutre/alternative (lisible)
- danger rouge #c0392b : destructif (outline par défaut, plein en confirmation)
Audit + conformation des usages :
- compte_admin « Supprimer mon compte » : primary outline -> danger outline
- compte_abonnement « Me désabonner » : outline-primary -> outline-danger
- compte_abonnement « Je suis sûr » : outline-primary -> danger plein
Tests : ajout tests/test_boutons.py (garde de non-régression du primary).
conftest : implémente le hook pytest_setup_options (--headless=new) ; la
fixture chrome_options n'était jamais utilisée par dash.testing, d'où les
fenêtres Chrome qui s'ouvraient pendant les tests.
Specs et plan : docs/superpowers/{specs,plans}/2026-06-30-charte-boutons*.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Avec prevent_initial_call=True, le callback ne s'exécutait pas lors de
la chaîne initiale (_generate_csrf_token → csrf-token), laissant le champ
csrf_token vide au premier chargement direct de /connexion → erreur 400.
Ajoute des tests comportementaux avec CSRF activé (comme en production) et
un test architectural qui vérifie que le callback reste appelable initialement.
Corrige aussi les assertions de redirection post-login (/compte/abonnement).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Affiche un bandeau d'info sur /compte/abonnement et grise les boutons
S'abonner quand l'accès gratuit pour tous est activé.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ouvre les fonctionnalités d'abonné à tout utilisateur connecté tant que
Frisbii n'a pas validé la réception de paiements.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Workaround nonce OIDC LinkedIn (non-conformité) : capture MissingClaimError après échange de code réussi et fetch userinfo séparément
- Ajout token_endpoint_auth_method: client_secret_post (requis par LinkedIn)
- suppress_callback_exceptions=True pour corriger les erreurs Dash multi-pages
- Suppression bouton déconnexion redondant sur /compte/admin et style hover incorrect sur la navbar
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds pending_email column to users table with idempotent migration.
Implements set_pending_email() and promote_pending_email() for email-change workflow.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implement CLI interface for the backup module with three subcommands:
- backup: create a backup and apply rotation
- list: list available backups
- restore: restore a specific backup
Also add __main__.py to enable 'python -m src.backup'.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Wraps temp file operations in try/except to ensure the temporary database file is always cleaned up, even if an exception occurs during write_snapshot or verify_integrity.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implémente les trois fonctions de gestion de snapshots SQLite:
- make_snapshot: crée un snapshot gzippé cohérent via sqlite3.Connection.backup()
- write_snapshot: écrit le snapshot décompressé à destination
- verify_integrity: valide l'intégrité d'une base avec PRAGMA integrity_check
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>