Skip to Content
React Native19. Projets guidésNiv.5 — Drill v2 ⭐

Projet Niv. 5 — ⭐ Drill v2 : la révision espacée

Le brief : le capstone. Drill apprend de VOS erreurs : les questions ratées reviennent plus souvent (boîtes de Leitner), un mode « Révision » cible vos faiblesses, les stats montrent la progression réelle. La boucle pédagogique se ferme — sur l’app ET sur vous.

Ce que vous allez pratiquer

TOUT — c’est le principe d’un capstone : l’algorithme en lib/ pur testé à fond, une migration v2 sur des données EXISTANTES (vos mois d’historique !), l’évolution d’une app en production (OTA, versionnage), et les décisions de conception en autonomie. Chapitres liés : 6.3, 8.2, 8.3, 12.5-12.6, 14.2.

Le système de Leitner (la spec)

Chaque question connue de l’utilisateur vit dans une boîte 1-5 :

  • Nouvelle question rencontrée → boîte 3.
  • Bonne réponse → boîte +1 (max 5). Mauvaise → boîte 1 (retour à la case départ).
  • La boîte définit l’échéance de révision : B1 = 1 jour, B2 = 3 j, B3 = 7 j, B4 = 14 j, B5 = 30 j.
  • Une question est due si now >= lastAnswered + interval(box).

Le mode Révision tire d’abord les questions DUES (les plus anciennes d’abord), complète avec des nouvelles si besoin. C’est SM-0 simplifié — largement suffisant, et VOS données d’answers depuis la P8 alimentent tout.

L’architecture recommandée

  • La migration v2 (le moment le plus formateur du projet) :
-- v2 : l'état de révision par question CREATE TABLE review_state ( question_id TEXT PRIMARY KEY, -- l'id STABLE du repo (le contrat du ch. 7.3 paie ici) box INTEGER NOT NULL DEFAULT 3, last_answered_at INTEGER NOT NULL, times_seen INTEGER NOT NULL DEFAULT 0 ); -- + le BACKFILL : reconstruire l'état depuis la table answers existante INSERT INTO review_state (question_id, box, last_answered_at, times_seen) SELECT question_id, MAX(1, MIN(5, 3 + SUM(CASE WHEN correct THEN 1 ELSE -2 END))), -- heuristique MAX(rowid) /* … le vrai last : sous-requête sur answers */, COUNT(*) FROM answers GROUP BY question_id;

Le backfill est la leçon : vos mois d’historique deviennent l’état initial — une migration qui TRANSFORME des données, pas juste un ALTER. (L’heuristique exacte est à vous : documentez-la dans la migration même.)

  • lib/leitner.ts, pur, testé AVANT : nextBox(box, correct), isDue(state, now), pickReviewQuestions(states, all, count, now, rng) — l’horloge et le hasard en paramètres (les leçons de la P14 appliquées d’instinct).
  • La machine d’état ne change PAS : le mode Révision est un start() avec un tirage différent — la conception de la P6 encaisse la v2 sans broncher (si ce n’est pas le cas, c’est un signal d’architecture à corriger d’abord).
  • L’UI : un bouton « 🔁 Réviser (12 dues) » sur l’accueil, le badge de boîte sur l’explication (« cette question monte en boîte 4 ! »), et l’écran stats enrichi (répartition des boîtes par thème — la « santé » de votre mémoire).

Les jalons

  1. lib/leitner.ts + la suite de tests complète (les 5 boîtes, les échéances, le tirage).
  2. La migration v2 avec backfill — testée sur une COPIE de votre vraie base (adb pull !).
  3. L’enregistrement : chaque answer met à jour review_state (dans la même transaction).
  4. Le mode Révision (tirage dues-d’abord) + le compteur sur l’accueil.
  5. Les stats de boîtes + le badge de progression sur l’explication.
  6. La release : bump 2.0.0, build, OTA de baseline, tag — le rituel complet du ch. 12.6, en conditions réelles.

Critères de réussite

  • La suite leitner passe — y compris « due à minuit moins une » (l’horloge injectée)
  • La migration backfill sur votre vraie base : l’état initial est PLAUSIBLE (vos questions ratées sont bien en boîtes basses)
  • Une session de révision de 10 questions contient d’abord TOUTES les dues
  • Rater une question de boîte 5 la renvoie en boîte 1 (et ça se VOIT dans l’UI)
  • Le mode Quiz classique n’a pas bougé d’un pixel (la v2 est additive)
  • Drill 2.0.0 tourne sur votre téléphone, l’historique v1 intact — et vous révisez pour de vrai

Pièges connus

  • Le backfill sur la VRAIE base se teste sur une copie d’abord : adb pull du fichier drill.db (via run-as ou le backup — ou plus simple : testez sur l’émulateur seedé). Une migration ratée sur ses propres données de production est la leçon qu’on ne veut apprendre qu’une fois — en TP.
  • Les questions SUPPRIMÉES du repo (le contrat « jamais réutiliser un id », ch. 7.3) : leur review_state orphelin est inoffensif — mais le tirage doit ignorer les states sans question correspondante (le LEFT JOIN mental).
  • N’inventez pas SM-2/Anki d’entrée (ease factors, intervalles flottants) : Leitner d’abord, l’upgrade ensuite si VOS données montrent des limites. Commencer simple est une compétence.

🏁 Et après ? Vous avez une app de révision alimentée par un repo de questions que l’IA peut remplir à volonté (le README-contrat du ch. 7.3), un pipeline de release complet, et cinq apps de productivité à votre main. La suite logique : les milliers de questions dans drill-questions (les sessions de génération), et — qui sait — la P13 pour de vrai le jour où quelqu’un vous demande « elle est où, ton app ? ». Le cours s’arrête ici ; la pratique, elle, commence.