feat(vocab): update intensive review UI and logic for better user guidance

This commit is contained in:
Torsten Schulz (local)
2026-08-26 10:16:41 +02:00
parent bac915c328
commit 68470bf576
7 changed files with 42 additions and 43 deletions

View File

@@ -2022,15 +2022,12 @@ export default class VocabService {
const requestedLimit = this._clampInteger(query?.limit, { min: 1, max: DAILY_SRS_LIMIT, fallback: DAILY_SRS_LIMIT });
const limit = Math.min(DAILY_SRS_LIMIT, requestedLimit);
const now = new Date();
const dueWhere = {
userId: user.id,
courseId: Number(course.id),
nextDueAt: {
[Op.lte]: now
}
};
const dueRows = await VocabSrsItem.findAll({
where: dueWhere,
// SRS is a daily review: a term scheduled for any time today belongs to
// today's batch. Older rows remain due as well. Comparing calendar dates
// avoids an accidental time-of-day gate for a daily task.
const todayKey = this._getSrsScheduleDateKey(now);
const scheduledRows = await VocabSrsItem.findAll({
where: { userId: user.id, courseId: Number(course.id) },
order: [
['nextDueAt', 'ASC'],
['wrongCount', 'DESC'],
@@ -2043,20 +2040,17 @@ export default class VocabService {
.map((entry) => String(entry?.itemKey || '').trim())
.filter(Boolean)
);
const validDueRows = dueRows.filter((item) =>
const validDueRows = scheduledRows.filter((item) =>
this._isTrainableSrsPair(item)
&& (!validKeys.size || validKeys.has(String(item.itemKey || '').trim()))
&& this._getSrsScheduleDateKey(item.nextDueAt) <= todayKey
);
const scheduledRows = await VocabSrsItem.findAll({
where: { userId: user.id, courseId: Number(course.id) },
order: [['nextDueAt', 'ASC']]
});
const upcomingByDate = new Map();
scheduledRows
.filter((item) => (
this._isTrainableSrsPair(item)
&& (!validKeys.size || validKeys.has(String(item.itemKey || '').trim()))
&& new Date(item.nextDueAt).getTime() > now.getTime()
&& this._getSrsScheduleDateKey(item.nextDueAt) > todayKey
))
.forEach((item) => {
const date = this._getSrsScheduleDateKey(item.nextDueAt);