My App
LoopKitBackend

Review Session

Build study queues and grade cards with ReviewSessionService

ReviewSessionService

The core service for study sessions. Manages queue building, card grading, and undo functionality.

Methods

buildQueue

Builds a study queue for a deck, respecting daily limits and card ordering.

async buildQueue(deckId: string, options?: SessionOptions): Promise<SessionQueue>

Parameters:

ParameterTypeDescription
deckIdstringThe deck to study
optionsSessionOptionsOptional overrides for limits
interface SessionOptions {
    tags?: string[];           // Filter cards by tags
    newCardsLimit?: number;    // Override newCardsPerDay
    reviewCardsLimit?: number; // Override maxReviewsPerDay
}

Returns:

interface SessionQueue {
    cards: CardBase[];  // Ordered: learningreviewnew
    counts: {
        new: number;
        learning: number;
        review: number;
    };
}

Queue ordering:

  1. Learning/relearning cards (always included, regardless of limits)
  2. Review cards due today (respects maxReviewsPerDay)
  3. New cards (respects newCardsPerDay)

Example:

const queue = await session.buildQueue('deck-123');
console.log(`${queue.counts.new} new, ${queue.counts.review} review cards`);

gradeCard

Grade a card and advance its SRS state.

async gradeCard(
    cardId: string,
    grade: Grade,
    timeTakenMs: number,
): Promise<GradeResult>

Parameters:

ParameterTypeDescription
cardIdstringThe card to grade
gradeGrade'again' | 'hard' | 'good' | 'easy'
timeTakenMsnumberTime spent reviewing (for statistics)

Returns:

interface GradeResult {
    card: CardBase;                        // Updated card state
    reviewLog: ReviewLog;                  // Immutable review record
    nextIntervals: Record<Grade, string>;  // Preview of next intervals (e.g., "1m", "10d")
}

Example:

const result = await session.gradeCard('card-456', 'good', 5200);
console.log(result.nextIntervals);
// { again: '1m', hard: '6m', good: '10m', easy: '4d' }

undoLastReview

Undo a review by restoring the card to its previous state and deleting the review log.

async undoLastReview(reviewLogId: string): Promise<void>

Parameters:

ParameterTypeDescription
reviewLogIdstringThe review log ID to undo

Throws: UndoNotAvailableError if the review log doesn't exist.

getSessionSummary

Calculate summary statistics from a list of review logs.

getSessionSummary(logs: ReviewLog[]): SessionSummary

Returns:

interface SessionSummary {
    totalReviewed: number;
    correctCount: number;         // grade !== 'again'
    incorrectCount: number;       // grade === 'again'
    averageTimeMsPerCard: number;
    gradeDistribution: Record<Grade, number>;
    newCardsStudied: number;
    reviewsCompleted: number;
}

On this page