Files
step3/api/QuestionsApi/Services/Flashcards/FlashcardSettingsStore.cs
T
hz 48a8c8361d Add flashcards feature with spaced repetition scheduling
Adds a full flashcards system: FSRS-based scheduling, cloze/basic
card types, CSV import/export, media storage, and study UI, wired
into navigation and the dashboard alongside existing question flows.
2026-07-21 15:08:52 -05:00

37 lines
1.6 KiB
C#

using MongoDB.Driver;
using QuestionsApi.Models;
namespace QuestionsApi.Services.Flashcards;
public sealed class FlashcardSettingsStore
{
private readonly IMongoCollection<FlashcardSettings> _settings;
public FlashcardSettingsStore(MongoDatabaseProvider mongo)
{
_settings = mongo.Database.GetCollection<FlashcardSettings>("FlashcardSettings");
_settings.Indexes.CreateOne(new CreateIndexModel<FlashcardSettings>(
Builders<FlashcardSettings>.IndexKeys.Ascending(v => v.UserId),
new CreateIndexOptions { Unique = true, Name = "flashcard_settings_unique_user" }));
}
public async Task<FlashcardSettings> GetAsync(string userId) =>
await _settings.Find(v => v.UserId == userId).FirstOrDefaultAsync()
?? new FlashcardSettings { UserId = userId };
public async Task<FlashcardSettings> UpdateAsync(string userId, UpdateFlashcardSettingsRequest request)
{
var now = DateTime.UtcNow;
return await _settings.FindOneAndUpdateAsync(
v => v.UserId == userId,
Builders<FlashcardSettings>.Update
.Set(v => v.NewCardsPerDay, Math.Clamp(request.NewCardsPerDay, 0, 2000))
.Set(v => v.ReviewsPerDay, Math.Clamp(request.ReviewsPerDay, 0, 5000))
.Set(v => v.DesiredRetention, FsrsFlashcardScheduler.DesiredRetention)
.Set(v => v.UpdatedUtc, now)
.Inc(v => v.Revision, 1)
.SetOnInsert(v => v.UserId, userId),
new FindOneAndUpdateOptions<FlashcardSettings> { IsUpsert = true, ReturnDocument = ReturnDocument.After });
}
}