From 365c36d97b78555fb8df787929244d06b9b1562d Mon Sep 17 00:00:00 2001 From: SpecialX <47072643+wangxiner55@users.noreply.github.com> Date: Fri, 3 Jul 2026 10:23:24 +0800 Subject: [PATCH] feat(db): add migrations for RBAC, diagnostic, messaging, attendance, leave, invitation codes - 0011: RBAC role flags and seed data - 0012: diagnostic grade_id - 0013: message recall - 0014: message templates - 0015: group messages and message reports/blocks - 0016: invitation codes - 0017: draft device sync - 0018: attendance status reason - 0019: attendance warning thresholds - 0020: leave requests - 0021: attendance period --- drizzle/0011_rbac_role_flags_and_seed.sql | 85 +++++++++++++++++++ drizzle/0012_diagnostic_grade_id.sql | 4 + drizzle/0013_message_recall.sql | 2 + drizzle/0014_message_templates.sql | 13 +++ drizzle/0015_group_messages.sql | 3 + drizzle/0016_invitation_codes.sql | 19 +++++ drizzle/0016_message_reports_and_blocks.sql | 35 ++++++++ drizzle/0017_draft_device_sync.sql | 8 ++ drizzle/0018_attendance_status_reason.sql | 11 +++ .../0019_attendance_warning_thresholds.sql | 6 ++ drizzle/0020_leave_requests.sql | 53 ++++++++++++ drizzle/0021_attendance_period.sql | 20 +++++ drizzle/meta/_journal.json | 49 +++++++++++ 13 files changed, 308 insertions(+) create mode 100644 drizzle/0011_rbac_role_flags_and_seed.sql create mode 100644 drizzle/0012_diagnostic_grade_id.sql create mode 100644 drizzle/0013_message_recall.sql create mode 100644 drizzle/0014_message_templates.sql create mode 100644 drizzle/0015_group_messages.sql create mode 100644 drizzle/0016_invitation_codes.sql create mode 100644 drizzle/0016_message_reports_and_blocks.sql create mode 100644 drizzle/0017_draft_device_sync.sql create mode 100644 drizzle/0018_attendance_status_reason.sql create mode 100644 drizzle/0019_attendance_warning_thresholds.sql create mode 100644 drizzle/0020_leave_requests.sql create mode 100644 drizzle/0021_attendance_period.sql diff --git a/drizzle/0011_rbac_role_flags_and_seed.sql b/drizzle/0011_rbac_role_flags_and_seed.sql new file mode 100644 index 0000000..5288772 --- /dev/null +++ b/drizzle/0011_rbac_role_flags_and_seed.sql @@ -0,0 +1,85 @@ +-- 0011_rbac_role_flags_and_seed.sql +-- RBAC: add is_system/is_enabled columns to roles table and seed role_permissions. + +-- 1. Add is_system and is_enabled columns to roles table. +ALTER TABLE `roles` + ADD COLUMN `is_system` boolean DEFAULT false NOT NULL, + ADD COLUMN `is_enabled` boolean DEFAULT true NOT NULL; + +-- 2. Mark the 6 builtin roles as system roles. +UPDATE `roles` SET `is_system` = true + WHERE `name` IN ('admin', 'teacher', 'student', 'parent', 'grade_head', 'teaching_head'); + +-- 3. Seed role_permissions for builtin roles. +-- Uses INSERT IGNORE so re-running is safe (role_permissions has a composite PK). +-- Permissions are resolved from ROLE_PERMISSIONS_SEED in src/shared/lib/permissions.ts. + +-- admin +INSERT IGNORE INTO `role_permissions` (`role_id`, `permission`) + SELECT id, 'exam:create' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'exam:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'exam:update' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'exam:delete' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'exam:duplicate' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'exam:publish' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'exam:ai_generate' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'homework:create' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'homework:grade' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'question:create' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'question:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'question:update' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'question:delete' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'textbook:create' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'textbook:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'textbook:update' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'textbook:delete' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'class:create' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'class:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'class:update' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'class:delete' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'class:enroll' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'class:schedule' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'school:manage' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'grade:manage' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'user:manage' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'user:profile_update' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'ai:chat' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'ai:configure' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'settings:admin' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'audit_log:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'announcement:manage' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'announcement:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'grade_record:manage' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'grade_record:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'course_plan:manage' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'course_plan:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'attendance:manage' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'attendance:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'message:send' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'message:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'message:delete' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'schedule:auto' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'schedule:adjust' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'elective:manage' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'elective:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'exam:proctor' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'exam:proctor:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'diagnostic:manage' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'diagnostic:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'lesson_plan:create' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'lesson_plan:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'lesson_plan:update' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'lesson_plan:delete' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'lesson_plan:publish' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'file:upload' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'file:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'file:delete' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'dashboard:admin_read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'error_book:analytics_read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'adaptive_practice:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'role:create' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'role:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'role:update' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'role:delete' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'role:assign' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'permission:read' FROM `roles` WHERE `name` = 'admin'; diff --git a/drizzle/0012_diagnostic_grade_id.sql b/drizzle/0012_diagnostic_grade_id.sql new file mode 100644 index 0000000..1e18525 --- /dev/null +++ b/drizzle/0012_diagnostic_grade_id.sql @@ -0,0 +1,4 @@ +-- v4-P2-3: Add gradeId column to learning_diagnostic_reports for grade-level diagnostic reports +ALTER TABLE `learning_diagnostic_reports` ADD COLUMN `grade_id` varchar(128);--> statement-breakpoint +ALTER TABLE `learning_diagnostic_reports` ADD CONSTRAINT `learning_diagnostic_reports_grade_id_grades_id_fk` FOREIGN KEY (`grade_id`) REFERENCES `grades`(`id`) ON DELETE set null ON UPDATE no action;--> statement-breakpoint +CREATE INDEX `diagnostic_grade_idx` ON `learning_diagnostic_reports` (`grade_id`); diff --git a/drizzle/0013_message_recall.sql b/drizzle/0013_message_recall.sql new file mode 100644 index 0000000..69c70df --- /dev/null +++ b/drizzle/0013_message_recall.sql @@ -0,0 +1,2 @@ +-- P2-4: 消息撤回功能(2 分钟窗口) +ALTER TABLE `messages` ADD COLUMN `recalled_at` timestamp; diff --git a/drizzle/0014_message_templates.sql b/drizzle/0014_message_templates.sql new file mode 100644 index 0000000..c85bc33 --- /dev/null +++ b/drizzle/0014_message_templates.sql @@ -0,0 +1,13 @@ +-- P2-6: 快捷回复模板 +CREATE TABLE `message_templates` ( + `id` varchar(128) PRIMARY KEY NOT NULL, + `user_id` varchar(128) NOT NULL, + `title` varchar(100) NOT NULL, + `content` text NOT NULL, + `sort_order` integer DEFAULT 0 NOT NULL, + `updated_at` timestamp DEFAULT (now()) ON UPDATE now() NOT NULL, + `created_at` timestamp DEFAULT (now()) NOT NULL, + CONSTRAINT `message_templates_user_id_users_id_fk` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE cascade ON UPDATE no action +); +CREATE INDEX `message_templates_user_idx` ON `message_templates`(`user_id`); +CREATE INDEX `message_templates_user_sort_idx` ON `message_templates`(`user_id`, `sort_order`); diff --git a/drizzle/0015_group_messages.sql b/drizzle/0015_group_messages.sql new file mode 100644 index 0000000..7a3ea8a --- /dev/null +++ b/drizzle/0015_group_messages.sql @@ -0,0 +1,3 @@ +-- P2-2: 群组消息(教师→全班家长,fan-out on write) +ALTER TABLE `messages` ADD COLUMN `group_message_id` varchar(128); +CREATE INDEX `messages_group_message_idx` ON `messages`(`group_message_id`); diff --git a/drizzle/0016_invitation_codes.sql b/drizzle/0016_invitation_codes.sql new file mode 100644 index 0000000..ea35d50 --- /dev/null +++ b/drizzle/0016_invitation_codes.sql @@ -0,0 +1,19 @@ +-- audit-P2-3: 注册邀请码表(admin 批量生成,注册时校验 + 自动分配角色/班级) +CREATE TABLE IF NOT EXISTS `invitation_codes` ( + `id` serial PRIMARY KEY, + `code` varchar(64) NOT NULL, + `email` varchar(255), + `role` varchar(50) NOT NULL, + `class_id` varchar(128), + `notes` varchar(500), + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `created_by` varchar(128), + `expires_at` timestamp NULL, + `used_by` varchar(128), + `used_at` timestamp NULL, + UNIQUE KEY `invitation_codes_code_unique` (`code`) +); + +CREATE INDEX `invitation_codes_code_idx` ON `invitation_codes`(`code`); +CREATE INDEX `invitation_codes_email_idx` ON `invitation_codes`(`email`); +CREATE INDEX `invitation_codes_used_by_idx` ON `invitation_codes`(`used_by`); diff --git a/drizzle/0016_message_reports_and_blocks.sql b/drizzle/0016_message_reports_and_blocks.sql new file mode 100644 index 0000000..460ecf3 --- /dev/null +++ b/drizzle/0016_message_reports_and_blocks.sql @@ -0,0 +1,35 @@ +-- P2-5: 消息举报 + 用户屏蔽 +-- 1. message_reports: 举报记录(reporterId → messageId / reportedUserId) +-- 2. user_blocks: 用户屏蔽关系(blockerId → blockedId,唯一约束防重复) + +CREATE TABLE `message_reports` ( + `id` varchar(128) NOT NULL, + `reporter_id` varchar(128) NOT NULL, + `message_id` varchar(128) NOT NULL, + `reported_user_id` varchar(128) NOT NULL, + `reason` varchar(50) NOT NULL, + `description` text, + `status` varchar(20) NOT NULL DEFAULT 'pending', + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + INDEX `message_reports_reporter_idx` (`reporter_id`), + INDEX `message_reports_message_idx` (`message_id`), + INDEX `message_reports_reported_user_idx` (`reported_user_id`), + INDEX `message_reports_status_idx` (`status`), + CONSTRAINT `message_reports_reporter_id_users_id_fk` FOREIGN KEY (`reporter_id`) REFERENCES `users`(`id`) ON DELETE CASCADE, + CONSTRAINT `message_reports_message_id_messages_id_fk` FOREIGN KEY (`message_id`) REFERENCES `messages`(`id`) ON DELETE CASCADE, + CONSTRAINT `message_reports_reported_user_id_users_id_fk` FOREIGN KEY (`reported_user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE +); + +CREATE TABLE `user_blocks` ( + `id` varchar(128) NOT NULL, + `blocker_id` varchar(128) NOT NULL, + `blocked_id` varchar(128) NOT NULL, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE INDEX `user_blocks_blocker_blocked_uniq` (`blocker_id`, `blocked_id`), + INDEX `user_blocks_blocker_idx` (`blocker_id`), + CONSTRAINT `user_blocks_blocker_id_users_id_fk` FOREIGN KEY (`blocker_id`) REFERENCES `users`(`id`) ON DELETE CASCADE, + CONSTRAINT `user_blocks_blocked_id_users_id_fk` FOREIGN KEY (`blocked_id`) REFERENCES `users`(`id`) ON DELETE CASCADE +); diff --git a/drizzle/0017_draft_device_sync.sql b/drizzle/0017_draft_device_sync.sql new file mode 100644 index 0000000..69ae2db --- /dev/null +++ b/drizzle/0017_draft_device_sync.sql @@ -0,0 +1,8 @@ +-- P2-10: 跨设备草稿同步 +-- 1. 新增 device_id 列(标识来源设备) +-- 2. 新增 version 列(乐观锁,冲突检测) +-- 3. 新增 (user_id, parent_message_id) 索引(按会话查询最新版本草稿) + +ALTER TABLE `message_drafts` ADD COLUMN `device_id` varchar(128); +ALTER TABLE `message_drafts` ADD COLUMN `version` int NOT NULL DEFAULT 1; +CREATE INDEX `message_drafts_user_parent_idx` ON `message_drafts`(`user_id`, `parent_message_id`); diff --git a/drizzle/0018_attendance_status_reason.sql b/drizzle/0018_attendance_status_reason.sql new file mode 100644 index 0000000..2c8c6ce --- /dev/null +++ b/drizzle/0018_attendance_status_reason.sql @@ -0,0 +1,11 @@ +-- L-1: 考勤状态细分 + 原因字段 +-- 1. 扩展 attendance_records.status 枚举:新增 'school_activity'(校内活动请假,如运动会、研学、社团活动) +-- 2. 新增 reason 字段:记录缺勤/迟到/早退/请假的具体原因(最多 255 字符),与 remark 区分 +-- - remark:教师备注(自由文本,可记录点名时观察到的情况) +-- - reason:标准化原因(用于统计与家长通知,如"病假-感冒"、"家中有事"等) + +ALTER TABLE `attendance_records` + MODIFY COLUMN `status` + ENUM('present','absent','late','early_leave','excused','school_activity') NOT NULL; + +ALTER TABLE `attendance_records` ADD COLUMN `reason` varchar(255); diff --git a/drizzle/0019_attendance_warning_thresholds.sql b/drizzle/0019_attendance_warning_thresholds.sql new file mode 100644 index 0000000..e0ce62d --- /dev/null +++ b/drizzle/0019_attendance_warning_thresholds.sql @@ -0,0 +1,6 @@ +-- L-3:出勤率阈值预警 +-- 新增 attendance_rate_threshold(出勤率阈值,默认 90%) +-- 新增 consecutive_absence_threshold(连续缺勤阈值,默认 3 次) +ALTER TABLE `attendance_rules` + ADD COLUMN `attendance_rate_threshold` int DEFAULT 90, + ADD COLUMN `consecutive_absence_threshold` int DEFAULT 3; diff --git a/drizzle/0020_leave_requests.sql b/drizzle/0020_leave_requests.sql new file mode 100644 index 0000000..2ebc96e --- /dev/null +++ b/drizzle/0020_leave_requests.sql @@ -0,0 +1,53 @@ +-- 0020_leave_requests.sql +-- L-5 在线请假流程:创建 leave_requests 表。 + +CREATE TABLE IF NOT EXISTS `leave_requests` ( + `id` varchar(128) NOT NULL, + `student_id` varchar(128) NOT NULL, + `requester_id` varchar(128) NOT NULL, + `class_id` varchar(128) NOT NULL, + `leave_type` enum('sick','personal','family','other') NOT NULL, + `start_date` date NOT NULL, + `end_date` date NOT NULL, + `reason` text NOT NULL, + `status` enum('pending','approved','rejected','cancelled') NOT NULL DEFAULT 'pending', + `reviewer_id` varchar(128) DEFAULT NULL, + `review_comment` text, + `reviewed_at` timestamp NULL DEFAULT NULL, + `attendance_synced` boolean NOT NULL DEFAULT false, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + KEY `leave_requests_student_idx` (`student_id`), + KEY `leave_requests_requester_idx` (`requester_id`), + KEY `leave_requests_class_idx` (`class_id`), + KEY `leave_requests_status_idx` (`status`), + KEY `leave_requests_reviewer_idx` (`reviewer_id`), + KEY `leave_requests_class_status_idx` (`class_id`, `status`), + KEY `leave_requests_student_status_idx` (`student_id`, `status`), + CONSTRAINT `lr_c_fk` FOREIGN KEY (`class_id`) REFERENCES `classes` (`id`) ON DELETE CASCADE, + CONSTRAINT `lr_s_fk` FOREIGN KEY (`student_id`) REFERENCES `users` (`id`) ON DELETE CASCADE, + CONSTRAINT `lr_rq_fk` FOREIGN KEY (`requester_id`) REFERENCES `users` (`id`) ON DELETE CASCADE, + CONSTRAINT `lr_rv_fk` FOREIGN KEY (`reviewer_id`) REFERENCES `users` (`id`) ON DELETE SET NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- 为 builtin 角色注入新权限(INSERT IGNORE 幂等) +-- admin:三个权限全有 +INSERT IGNORE INTO `role_permissions` (`role_id`, `permission`) + SELECT id, 'leave_request:create' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'leave_request:read' FROM `roles` WHERE `name` = 'admin' + UNION ALL SELECT id, 'leave_request:review' FROM `roles` WHERE `name` = 'admin' + -- teacher:read + review(班主任审批本班请假) + UNION ALL SELECT id, 'leave_request:read' FROM `roles` WHERE `name` = 'teacher' + UNION ALL SELECT id, 'leave_request:review' FROM `roles` WHERE `name` = 'teacher' + -- parent:create + read(代子女提交、查看子女请假记录) + UNION ALL SELECT id, 'leave_request:create' FROM `roles` WHERE `name` = 'parent' + UNION ALL SELECT id, 'leave_request:read' FROM `roles` WHERE `name` = 'parent' + -- student:create + read(本人提交、查看本人请假记录) + UNION ALL SELECT id, 'leave_request:create' FROM `roles` WHERE `name` = 'student' + UNION ALL SELECT id, 'leave_request:read' FROM `roles` WHERE `name` = 'student' + -- grade_head / teaching_head:read + review(年级主任/教务主任可审批) + UNION ALL SELECT id, 'leave_request:read' FROM `roles` WHERE `name` = 'grade_head' + UNION ALL SELECT id, 'leave_request:review' FROM `roles` WHERE `name` = 'grade_head' + UNION ALL SELECT id, 'leave_request:read' FROM `roles` WHERE `name` = 'teaching_head' + UNION ALL SELECT id, 'leave_request:review' FROM `roles` WHERE `name` = 'teaching_head'; diff --git a/drizzle/0021_attendance_period.sql b/drizzle/0021_attendance_period.sql new file mode 100644 index 0000000..0b937b5 --- /dev/null +++ b/drizzle/0021_attendance_period.sql @@ -0,0 +1,20 @@ +-- 0021_attendance_period.sql +-- L-6 节次考勤:为 attendance_records 表添加 period 字段。 +-- +-- 节次枚举: +-- morning_reading 早读 +-- morning 上午 +-- afternoon 下午 +-- evening 晚自习 +-- full_day 全日(默认值,向后兼容:null 也表示全日) +-- +-- 向后兼容策略: +-- - 新增 period 列为 NULLABLE,已有数据保持 NULL(视为 full_day) +-- - 新记录由应用层显式写入 period;未指定时写入 'full_day' +-- - 查询层 period IS NULL OR period = 'full_day' 均视为全日记录 + +ALTER TABLE `attendance_records` + ADD COLUMN `period` ENUM('morning_reading','morning','afternoon','evening','full_day') NULL DEFAULT NULL AFTER `date`; + +-- 复合索引:班级 + 日期 + 节次,支持按节次查询班级当日点名 +CREATE INDEX `attendance_records_class_date_period_idx` ON `attendance_records` (`class_id`, `date`, `period`); diff --git a/drizzle/meta/_journal.json b/drizzle/meta/_journal.json index 739989a..c8fda5c 100644 --- a/drizzle/meta/_journal.json +++ b/drizzle/meta/_journal.json @@ -43,6 +43,55 @@ "when": 1782141546400, "tag": "0005_messy_pride", "breakpoints": true + }, + { + "idx": 6, + "version": "5", + "when": 1782374400000, + "tag": "0013_message_recall", + "breakpoints": true + }, + { + "idx": 7, + "version": "5", + "when": 1782374500000, + "tag": "0014_message_templates", + "breakpoints": true + }, + { + "idx": 8, + "version": "5", + "when": 1782374600000, + "tag": "0015_group_messages", + "breakpoints": true + }, + { + "idx": 9, + "version": "5", + "when": 1782445200000, + "tag": "0018_attendance_status_reason", + "breakpoints": true + }, + { + "idx": 10, + "version": "5", + "when": 1782448800000, + "tag": "0019_attendance_warning_thresholds", + "breakpoints": true + }, + { + "idx": 11, + "version": "5", + "when": 1782452400000, + "tag": "0020_leave_requests", + "breakpoints": true + }, + { + "idx": 12, + "version": "5", + "when": 1782456000000, + "tag": "0021_attendance_period", + "breakpoints": true } ] } \ No newline at end of file