Spaced Repetition Feature: Phase 3 Advanced Features & Analytics Plan
Prerequisites:
1. Objective
This document provides a detailed, actionable plan for implementing the backend components for Phase 3: Advanced Features & Analytics. The goal of this phase is to enhance the core SRS engine by giving users more control over their learning process and providing them with valuable insights into their progress.
All changes will be implemented within the src/features/educationpub/ directory.
2. Task Breakdown & Implementation Details
2.1. Collection-Based Reviews
This feature will allow users to study specific sets of flashcards, such as those belonging to a particular FlashcardModel (i.e., a "deck").
a. API Endpoint Modification
The existing GET /api/edu/srs/due endpoint will be updated to accept an optional query parameter to filter by collection.
- Endpoint:
GET /api/edu/srs/due - Query Parameter:
?collectionId=<uuid>(optional) - Logic:
- If
collectionIdis provided, the service will return only due cards that belong to the specifiedFlashcardModel. - If
collectionIdis omitted, the service will return all due cards for the actor, maintaining the original MVP behavior.
- If
b. Service Layer Update
The SpacedRepetitionService will be updated to handle the new filtering logic.
- File to Update:
src/features/educationpub/services/spaced-repetition.service.ts - Method to Update:
getDueFlashcards - Implementation:
// In SpacedRepetitionService
async getDueFlashcards(actorId: string, collectionId?: string): Promise<Flashcard[]> {
const queryBuilder = this.scheduleRepository.createQueryBuilder('schedule')
.innerJoinAndSelect('schedule.flashcard', 'flashcard')
.where('schedule.actor.id = :actorId', { actorId })
.andWhere('schedule.due <= :now', { now: new Date() });
if (collectionId) {
queryBuilder.andWhere('flashcard.flashcardModel.id = :collectionId', { collectionId });
}
const schedules = await queryBuilder.getMany();
return schedules.map(s => s.flashcard);
}
2.2. User-Configurable FSRS Parameters
This feature will allow users to customize the FSRS algorithm to better suit their personal learning style.
a. Create ActorFsrsParameters Entity
A new entity will be created to store custom FSRS parameters on a per-actor basis.
- File Location:
src/features/educationpub/entities/actor-fsrs-parameters.entity.ts - Implementation:
import { Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn } from 'typeorm';
import { Actor } from '../../activitypub/entities/actor.entity';
@Entity()
export class ActorFsrsParameters {
@PrimaryGeneratedColumn('uuid')
id: string;
@OneToOne(() => Actor)
@JoinColumn()
actor: Actor;
@Column('float', { default: 0.9 })
request_retention: number;
@Column({ default: 36500 })
maximum_interval: number;
// Add other FSRS parameters as needed
}
b. Update FSRSLogic and SpacedRepetitionService
The FSRSLogic service will be updated to accept an optional parameters object. The SpacedRepetitionService will be responsible for fetching these parameters for an actor and passing them to the logic layer.
c. Create New API Endpoints
New endpoints will be created for managing these settings.
- Controller:
SpacedRepetitionController - Endpoints:
GET /api/edu/srs/parameters: Fetches the current actor's FSRS parameters.PUT /api/edu/srs/parameters: Updates the current actor's FSRS parameters.
- DTO to Create:
src/features/educationpub/dto/update-fsrs-params.dto.ts
2.3. Learning Analytics Dashboard
This feature provides the backend endpoints needed to power a user-facing analytics dashboard.
a. New Service Methods
New methods will be added to the SpacedRepetitionService to compute analytics data.
- File to Update:
src/features/educationpub/services/spaced-repetition.service.ts - New Methods:
getWorkloadForecast(actorId: string): Queries theSpacedRepetitionScheduletable to count the number of cards due on each of the next 30 days.getRetentionRate(actorId: string): Analyzes theReviewLogto calculate the percentage of "Good" and "Easy" ratings over different time periods.getAnalyticsSummary(actorId: string): A composite method that calls the other analytics methods to return all data in a single payload.
b. New API Endpoint
A new endpoint will expose the analytics data.
- Controller: A new
AnalyticsControllercould be created or it could be added to theSpacedRepetitionController. - Endpoint:
GET /api/edu/srs/analytics/summary - Response Shape:
{
"retention": {
"past_7_days": 0.92,
"past_30_days": 0.88
},
"forecast": [
{ "date": "2025-07-31", "count": 15 },
{ "date": "2025-08-01", "count": 22 }
],
"totalCardsInLearning": 250
}
2.4. Module Integration
- File to Update:
src/features/educationpub/educationpub.module.ts - Changes:
- Add
ActorFsrsParametersto theTypeOrmModule.forFeature([...])array.
- Add
3. Testing Strategy
- Unit Tests:
- Update
spaced-repetition.service.spec.tsto test the new collection filtering logic and the new analytics calculation methods. - Create tests for the new
PUT /api/edu/srs/parameterslogic, ensuring custom parameters are correctly passed to theFSRSLogicservice.
- Update
- End-to-End (E2E) Tests:
- Update the
GET /duetest to verify that thecollectionIdquery parameter correctly filters the results. - Add new E2E tests for the
GET /parameters,PUT /parameters, andGET /analytics/summaryendpoints to ensure they are secure and return data in the expected format.
- Update the