feat(flashcards): révision SM-2, génération IA et page /revision
Livre US-FLASHCARDS avec decks, session de révision, stats et migration Prisma. Finalise le Web Clipper (i18n 15 langues) et corrige les erreurs ESLint bloquant la CI. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
39
memento-note/lib/flashcards/sm2.ts
Normal file
39
memento-note/lib/flashcards/sm2.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
export type Sm2Grade = 1 | 2 | 3 | 4
|
||||
|
||||
export interface Sm2State {
|
||||
easinessFactor: number
|
||||
interval: number
|
||||
}
|
||||
|
||||
export interface Sm2UpdateResult extends Sm2State {
|
||||
nextReviewAt: Date
|
||||
}
|
||||
|
||||
/** SM-2 update per US-FLASHCARDS spec (grades 1–4). */
|
||||
export function computeSm2Update(
|
||||
grade: number,
|
||||
previous: Sm2State,
|
||||
): Sm2UpdateResult {
|
||||
const g = Math.min(4, Math.max(1, Math.round(grade))) as Sm2Grade
|
||||
const ef = previous.easinessFactor
|
||||
const newEF = Math.max(
|
||||
1.3,
|
||||
ef + 0.1 - (5 - g) * (0.08 + (5 - g) * 0.02),
|
||||
)
|
||||
|
||||
const nextInterval =
|
||||
g <= 2 ? 1 : Math.max(1, Math.round(previous.interval * newEF))
|
||||
|
||||
const nextReviewAt = new Date()
|
||||
nextReviewAt.setDate(nextReviewAt.getDate() + nextInterval)
|
||||
|
||||
return {
|
||||
easinessFactor: newEF,
|
||||
interval: nextInterval,
|
||||
nextReviewAt,
|
||||
}
|
||||
}
|
||||
|
||||
export function isCardMastered(interval: number): boolean {
|
||||
return interval >= 21
|
||||
}
|
||||
Reference in New Issue
Block a user