========================================
Class Management 班级管理模块
========================================

基于 FastAPI + SQLAlchemy + MySQL 的班级管理模块，
提供班级的增删改查、多字段分页查询、逻辑删除等能力。

----------------------------------------
一、目录结构
----------------------------------------

class_management/
  api/
    class_management_api.py       # 路由层：定义 HTTP 接口
  dao/
    class_management_dao.py       # 数据访问层：封装数据库操作
  model/
    class_management_model.py     # ORM 模型：映射数据库表
  schema/
    class_management_request.py   # Pydantic 模型：请求/响应体
  database.py                     # 数据库连接、Session、Base

分层职责：
  api     接收请求、参数校验、返回响应，不直接写 SQL
  dao     封装 CRUD、事务控制，不处理 HTTP 状态码
  model   定义表结构、字段约束，不写业务逻辑
  schema  定义请求/响应格式，不碰数据库

----------------------------------------
二、数据表结构
----------------------------------------

表名：classes

字段                类型         约束                    说明
------------------  -----------  ----------------------  ------------------
id                  Integer      PK, Auto Increment      班级主键
num                 String(50)   NOT NULL, UNIQUE        班级编号
name                String(50)   NOT NULL                班级名称
head_teacher_id     Integer      FK -> teachers.id       班主任编号
coach_teacher_id    Integer      FK -> teachers.id       授课老师编号
tutor_teacher_id    Integer      FK -> teachers.id       助教老师编号
class_start_time    Date         可空                    开班日期
class_end_time      Date         可空                    结课日期
is_delete           Integer      默认 0                  逻辑删除 0未删 1已删
create_time         DATETIME     默认 now                创建时间
update_time         DATETIME     默认 now, onupdate now  更新时间

注意：head_teacher_id / coach_teacher_id / tutor_teacher_id 是外键，
      插入前需保证 teachers 表中存在对应 id。

----------------------------------------
三、API 接口
----------------------------------------

基础前缀：/classes

[1] 新增班级
    POST /classes

    请求体：
    {
      "num": "C001",
      "name": "Python01班",
      "head_teacher_id": 1,
      "coach_teacher_id": 2,
      "tutor_teacher_id": 3,
      "class_start_time": "2025-01-01",
      "class_end_time": "2025-06-30"
    }

    字段说明：
      num                 string  班级编号，唯一
      name                string  班级名称
      head_teacher_id     int     班主任 ID
      coach_teacher_id    int     授课老师 ID
      tutor_teacher_id    int     助教老师 ID
      class_start_time    date    格式 YYYY-MM-DD
      class_end_time      date    格式 YYYY-MM-DD

    响应：
    {
      "code": 200,
      "detail": "新增成功",
      "totals": 1,
      "data": { ... }
    }

    错误：
      400  班级编号已存在


[2] 根据 ID 查询班级
    GET /classes/{class_id}

    响应：
    {
      "code": 200,
      "detail": "OK",
      "totals": 1,
      "data": {
        "id": 1,
        "num": "C001",
        "name": "Python01班",
        "head_teacher_id": 1,
        "coach_teacher_id": 2,
        "tutor_teacher_id": 3,
        "class_start_time": "2025-01-01",
        "class_end_time": "2025-06-30"
      }
    }

    错误：
      404  该班级不存在或已删除

[3] 多字段分页查询
    GET /classes

    Query 参数：
      num                string  班级编号（精确匹配）
      name               string  班级名称（精确匹配）
      head_teacher_id    int     班主任 ID
      coach_teacher_id   int     授课老师 ID
      tutor_teacher_id   int     助教老师 ID
      class_start_time   date    开班日期
      class_end_time     date    结课日期
      page               int     页码，默认 1，>=1
      page_size          int     每页条数，默认 5，1~20

    请求示例：
      GET /classes?name=Python01班&page=1&page_size=5

    响应：
    {
      "code": 200,
      "detail": "OK",
      "totals": 1,
      "data": [
        { "id": 1, "num": "C001", "name": "Python01班", ... }
      ]
    }

    注意：当前为内存分页，先查出所有匹配记录再切片。
          数据量大时建议改成 DB 层 offset/limit。

[4] 修改班级信息
    PUT /classes/{class_id}

    请求体（只传要改的字段）：
    {
      "head_teacher_id": 5,
      "class_end_time": "2025-12-31"
    }

    响应：
    {
      "code": 200,
      "detail": "修改成功",
      "data": { "id": 1 }
    }

    错误：
      400  没有传入要修改的字段
      404  班级不存在，修改失败

[5] 逻辑删除班级
    DELETE /classes/{class_id}

    响应：
    {
      "code": 200,
      "detail": "删除成功",
      "data": { "id": 1 }
    }

    错误：
      404  班级不存在，删除失败

    说明：逻辑删除，只把 is_delete 置为 1，不物理删除记录。

----------------------------------------
五、约定与规范
----------------------------------------

返回值约定：

  DAO 函数            成功返回    失败返回        API 判断
  ------------------  ----------  ------------  ------------------
  add_class_dao       None        错误字符串      if res:
  update_class_dao    int >= 1    0             if not row_count:
  delete_class_dao    int >= 1    0             if not del_rows:
  get_class_dao       list        []            if not res:

逻辑删除：
  所有查询默认过滤 is_delete = 0，
  删除操作用 UPDATE is_delete = 1，不做物理删除。

分页：
  page 从 1 开始
  page_size 范围 1~20
  返回 totals 为总条数，data 为当前页数据



模块负责人：cyf
最后更新：2026-09-22