Application de révision espacée (web) basée sur la méthode de Leitner, avec édition Markdown/LaTeX, stockage local-first, synchronisation cloud optionnelle (delta), partage de decks, notifications push et catalogue de packs publics via Supabase.
- Aperçu
- Fonctionnalités
- Stack technique
- Comment l'application fonctionne pas à pas
- Architecture des données
- Démarrage rapide web
- Variables d'environnement
- Scripts utiles
- Pipelines de contenu et geo
- Tests
- Déploiement
- Structure du projet
- Limites connues
- Licence
Application web React/Vite 100 % locale (IndexedDB), avec :
- un moteur Leitner déterministe (boîtes 0 à 5),
- une sync optionnelle vers Supabase (delta incrémental, last-write-wins),
- le partage de decks via lien public,
- des notifications Web Push quotidiennes,
- des scripts de génération/import de packs publics.
- Sessions de révision quotidiennes avec progression Leitner.
- Undo de la dernière réponse pendant une session.
- Raccourcis clavier globaux et recherche globale.
- Support Markdown + KaTeX (formules) sur front/back.
- Tags hiérarchiques (
Maths/Algèbre,Geo/Europe/...). - Import/export JSON (avec média et logs) + import/export Anki (
.apkg). - Import CSV/TSV.
- Bibliothèque avec filtres par tags, texte et boîtes.
- Partage de decks — générer un lien
/share/:id, importable par n'importe qui. - Packs publics Supabase importables en local (idempotent).
- Dashboard stats avancé (volume, progression, boîtes, tags, streaks, taux de réussite).
- Paramètres Leitner : intervalles, objectif quotidien, maintenance learned, reverse Q/A.
- Sync cloud optionnelle : sync complète au login puis delta incrémentale (filtre
updated_at >= lastSync - 30s). - Notifications Web Push — rappel quotidien si des cartes sont dues (opt-in).
- PWA — installable, cache offline complet.
- Dark mode.
- Internationalisation français/anglais.
- Frontend web : React 19, TypeScript strict, Vite, React Router 7.
- Stockage local web : Dexie (IndexedDB).
- Backend externe : Supabase (auth, tables
user_*,shared_decks, packs publics). - PWA :
vite-plugin-pwa+ Workbox. - Tests : Vitest + React Testing Library +
fake-indexeddb.
- Une carte créée manuellement ou importée est stockée localement.
- Un
ReviewStateest créé automatiquement avecbox=0etdue_date=null. - Les packs publics importés sont marqués avec
source_type='supabase_public'pour éviter les doublons.
- Le moteur charge les
ReviewStatelocaux. - Il complète la Boîte 1 chaque jour jusqu'à
box1Targeten promouvant des cartesbox=0(si disponibles), avecdue_date=today. - Il sélectionne les cartes dues (
box>=1etdue_date <= today). - Il ajoute aussi les cartes
learneddues en maintenance (learned_at + learnedReviewIntervalDays <= today).
- La question est affichée, puis la réponse après action utilisateur.
- Selon
reverseProbability, front/back peuvent être inversés aléatoirement. - L'utilisateur répond
GoodouBad. Il peut annuler la dernière réponse.
Good: promotion de boîte (jusqu'à 5).Gooddepuis la boîte 5 : carte marquéelearned, sortie du flux standard.Bad: retour en boîte 1.- Chaque réponse crée un
ReviewLog.
- Les stats sont calculées depuis les données locales (cartes, review states, logs).
- Les écrans montrent : due du jour, répartition par boîtes, progression 7/30 jours, perf par tags, streaks.
- Si l'utilisateur se connecte (Supabase Auth), la sync est activée.
- Sync complète au premier login (snapshot total).
- Sync delta ensuite : seules les lignes modifiées depuis
lastSyncAt - 30ssont récupérées côté remote, et seules les cartes nouvelles (sanscloud_id) sont poussées — les cartes déjà synchronisées absentes du snapshot delta sont ignorées (pas de résurrection). - Sync toutes les 15 secondes (debounce) + au focus fenêtre.
flowchart LR
A["Create / Import Card"] --> B["Local DB: box=0"]
B --> C["Build Daily Session"]
C --> D["Review Card"]
D -->|Good| E["Promote Box"]
D -->|Bad| F["Back to Box 1"]
E --> G["If Box 5 + Good => learned"]
F --> H["Write ReviewLog"]
G --> H["Write ReviewLog"]
H --> I["Update Stats"]
H --> J["Optional Cloud Sync (delta, if logged in)"]
cards: contenu des cartes + metadata source/sync.reviewStates: état Leitner courant par carte.reviewLogs: historique des réponses.media: blobs associés aux cartes.
user_cards,user_progress,user_review_log,user_settings: sync utilisateur.shared_decks: decks partagés publiquement (lecture publique, écriture propriétaire).packs,public_cards: packs publics.
- Node.js 20+ recommandé.
- npm.
- Un projet Supabase (URL + anon key) pour packs/auth/sync.
npm installCréer /.env.local :
VITE_SUPABASE_URL=https://<project-ref>.supabase.co
VITE_SUPABASE_ANON_KEY=<anon-key>npm run dev- Ouvrir l'app web.
- Aller dans
Packs, ouvrir un pack, cliquerImport. - Aller dans
Libraryet vérifier les cartes. - Lancer
Review, répondre à quelques cartes. - Ouvrir
StatspuisSettingspour vérifier la persistance.
VITE_SUPABASE_URLVITE_SUPABASE_ANON_KEY
SUPABASE_URLSUPABASE_SERVICE_ROLE_KEYSUPABASE_DB_URL(requis pour certaines opérations SQL/seed)COUNTRIES_EXCLUDE_ANTARCTICA=1(optionnel)
ALLOW_DESTRUCTIVE_SUPABASE=1ALLOW_DESTRUCTIVE_COUNTRIES=1
npm run dev: démarre l'app web.npm run build: build TypeScript + Vite.npm run preview: sert le build.npm run lint: lint ESLint.
npm run test: tests unitaires.npm run test:watch: tests en watch.npm run check: lint + typecheck + tests.
npm run supabase:buildnpm run seed:packsnpm run seed:countries-packnpm run seed:departements-packnpm run pipeline:geo-pack
npm run pipeline:countriesnpm run pipeline:departementsnpm run pipeline:departements-pack
- Génération SVG (
out/svg/{ISO2}.svg+out/preview.html). - Upload vers bucket Supabase
country-maps. - Seed/upsert SQL de
public.countries.
npm run gen:country-svgs
npm run upload:country-svgs
npm run seed:countries
# ou pipeline complet
npm run pipeline:countriesnpm run gen:departement-svgs
npm run upload:departement-svgs
npm run seed:departements-table
npm run pipeline:departementsCommandes principales :
npm run test
npm run checkCouverture actuelle :
- Moteur Leitner (algorithme, intervalles,
is_learned). - Logique de sync (delta guard, delta resurrection,
pendingDeletes, résistance réseau). - Composants Markdown/media.
- Smoke tests des routes principales.
- SharedDeck (import, déduplication, retry après erreur).
- Notifications (permission, garde once-per-day).
- Workflow :
/.github/workflows/deploy-web.yml - URL : https://v0latix.github.io/Flashcards/
- Secrets requis :
VITE_SUPABASE_URL,VITE_SUPABASE_ANON_KEY.
.
├── src/
│ ├── routes/ # Pages React Router (Library, Review, Stats, SharedDeck…)
│ ├── leitner/ # Moteur Leitner + settings
│ ├── sync/ # Sync engine (delta + full) + remoteStore
│ ├── db/ # Schéma Dexie + migrations
│ ├── notifications/ # Service notifications + hook
│ ├── supabase/ # Client Supabase + sharedDecks + auth
│ ├── i18n/ # Traductions fr/en
│ └── supabase-pipeline/ # Seeds packs publics
├── supabase/ # Migrations SQL
├── packs/ # Packs JSON locaux
├── docs/ # Specs, ADRs, contexte projet
├── src/countries-pipeline/
└── src/departements-pipeline/
- Pas de vraie suite E2E complète (tests majoritairement unit/smoke).
- Les appels Supabase ne sont pas exécutés en réseau réel pendant les tests.
MIT. Voir LICENSE.