continue fixing

This commit is contained in:
2026-06-13 10:35:06 +08:00
parent 76c2f17229
commit b19c811048
8 changed files with 240 additions and 43 deletions

View File

@@ -9,6 +9,10 @@ import { Word, WordSet, WordRecord, VocabularyTestRecord, VocabularyTestAttempt
import mongoose from 'mongoose';
import csv from 'csv-parser';
import { config } from '../config';
import {
INVALIDATING_VOCABULARY_RISK_FLAGS,
analyzeVocabularyAttemptResultRisk
} from '../utils/vocabularyRisk';
const router = express.Router();
@@ -1196,21 +1200,6 @@ router.post('/test-record', authMiddleware, async (req, res) => {
}
}
const batchRiskFlags = isMultipleChoiceAttempt ? [] : analyzeBatchRisk(attemptAny.answerDurations || []);
attemptAny.riskFlags = Array.from(new Set([...(attemptAny.riskFlags || []), ...batchRiskFlags]));
const shouldInvalidateBatch = batchRiskFlags.length > 0 ||
['too_fast', 'too_slow', 'missing_input_value_trace', 'input_value_mismatch'].some(flag => (attemptAny.riskFlags || []).includes(flag));
const claimedAttempt = await VocabularyTestAttempt.findOneAndUpdate(
{ _id: attempt._id, user: userId, status: 'active' },
{ $set: { status: 'submitted', submittedAt: new Date(lastSubmittedAtMs), riskFlags: attemptAny.riskFlags } },
{ new: true }
);
if (!claimedAttempt) {
return res.status(409).json({ message: INVALID_CREDENTIAL_MESSAGE });
}
const submittedWordIds = submittedAnswers.map((item: any) => getObjectIdString(item.word));
const submittedWords = await Word.find({ _id: { $in: submittedWordIds } }).select('_id word');
const submittedWordMap = new Map<string, string>();
@@ -1229,14 +1218,36 @@ router.post('/test-record', authMiddleware, async (req, res) => {
};
});
const totalWords = evaluatedResults.length;
const originallyCorrectWords = evaluatedResults.filter(result => result.isCorrect).length;
const batchRiskFlags = [
...(isMultipleChoiceAttempt ? [] : analyzeBatchRisk(attemptAny.answerDurations || [])),
...analyzeVocabularyAttemptResultRisk({
testType: attemptAny.testType,
totalWords,
correctWords: originallyCorrectWords
})
];
attemptAny.riskFlags = Array.from(new Set([...(attemptAny.riskFlags || []), ...batchRiskFlags]));
const shouldInvalidateBatch = INVALIDATING_VOCABULARY_RISK_FLAGS.some(flag => (attemptAny.riskFlags || []).includes(flag));
const claimedAttempt = await VocabularyTestAttempt.findOneAndUpdate(
{ _id: attempt._id, user: userId, status: 'active' },
{ $set: { status: 'submitted', submittedAt: new Date(lastSubmittedAtMs), riskFlags: attemptAny.riskFlags } },
{ new: true }
);
if (!claimedAttempt) {
return res.status(409).json({ message: INVALID_CREDENTIAL_MESSAGE });
}
if (!shouldInvalidateBatch) {
for (const result of evaluatedResults) {
await updateWordRecordForAnswer(userId, result.wordId, attemptAny.testType, result.isCorrect);
}
}
const totalWords = evaluatedResults.length;
const correctWords = shouldInvalidateBatch ? 0 : evaluatedResults.filter(result => result.isCorrect).length;
const correctWords = shouldInvalidateBatch ? 0 : originallyCorrectWords;
const verifiedStats = {
totalWords,
correctWords,