Implement batch transmission of unanswered questions and automated session cleanup
This commit is contained in:
+29
-1
@@ -739,7 +739,19 @@ function WettkampfSelectPage({ navigate }) {
|
||||
setProgressDialog(null);
|
||||
};
|
||||
|
||||
const startFresh = () => {
|
||||
const startFresh = async () => {
|
||||
setChecking(true);
|
||||
try {
|
||||
await api.post('/api/results/abandon', {
|
||||
sessionId: progressDialog.sessionId,
|
||||
setId: selectedSet.id,
|
||||
nutzername: name.trim(),
|
||||
expectedCount: selectedSet.wettkampfCount
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('Abandon error:', e);
|
||||
}
|
||||
setChecking(false);
|
||||
navigate('wettkampf-quiz', {
|
||||
setId: selectedSet.id, setName: selectedSet.name,
|
||||
name: name.trim(), questionCount: selectedSet.wettkampfCount,
|
||||
@@ -1078,6 +1090,22 @@ function WettkampfQuizPage({ params, navigate }) {
|
||||
if (rowsToUpdate.length > 0) {
|
||||
await api.put('/api/results/finalize', { results: rowsToUpdate });
|
||||
}
|
||||
|
||||
const rowsToCreate = finalResults.filter((r) => !r.rowId);
|
||||
if (rowsToCreate.length > 0) {
|
||||
const batched = rowsToCreate.map((r) => ({
|
||||
Nutzername: params.name,
|
||||
Frage_ID: r.questionId,
|
||||
Fragenset: params.setName,
|
||||
Antwort: '',
|
||||
Richtig: false,
|
||||
Punkte: 0,
|
||||
Session_ID: sessionId.current,
|
||||
Modus: 'Wettkampf',
|
||||
Zeitstempel: new Date().toISOString(),
|
||||
}));
|
||||
await api.post('/api/results', { answers: batched });
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Finalize error:', e);
|
||||
}
|
||||
|
||||
+43
-1
@@ -280,7 +280,8 @@ app.get('/api/wettkampf-progress/:name/:setId', async (req, res) => {
|
||||
const richtig = a['Richtig'];
|
||||
return punkte === 0 && (richtig === false || richtig === 'false' || !richtig);
|
||||
});
|
||||
if (allUnscored && answers.length > 0) {
|
||||
const isFullLength = set.wettkampfCount && answers.length >= set.wettkampfCount;
|
||||
if (allUnscored && answers.length > 0 && !isFullLength) {
|
||||
const latest = answers.reduce((max, a) => {
|
||||
const ts = a['Zeitstempel'] || '';
|
||||
return ts > max ? ts : max;
|
||||
@@ -324,6 +325,47 @@ app.post('/api/results', async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/api/results/abandon', async (req, res) => {
|
||||
try {
|
||||
const config = readConfig();
|
||||
if (!config.answersTableId) return res.status(400).json({ error: 'Nicht konfiguriert' });
|
||||
|
||||
const { sessionId, setId, nutzername, expectedCount } = req.body;
|
||||
if (!sessionId || !setId || !nutzername) return res.status(400).json({ error: 'Fehlende Parameter' });
|
||||
|
||||
const set = config.sets.find((s) => s.id === setId);
|
||||
if (!set) return res.status(404).json({ error: 'Set nicht gefunden' });
|
||||
|
||||
const allAnswers = await listRows(config.answersTableId, { Session_ID: sessionId, Nutzername: nutzername });
|
||||
const answeredIds = new Set(allAnswers.map(a => Number(a['Frage_ID'])));
|
||||
const needed = expectedCount - allAnswers.length;
|
||||
|
||||
if (needed > 0) {
|
||||
const questions = await listRows(set.tableId);
|
||||
const unpicked = questions.filter(q => !answeredIds.has(q.id));
|
||||
const shuffled = unpicked.sort(() => Math.random() - 0.5);
|
||||
const selected = shuffled.slice(0, needed);
|
||||
|
||||
const batched = selected.map(q => ({
|
||||
Nutzername: nutzername,
|
||||
Frage_ID: q.id,
|
||||
Fragenset: set.name,
|
||||
Antwort: '',
|
||||
Richtig: false,
|
||||
Punkte: 0,
|
||||
Session_ID: sessionId,
|
||||
Modus: 'Wettkampf',
|
||||
Zeitstempel: new Date().toISOString(),
|
||||
}));
|
||||
await batchCreateRows(config.answersTableId, batched);
|
||||
}
|
||||
res.json({ success: true });
|
||||
} catch(e) {
|
||||
console.error('[api] Abandon error:', e.message);
|
||||
res.status(500).json({ error: e.message });
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/api/results/:name', async (req, res) => {
|
||||
try {
|
||||
const config = readConfig();
|
||||
|
||||
Reference in New Issue
Block a user