Skip to content

API 契约 v1(OpenAPI 3.0 · 2026-08-15 M0 D1 拍板)

作者:👤 Claude(执行副董事) 拍板:M0 D1 Claude 出全 3 份关键文档之一 目的:Codex 启动 M0 D2 写代码时直接按此契约开发,含 7 端点 + 参数 + 响应 关联:02-API接口规范.md(原型版基线)· 03-阶段计划.md · 06-数据模型.md · 07-5维评价详细设计.md


0. 基础约定

项 值
Base URL http://localhost:3000/api(开发) / https://zehu-prod.xxx.com/api(生产)
协议 HTTPS(生产) / HTTP(开发)
认证 JWT(Bearer Token),Header Authorization: Bearer <token>
数据格式 JSON,UTF-8
时间戳 ISO 8601 字符串(2026-08-15T01:30:00+08:00)
错误响应 HTTP 4xx/5xx + { "code": "ERROR_CODE", "message": "..." }

1. 7 大端点(OpenAPI 3.0)

1.1 POST /auth/login 三端登录

入参:

{
  "platform": "wechat" | "dingtalk" | "web",
  "accountType": "student" | "parent" | "teacher" | "schoolAdmin" | "educationAdmin" | "principal" | "partner",
  "identifier": "<微信 openid / 钉钉 unionId / 学号 / 工号 / 教联体账号>"
}

响应(200):

{
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "user": {
    "id": "u_123",
    "name": "张三",
    "role": "student",
    "classId": "c_456",
    "schoolId": "s_789",
    "avatar": "https://...",
    "mustChangePassword": false
  }
}

错误: - 401 INVALID_CREDENTIALS — 账号或密码错误 - 403 NOT_APPROVED — 账号未审批(教师/教务等需校长审批) - 404 USER_NOT_FOUND — 用户不存在 - 429 TOO_MANY_ATTEMPTS — 登录失败次数过多


1.2 GET /me 当前用户

Header:Authorization: Bearer <token>

响应(200):

{
  "id": "u_123",
  "name": "张三",
  "role": "student",
  "classId": "c_456",
  "schoolId": "s_789",
  "class": { "id": "c_456", "name": "初二(3)班", "grade": "8" },
  "permissions": ["evaluation.read", "evaluation.write"]
}


1.3 GET /dashboard/summary 首页驾驶舱

响应(200):

{
  "userRole": "teacher",
  "classId": "c_456",
  "todayTodos": [
    { "id": "t_1", "type": "evaluation", "title": "评价王小明 5 维", "dueAt": "2026-08-15T18:00:00+08:00" }
  ],
  "classRadar": {
    "moral": 85.5,
    "academic": 78.2,
    "health": 92.1,
    "art": 80.5,
    "practice": 88.3
  },
  "recentActivities": [
    { "id": "a_1", "type": "evaluation", "title": "李老师评价了王小明", "at": "2026-08-15T09:30:00+08:00" }
  ],
  "weekStats": {
    "evaluationsCount": 42,
    "partiesAttendCount": 3,
    "growthPercent": 5.2
  }
}


1.4 GET /evaluation/dimensions 五维评价维度

响应(200):

{
  "dimensions": [
    { "id": "moral", "name": "思想品德", "weight": 0.2, "points": 30 },
    { "id": "academic", "name": "学业水平", "weight": 0.3, "points": 30 },
    { "id": "health", "name": "身心健康", "weight": 0.2, "points": 30 },
    { "id": "art", "name": "艺术素养", "weight": 0.15, "points": 30 },
    { "id": "practice", "name": "劳动与社会实践", "weight": 0.15, "points": 30 }
  ]
}


1.5 POST /evaluation/records 提交/查询评价记录

Query(GET 模式):?studentId=u_123&term=2026-fall&limit=20&offset=0

Body(POST 模式):

{
  "studentId": "u_123",
  "dimension": "moral",
  "point": "p_moral_3",
  "level": "A",
  "score": 95,
  "comment": "主动帮助同学,品德表现突出",
  "evaluatedAt": "2026-08-15T09:30:00+08:00",
  "evidence": [ "https://.../photo1.jpg" ]
}

响应(200 POST):

{
  "id": "e_12345",
  "createdAt": "2026-08-15T09:30:05+08:00",
  "evaluatorId": "u_teacher_1",
  "evaluatorName": "李老师"
}

响应(200 GET):

{
  "total": 156,
  "records": [
    {
      "id": "e_1",
      "dimension": "moral",
      "point": "p_moral_3",
      "level": "A",
      "score": 95,
      "comment": "...",
      "evaluatorName": "李老师",
      "evaluatedAt": "2026-08-15T09:30:00+08:00"
    }
  ]
}


