feat(learning): add persistent achievement records
New achievements table: stage_completed/curriculum_completed/assessment_completed/ capstone_completed, idempotent (WHERE NOT EXISTS guard, not a unique-index dance — simple and correct at this write volume). Not a certificate — a durable internal record Phase 4/5 can render one from later. recordAssessmentAchievement only fires on an actual pass, defensively, even though today's only completion_rule already guarantees that.
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
-- Persistent completion records — stage/curriculum/assessment/capstone. Not a certificate
|
||||
-- (Phase 4/5 territory, see docs/PHASE3B_LEARNING_AND_ASSESSMENT.md): just the durable fact
|
||||
-- that something was achieved, with enough context to render a certificate from later without
|
||||
-- re-deriving it from raw attempt history.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS achievements (
|
||||
achievement_id BIGSERIAL PRIMARY KEY,
|
||||
student_id TEXT NOT NULL REFERENCES students(student_id),
|
||||
achievement_type TEXT NOT NULL CHECK (achievement_type IN
|
||||
('stage_completed', 'curriculum_completed', 'assessment_completed', 'capstone_completed')),
|
||||
curriculum_path_id TEXT,
|
||||
curriculum_version INTEGER,
|
||||
stage_id TEXT,
|
||||
assessment_session_id UUID REFERENCES assessment_sessions(assessment_session_id),
|
||||
achieved_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
metadata JSONB
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_achievements_student ON achievements(student_id, achievement_type);
|
||||
Reference in New Issue
Block a user