New platform/api/ service owns students, cohorts, curriculum, progress, scenario attempts, and student/admin sessions. No k3s, no --privileged, no terminal runtime — starts instantly, unlike the old identity service which booted an unused k3s cluster just to serve roster/progress APIs. Provisioner calls (student and admin) are consolidated here too, in provisioner-client.js, so it's the only service that talks to the Provisioner directly.
35 lines
1.6 KiB
JavaScript
35 lines
1.6 KiB
JavaScript
// Postgres-backed progress store — same shape/semantics as the SQLite loadProgress/saveProgress
|
|
// it replaces in backend/server.js, now backed by the `progress` table (migrations/004).
|
|
|
|
async function loadProgress(pool, studentId) {
|
|
const { rows } = await pool.query('SELECT * FROM progress WHERE student_id = $1', [studentId]);
|
|
return Object.fromEntries(rows.map((r) => [r.scenario_id, {
|
|
status: r.status,
|
|
attempts: r.attempts,
|
|
last_validated: r.last_validated,
|
|
completed_at: r.completed_at,
|
|
started_at: r.started_at,
|
|
notes: r.notes,
|
|
time_spent_seconds: r.time_spent_seconds || 0,
|
|
}]));
|
|
}
|
|
|
|
async function saveOneProgress(pool, studentId, scenarioId, p) {
|
|
await pool.query(
|
|
`INSERT INTO progress (student_id, scenario_id, status, attempts, last_validated, completed_at, started_at, notes, time_spent_seconds)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
|
|
ON CONFLICT (student_id, scenario_id) DO UPDATE SET
|
|
status = excluded.status, attempts = excluded.attempts, last_validated = excluded.last_validated,
|
|
completed_at = excluded.completed_at, started_at = excluded.started_at, notes = excluded.notes,
|
|
time_spent_seconds = excluded.time_spent_seconds`,
|
|
[studentId, scenarioId, p.status || null, p.attempts || 0, p.last_validated || null,
|
|
p.completed_at || null, p.started_at || null, p.notes || null, p.time_spent_seconds || 0]
|
|
);
|
|
}
|
|
|
|
async function touchStudent(pool, studentId) {
|
|
await pool.query(`UPDATE students SET last_active_at = now() WHERE student_id = $1`, [studentId]).catch(() => {});
|
|
}
|
|
|
|
module.exports = { loadProgress, saveOneProgress, touchStudent };
|