-- Teacher lesson submissions and immutable video candidates. -- Requires 20260909_curriculum_publication_identity.sql. CREATE TABLE IF NOT EXISTS `teacher_submissions` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `uuid` CHAR(36) NOT NULL, `teacher_id` BIGINT UNSIGNED NOT NULL, `curriculum_lesson_id` BIGINT UNSIGNED NOT NULL, `status` ENUM('draft','uploading','review','published','withdrawn','archived') NOT NULL DEFAULT 'draft', `current_published_video_version_id` BIGINT UNSIGNED NULL, `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uq_teacher_submission_uuid` (`uuid`), UNIQUE KEY `uq_teacher_curriculum_submission` (`teacher_id`,`curriculum_lesson_id`), KEY `idx_submission_lesson_status` (`curriculum_lesson_id`,`status`), CONSTRAINT `fk_submission_teacher` FOREIGN KEY (`teacher_id`) REFERENCES `teachers` (`id`) ON DELETE RESTRICT, CONSTRAINT `fk_submission_curriculum_lesson` FOREIGN KEY (`curriculum_lesson_id`) REFERENCES `curriculum_lessons` (`id`) ON DELETE RESTRICT ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE IF NOT EXISTS `video_versions` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `uuid` CHAR(36) NOT NULL, `teacher_submission_id` BIGINT UNSIGNED NOT NULL, `version_number` INT UNSIGNED NOT NULL, `status` ENUM('draft','uploading','review','rejected','published','superseded','withdrawn') NOT NULL DEFAULT 'draft', `replaces_video_version_id` BIGINT UNSIGNED NULL, `source_lesson_id` BIGINT UNSIGNED NULL, `upload_audit_id` BIGINT UNSIGNED NULL, `content_sha256` CHAR(64) NULL, `review_report_json` JSON NULL, `published_at` TIMESTAMP NULL DEFAULT NULL, `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uq_video_version_uuid` (`uuid`), UNIQUE KEY `uq_submission_version` (`teacher_submission_id`,`version_number`), KEY `idx_video_version_status` (`teacher_submission_id`,`status`), CONSTRAINT `fk_video_version_submission` FOREIGN KEY (`teacher_submission_id`) REFERENCES `teacher_submissions` (`id`) ON DELETE RESTRICT, CONSTRAINT `fk_video_version_replacement` FOREIGN KEY (`replaces_video_version_id`) REFERENCES `video_versions` (`id`) ON DELETE RESTRICT ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; ALTER TABLE `teacher_submissions` ADD CONSTRAINT `fk_submission_current_version` FOREIGN KEY (`current_published_video_version_id`) REFERENCES `video_versions` (`id`) ON DELETE RESTRICT; CREATE TABLE IF NOT EXISTS `submission_idempotency_keys` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `teacher_id` BIGINT UNSIGNED NOT NULL, `operation` VARCHAR(64) NOT NULL, `idempotency_key` VARCHAR(128) NOT NULL, `request_sha256` CHAR(64) NOT NULL, `response_json` JSON NULL, `http_status` SMALLINT UNSIGNED NULL, `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), UNIQUE KEY `uq_submission_idempotency` (`teacher_id`,`operation`,`idempotency_key`), CONSTRAINT `fk_submission_idempotency_teacher` FOREIGN KEY (`teacher_id`) REFERENCES `teachers` (`id`) ON DELETE RESTRICT ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- Rollback: preserve submissions and versions. Withdraw affected publications; -- do not drop records that may be referenced by student progress or review data.