database: type: "sqlite" version: "3" tables: - name: "users" columns: - name: "id" type: "TEXT" primaryKey: true - name: "name" type: "TEXT" nullable: false constraints: "CHECK(length(name) >= 2 AND length(name) <= 20)" - name: "phone" type: "TEXT" nullable: false unique: true constraints: "CHECK(length(phone) = 11 AND phone LIKE '1%' AND substr(phone, 2, 1) BETWEEN '3' AND '9')" - name: "password" type: "TEXT" comment: "用户登录密码 (当前版本为明文存储)" - name: "created_at" type: "DATETIME" default: "CURRENT_TIMESTAMP" indexes: - name: "idx_users_phone" columns: ["phone"] - name: "idx_users_created_at" columns: ["created_at"] - name: "user_groups" columns: - name: "id" type: "TEXT" primaryKey: true - name: "name" type: "TEXT" nullable: false unique: true - name: "description" type: "TEXT" - name: "is_system" type: "INTEGER" default: "0" comment: "是否为系统内置组 (0:否, 1:是)" - name: "created_at" type: "DATETIME" default: "CURRENT_TIMESTAMP" indexes: - name: "idx_user_groups_name" columns: ["name"] - name: "user_group_members" columns: - name: "group_id" type: "TEXT" nullable: false foreignKey: table: "user_groups" column: "id" - name: "user_id" type: "TEXT" nullable: false foreignKey: table: "users" column: "id" - name: "created_at" type: "DATETIME" default: "CURRENT_TIMESTAMP" indexes: - name: "idx_user_group_members_unique" columns: ["group_id", "user_id"] unique: true - name: "question_categories" columns: - name: "id" type: "TEXT" primaryKey: true - name: "name" type: "TEXT" nullable: false unique: true - name: "created_at" type: "DATETIME" default: "CURRENT_TIMESTAMP" indexes: - name: "idx_question_categories_name" columns: ["name"] - name: "questions" columns: - name: "id" type: "TEXT" primaryKey: true - name: "content" type: "TEXT" nullable: false - name: "type" type: "TEXT" nullable: false constraints: "CHECK(type IN ('single', 'multiple', 'judgment', 'text'))" - name: "category" type: "TEXT" nullable: false default: "'通用'" comment: "题目类别名称 (无类别时默认通用)" - name: "options" type: "TEXT" comment: "JSON格式存储选项" - name: "answer" type: "TEXT" nullable: false - name: "score" type: "INTEGER" nullable: false constraints: "CHECK(score > 0)" - name: "created_at" type: "DATETIME" default: "CURRENT_TIMESTAMP" indexes: - name: "idx_questions_type" columns: ["type"] - name: "idx_questions_category" columns: ["category"] - name: "idx_questions_score" columns: ["score"] - name: "exam_subjects" columns: - name: "id" type: "TEXT" primaryKey: true - name: "name" type: "TEXT" nullable: false unique: true - name: "total_score" type: "INTEGER" nullable: false constraints: "CHECK(total_score > 0)" - name: "time_limit_minutes" type: "INTEGER" nullable: false default: "60" constraints: "CHECK(time_limit_minutes > 0)" - name: "type_ratios" type: "TEXT" nullable: false comment: "题型比重 JSON (single/multiple/judgment/text)" - name: "category_ratios" type: "TEXT" nullable: false comment: "题目类别比重 JSON (categoryName->ratio)" - name: "created_at" type: "DATETIME" default: "CURRENT_TIMESTAMP" - name: "updated_at" type: "DATETIME" default: "CURRENT_TIMESTAMP" indexes: - name: "idx_exam_subjects_name" columns: ["name"] - name: "exam_tasks" columns: - name: "id" type: "TEXT" primaryKey: true - name: "name" type: "TEXT" nullable: false - name: "subject_id" type: "TEXT" nullable: false foreignKey: table: "exam_subjects" column: "id" - name: "start_at" type: "DATETIME" nullable: false - name: "end_at" type: "DATETIME" nullable: false - name: "created_at" type: "DATETIME" default: "CURRENT_TIMESTAMP" indexes: - name: "idx_exam_tasks_subject_id" columns: ["subject_id"] - name: "idx_exam_tasks_start_at" columns: ["start_at"] - name: "idx_exam_tasks_end_at" columns: ["end_at"] - name: "exam_task_users" columns: - name: "id" type: "TEXT" primaryKey: true - name: "task_id" type: "TEXT" nullable: false foreignKey: table: "exam_tasks" column: "id" - name: "user_id" type: "TEXT" nullable: false foreignKey: table: "users" column: "id" - name: "assigned_at" type: "DATETIME" default: "CURRENT_TIMESTAMP" indexes: - name: "idx_exam_task_users_task_id" columns: ["task_id"] - name: "idx_exam_task_users_user_id" columns: ["user_id"] - name: "quiz_records" columns: - name: "id" type: "TEXT" primaryKey: true - name: "user_id" type: "TEXT" nullable: false foreignKey: table: "users" column: "id" - name: "total_score" type: "INTEGER" nullable: false - name: "correct_count" type: "INTEGER" nullable: false - name: "total_count" type: "INTEGER" nullable: false - name: "created_at" type: "DATETIME" default: "CURRENT_TIMESTAMP" indexes: - name: "idx_quiz_records_user_id" columns: ["user_id"] - name: "idx_quiz_records_created_at" columns: ["created_at"] - name: "quiz_answers" columns: - name: "id" type: "TEXT" primaryKey: true - name: "record_id" type: "TEXT" nullable: false foreignKey: table: "quiz_records" column: "id" - name: "question_id" type: "TEXT" nullable: false foreignKey: table: "questions" column: "id" - name: "user_answer" type: "TEXT" nullable: false - name: "score" type: "INTEGER" nullable: false - name: "is_correct" type: "BOOLEAN" nullable: false - name: "created_at" type: "DATETIME" default: "CURRENT_TIMESTAMP" indexes: - name: "idx_quiz_answers_record_id" columns: ["record_id"] - name: "idx_quiz_answers_question_id" columns: ["question_id"] - name: "system_configs" columns: - name: "id" type: "TEXT" primaryKey: true - name: "config_type" type: "TEXT" nullable: false unique: true - name: "config_value" type: "TEXT" nullable: false - name: "updated_at" type: "DATETIME" default: "CURRENT_TIMESTAMP"