feat(platform-api): split lightweight platform service from Lab image
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.
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
// 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 };
|
||||
Reference in New Issue
Block a user