This commit is contained in:
Rene Kievits
2025-12-18 01:30:52 +01:00
commit 6438660b03
78 changed files with 14230 additions and 0 deletions

View File

@@ -0,0 +1,85 @@
import { ReviewLog } from '../models/ReviewLog.js';
import { StudyItem } from '../models/StudyItem.js';
import { getDaysDiff, getSRSDate } from '../utils/dateUtils.js';
export const processReview = async (user, subjectId, success) => {
if (!user.stats) user.stats = { totalReviews: 0, correctReviews: 0, currentStreak: 0, maxStreak: 0 };
user.stats.totalReviews += 1;
if (success) user.stats.correctReviews += 1;
const todayStr = new Date().toISOString().split('T')[0];
const lastStudyStr = user.stats.lastStudyDate;
if (lastStudyStr !== todayStr) {
if (!lastStudyStr) {
user.stats.currentStreak = 1;
} else {
const diff = getDaysDiff(lastStudyStr, todayStr);
if (diff === 1) {
user.stats.currentStreak += 1;
} else if (diff > 1) {
const lastFreeze = user.stats.lastFreezeDate ? new Date(user.stats.lastFreezeDate) : null;
let daysSinceFreeze = 999;
if (lastFreeze) daysSinceFreeze = getDaysDiff(lastFreeze.toISOString().split('T')[0], todayStr);
const canUseShield = daysSinceFreeze >= 7;
if (canUseShield && diff === 2) {
console.log(`User ${user._id} saved by Zen Shield!`);
user.stats.lastFreezeDate = new Date();
user.stats.currentStreak += 1;
} else {
user.stats.currentStreak = 1;
}
}
}
user.stats.lastStudyDate = todayStr;
if (user.stats.currentStreak > user.stats.maxStreak) user.stats.maxStreak = user.stats.currentStreak;
}
await user.save();
await ReviewLog.findOneAndUpdate(
{ userId: user._id, date: todayStr },
{ $inc: { count: 1 } },
{ upsert: true, new: true }
);
const item = await StudyItem.findOne({ userId: user._id, wkSubjectId: subjectId });
if (!item) throw new Error('Item not found');
if (!item.stats) item.stats = { correct: 0, total: 0 };
item.stats.total += 1;
if (success) item.stats.correct += 1;
if (success) {
const nextLevel = Math.min(item.srsLevel + 1, 10);
item.srsLevel = nextLevel;
item.nextReview = getSRSDate(nextLevel);
} else {
item.srsLevel = Math.max(1, item.srsLevel - 1);
item.nextReview = Date.now();
}
await item.save();
return { nextReview: item.nextReview, srsLevel: item.srsLevel };
};
export const getQueue = async (user, limit = 100, sortMode) => {
const query = {
userId: user._id,
srsLevel: { $lt: 10, $gt: 0 },
nextReview: { $lte: new Date() }
};
let dueItems;
if (sortMode === 'priority') {
dueItems = await StudyItem.find(query).sort({ srsLevel: 1, level: 1 }).limit(limit);
} else {
dueItems = await StudyItem.find(query).limit(limit);
for (let i = dueItems.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[dueItems[i], dueItems[j]] = [dueItems[j], dueItems[i]];
}
}
return dueItems;
};