1.6 GET /students 学生列表(分页)

Query:?classId=c_456&grade=8&limit=20&offset=0&keyword=王

响应(200):

{
  "total": 45,
  "students": [
    {
      "id": "u_123",
      "name": "王小明",
      "studentNo": "20240815",
      "classId": "c_456",
      "className": "初二(3)班",
      "avatar": "https://...",
      "radar": {
        "moral": 85, "academic": 78, "health": 92, "art": 80, "practice": 88
      },
      "lastEvaluatedAt": "2026-08-15T09:30:00+08:00"
    }
  ]
}


1.7 GET /reports/term 学期报告单

Query:?studentId=u_123&term=2026-fall

响应(200):

{
  "student": { "id": "u_123", "name": "王小明", "className": "初二(3)班" },
  "term": "2026-fall",
  "scores": {
    "moral": { "score": 88, "level": "A", "breakdown": [ ... ] },
    "academic": { "score": 78, "level": "B", "breakdown": [ ... ] },
    "health": { "score": 92, "level": "A", "breakdown": [ ... ] },
    "art": { "score": 80, "level": "B", "breakdown": [ ... ] },
    "practice": { "score": 88, "level": "A", "breakdown": [ ... ] }
  },
  "overall": { "score": 85.2, "level": "A", "rank": 5 },
  "comments": {
    "classTeacher": "...",
    "schoolAdmin": "..."
  },
  "pdfUrl": "https://.../reports/u_123_2026-fall.pdf"
}


2. 错误码完整表

HTTP code 触发
400 INVALID_PARAMS 参数缺失或格式错
401 UNAUTHORIZED 未登录或 Token 过期
401 INVALID_TOKEN Token 无效
403 FORBIDDEN 权限不足
403 NOT_APPROVED 账号未审批
404 NOT_FOUND 资源不存在
409 CONFLICT 冲突(如重复提交)
413 PAYLOAD_TOO_LARGE 上传文件过大
429 RATE_LIMIT 限流
500 INTERNAL_ERROR 服务异常
503 SERVICE_UNAVAILABLE 维护中

3. 角色权限矩阵(v1)

端点 student parent teacher schoolAdmin educationAdmin principal partner
POST /auth/login ✅ ✅ ✅ ✅ ✅ ✅ ✅
GET /me ✅ ✅ ✅ ✅ ✅ ✅ ✅
GET /dashboard/summary ✅ ✅ ✅ ✅ ✅ ✅ ✅
GET /evaluation/dimensions ✅ ✅ ✅ ✅ ✅ ✅ ✅
POST /evaluation/records ❌ ❌ ✅(仅本班) ✅ ✅ ✅ ❌
GET /evaluation/records ✅(自己) ✅(自己孩子) ✅(本班) ✅ ✅ ✅ ❌
GET /students ✅(本班) ✅(自己孩子) ✅(本班) ✅ ✅ ✅ ❌
GET /reports/term ✅ ✅ ✅ ✅ ✅ ✅ ❌

4. 频率限制

端点 限制
POST /auth/login 5 次/分钟/IP
POST /evaluation/records 60 次/分钟/用户
GET /students 30 次/分钟/用户
GET /reports/term 10 次/分钟/用户

5. 共享类型

// 角色枚举
type Role = "student" | "parent" | "teacher" | "schoolAdmin" | "educationAdmin" | "principal" | "partner";

// 5 维评价维度
type Dimension = "moral" | "academic" | "health" | "art" | "practice";

// 评分等级
type Level = "A" | "B" | "C" | "D";

// 学期
type Term = "2026-fall" | "2026-spring" | "2025-fall" | ...;

6. 版本与部署

  • API 版本:v1(路径不加版本段,通过 Header X-API-Version: 1 兼容)
  • 兼容政策:新增字段不破坏旧客户端;删除字段需 6 个月过渡
  • OpenAPI 文件:docs/05-API契约.yaml(Codex D3 补)
  • Mock:http://localhost:3000/api/* 用 JSON 文件 mock

Why / How to apply

Why:M0 D1 Claude 一次性出全 3 份关键文档之一,Codex D2 启动后直接按契约开发,不用等设计稿。

How to apply: - Codex 写 Node API 时按此契约开发 - 写完用 OpenAPI 工具(Swagger CLI)生成 yaml - 前端用 openapi-typescript 自动生成类型 - 灰度测试时用 Postman/Insomnia 验证 7 端点