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
This commit is contained in:
85
drizzle/0011_rbac_role_flags_and_seed.sql
Normal file
85
drizzle/0011_rbac_role_flags_and_seed.sql
Normal file
@@ -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';
|
||||
4
drizzle/0012_diagnostic_grade_id.sql
Normal file
4
drizzle/0012_diagnostic_grade_id.sql
Normal file
@@ -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`);
|
||||
2
drizzle/0013_message_recall.sql
Normal file
2
drizzle/0013_message_recall.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
-- P2-4: 消息撤回功能(2 分钟窗口)
|
||||
ALTER TABLE `messages` ADD COLUMN `recalled_at` timestamp;
|
||||
13
drizzle/0014_message_templates.sql
Normal file
13
drizzle/0014_message_templates.sql
Normal file
@@ -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`);
|
||||
3
drizzle/0015_group_messages.sql
Normal file
3
drizzle/0015_group_messages.sql
Normal file
@@ -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`);
|
||||
19
drizzle/0016_invitation_codes.sql
Normal file
19
drizzle/0016_invitation_codes.sql
Normal file
@@ -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`);
|
||||
35
drizzle/0016_message_reports_and_blocks.sql
Normal file
35
drizzle/0016_message_reports_and_blocks.sql
Normal file
@@ -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
|
||||
);
|
||||
8
drizzle/0017_draft_device_sync.sql
Normal file
8
drizzle/0017_draft_device_sync.sql
Normal file
@@ -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`);
|
||||
11
drizzle/0018_attendance_status_reason.sql
Normal file
11
drizzle/0018_attendance_status_reason.sql
Normal file
@@ -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);
|
||||
6
drizzle/0019_attendance_warning_thresholds.sql
Normal file
6
drizzle/0019_attendance_warning_thresholds.sql
Normal file
@@ -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;
|
||||
53
drizzle/0020_leave_requests.sql
Normal file
53
drizzle/0020_leave_requests.sql
Normal file
@@ -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';
|
||||
20
drizzle/0021_attendance_period.sql
Normal file
20
drizzle/0021_attendance_period.sql
Normal file
@@ -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`);
|
||||
@@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user