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.
29 lines
1.3 KiB
SQL
29 lines
1.3 KiB
SQL
-- cohorts + cohort_enrollments — replaces the old students.cohort TEXT column with a real
|
|
-- many-to-many-capable model (a student can move between cohorts over time; the old model
|
|
-- couldn't represent that at all).
|
|
|
|
CREATE TABLE IF NOT EXISTS cohorts (
|
|
cohort_id TEXT PRIMARY KEY, -- slug, e.g. 'root-fall-2026'
|
|
name TEXT NOT NULL,
|
|
code TEXT UNIQUE, -- optional short join-style code, distinct from cohort_id
|
|
tier TEXT, -- e.g. 'root' — free text, not an enum yet (YAGNI)
|
|
start_date DATE,
|
|
end_date DATE,
|
|
status TEXT NOT NULL DEFAULT 'active', -- 'active' | 'archived'
|
|
seat_target INTEGER,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_cohorts_status ON cohorts(status);
|
|
|
|
CREATE TABLE IF NOT EXISTS cohort_enrollments (
|
|
cohort_id TEXT NOT NULL REFERENCES cohorts(cohort_id),
|
|
student_id TEXT NOT NULL REFERENCES students(student_id),
|
|
enrollment_status TEXT NOT NULL DEFAULT 'enrolled', -- 'enrolled' | 'removed'
|
|
enrolled_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
PRIMARY KEY (cohort_id, student_id)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_enrollments_student ON cohort_enrollments(student_id);
|