Harden published curriculum and student flows

This commit is contained in:
Hamza-Ayed
2026-09-30 08:22:17 +03:00
parent e8163fe265
commit ce7b0fcf14
53 changed files with 4723 additions and 3317 deletions
@@ -0,0 +1,33 @@
-- Apply after database_schema.sql. Rollback: disable the new endpoints, preserve
-- attempt rows for audit, then remove the column/table only after export.
ALTER TABLE student_error_notebook
ADD COLUMN retention_due_at TIMESTAMP NULL DEFAULT NULL AFTER mastered_at;
-- Existing question rows remain draft. A reviewer must approve each question
-- against the named lesson and record its source before it may prove remediation.
ALTER TABLE questions
ADD COLUMN remediation_review_status ENUM('draft','approved','rejected') NOT NULL DEFAULT 'draft',
ADD COLUMN remediation_reviewed_by BIGINT UNSIGNED NULL,
ADD COLUMN remediation_reviewed_at TIMESTAMP NULL DEFAULT NULL,
ADD COLUMN remediation_source_reference VARCHAR(700) NULL;
CREATE TABLE IF NOT EXISTS error_notebook_quiz_attempts (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
uuid CHAR(36) NOT NULL,
error_id BIGINT UNSIGNED NOT NULL,
student_id BIGINT UNSIGNED NOT NULL,
phase ENUM('initial','retention') NOT NULL,
question_ids_json JSON NOT NULL,
answer_key_json JSON NOT NULL,
status ENUM('open','passed','failed') NOT NULL DEFAULT 'open',
answers_sha256 CHAR(64) NULL,
correct_count TINYINT UNSIGNED NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
expires_at TIMESTAMP NOT NULL,
submitted_at TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE KEY uq_error_quiz_uuid (uuid),
KEY idx_error_quiz_student (student_id,error_id,status),
CONSTRAINT fk_error_quiz_error FOREIGN KEY (error_id) REFERENCES student_error_notebook(id) ON DELETE RESTRICT,
CONSTRAINT fk_error_quiz_student FOREIGN KEY (student_id) REFERENCES students(id) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
@@ -0,0 +1,7 @@
-- Apply after 20260909_financial_ledger.sql, before deploying releaseHold changes.
-- Existing released rows stay NULL: their original reason cannot be reconstructed.
ALTER TABLE teacher_withdrawal_holds
ADD COLUMN release_reason VARCHAR(500) NULL AFTER released_at;
-- Rollback: revert the application writer first. Keep this nullable audit column
-- and any recorded reasons; dropping it would erase financial history.
@@ -0,0 +1,17 @@
-- Apply after 20260909_watch_sessions.sql.
-- Preflight: this intentionally fails if historical data has more than one
-- active session per student. Reconcile those rows to ended/invalidated first.
ALTER TABLE watch_sessions
ADD COLUMN active_student_id BIGINT UNSIGNED
GENERATED ALWAYS AS (CASE WHEN status = 'active' THEN student_id ELSE NULL END) STORED,
ADD UNIQUE KEY uq_watch_one_active_per_student (active_student_id);
-- One decision per event, including repeated positions that are legitimately
-- excluded. Position pairs alone are not an event identity.
ALTER TABLE eligible_watch_intervals
DROP INDEX uq_eligible_interval,
ADD COLUMN event_sequence_no INT UNSIGNED NULL AFTER watch_session_id,
ADD UNIQUE KEY uq_watch_interval_event (watch_session_id, event_sequence_no, policy_version);
-- Rollback: stop writers that rely on the invariant first. Dropping the key
-- weakens protection and is not a routine production rollback.