214 lines
9.9 KiB
Markdown
214 lines
9.9 KiB
Markdown
# HKU ICB ClassHub Agent Guide
|
||
|
||
本文件用于约束后续 agent 与开发者在本项目中的工作方式。目标是让每次改动都符合项目定位、权限模型、技术栈和现有设计语言,避免临时拼接式开发。
|
||
|
||
## 1. 项目定义
|
||
|
||
本项目是 HKU ICB Graduate Class Resource Platform,面向班级、教师、学生和班委的班级资源与协作系统。核心价值是围绕“班级”组织信息,提供可信、清晰、轻量的日常管理能力。
|
||
|
||
主要模块包括:
|
||
|
||
- 登录、激活、账号审核与个人资料
|
||
- 班级与成员管理
|
||
- 通讯录、时间线、公告、课程日程、资源、作业、投票、班费
|
||
- 通知、上传与外部存储
|
||
|
||
开发时必须优先保护以下产品原则:
|
||
|
||
- 班级数据隔离优先,任何列表、详情、写入都要明确 class scope。
|
||
- 权限优先于界面便利,不允许只靠前端隐藏按钮来保证安全。
|
||
- 管理功能要清晰可审计,避免隐式批量修改。
|
||
- 面向真实班级使用场景,界面应安静、稳定、易扫描,不做营销页式表达。
|
||
|
||
## 2. 技术栈与目录
|
||
|
||
仓库结构:
|
||
|
||
- `backend/`:FastAPI 后端,SQLAlchemy async ORM,Alembic 迁移,SQLite 默认部署数据源。
|
||
- `frontend/`:Next.js App Router 前端,React 19,TypeScript,Tailwind CSS 4,shadcn/base-ui 风格组件,lucide-react 图标。
|
||
- `nginx/`:反向代理配置。
|
||
- `docker-compose.yml`:本地或服务器编排,前端端口映射为 `3008:3000`,后端为 `8000`。
|
||
|
||
关键命令:
|
||
|
||
- 前端开发:`cd frontend && npm run dev`
|
||
- 前端构建:`cd frontend && npm run build`
|
||
- 前端检查:`cd frontend && npm run lint`
|
||
- 后端运行:`cd backend && uvicorn app.main:app --reload`
|
||
- 后端迁移:`cd backend && alembic upgrade head`
|
||
- 整体容器:`docker compose up --build`
|
||
|
||
注意:`frontend/AGENTS.md` 已明确提示 Next.js 版本存在重要变化。修改 Next.js 相关 API、路由、缓存、服务端/客户端组件边界前,应以本仓库安装版本与本地文档为准,不要凭旧版本记忆实现。
|
||
|
||
## 3. 架构约束
|
||
|
||
### 后端分层
|
||
|
||
后端代码按以下边界组织:
|
||
|
||
- `app/api/`:HTTP 路由层,只处理请求参数、依赖注入、状态码与响应。
|
||
- `app/services/`:业务逻辑层,承载跨模型操作、校验、查询组合和副作用。
|
||
- `app/schemas/`:Pydantic 输入输出模型。
|
||
- `app/db/models.py`:SQLAlchemy 数据模型。
|
||
- `app/core/`:鉴权、依赖、权限与通用基础能力。
|
||
- `app/config.py`:环境配置,统一使用 `CH_` 前缀。
|
||
|
||
开发规则:
|
||
|
||
- 新业务优先放入 service,不要把复杂逻辑堆在 route handler。
|
||
- 数据库访问使用 async SQLAlchemy,不引入同步 session。
|
||
- 查询关系时优先使用 `selectinload` 等显式加载策略,避免隐式懒加载导致异步上下文问题。
|
||
- 新增或修改表结构必须提供 Alembic migration,不允许只改 model。
|
||
- 错误信息面向用户时要清晰,面向系统时要保留日志;不要把密钥、token、内部堆栈暴露给前端。
|
||
|
||
### 前端分层
|
||
|
||
前端代码按以下边界组织:
|
||
|
||
- `src/app/`:页面与布局,App Router 路由入口。
|
||
- `src/components/`:跨页面业务组件。
|
||
- `src/components/ui/`:基础 UI 组件,尽量保持通用和低业务耦合。
|
||
- `src/hooks/`:认证、通知、当前班级、侧边栏等状态逻辑。
|
||
- `src/lib/`:API 客户端、类型、权限、常量、工具函数。
|
||
|
||
开发规则:
|
||
|
||
- 复用 `src/lib/api.ts` 中的 `fetchAPI`、`postAPI`、`putAPI`、`deleteAPI`、`uploadAPI`,不要在页面中散落裸 `fetch`。
|
||
- 复用 `src/lib/permissions.ts` 判断前端可见性,但后端仍必须做真实权限校验。
|
||
- 能用已有 UI 组件就不要新写一套样式系统。
|
||
- 表单提交、加载、空状态、错误状态、成功反馈都要完整处理。
|
||
- 客户端组件只在需要浏览器状态、事件、localStorage、交互状态时使用。
|
||
|
||
## 4. 权限与数据边界
|
||
|
||
系统存在两层权限:
|
||
|
||
- 全局角色:`super_admin`、`teacher`、`student`
|
||
- 班级内角色与权限:由 `ClassMembership` 的 `membership_role`、`committee_role`、`class_permissions` 控制
|
||
|
||
后端权限入口主要在 `app/core/deps.py`:
|
||
|
||
- `get_current_user`
|
||
- `require_role`
|
||
- `resolve_class_id_for_user`
|
||
- `ensure_class_access`
|
||
- `ensure_class_permission`
|
||
|
||
权限开发必须遵守:
|
||
|
||
- 任何班级资源 API 都必须解析并校验 `class_id`。
|
||
- student 只能访问自己所属班级的数据。
|
||
- teacher 与 super_admin 的跨班级访问能力必须通过后端依赖或 service 显式表达。
|
||
- 新增班级模块时,要同步更新后端 `CLASS_PERMISSIONS`、`TEACHER_DEFAULT_PERMISSIONS`,前端权限类型、常量、导航与模块启用逻辑。
|
||
- 前端隐藏按钮只是体验优化,不是安全边界。
|
||
|
||
## 5. 设计规范
|
||
|
||
本项目不是营销网站,而是班级运营工具。界面应更像可靠的工作台:信息密度适中、层级清楚、操作明确。
|
||
|
||
视觉方向:
|
||
|
||
- 采用现有 Tailwind 4 token 与 `globals.css` 中的主题变量。
|
||
- 保持温暖、克制、学术感的视觉语气,不要突然引入高饱和大渐变或强装饰背景。
|
||
- 图标优先使用 `lucide-react`。
|
||
- 卡片、弹窗、表格、表单、按钮优先复用 `src/components/ui/`。
|
||
- 中文界面文案要简洁、具体,避免“智能化”“一站式”等空泛营销词。
|
||
|
||
布局规则:
|
||
|
||
- 后台页面优先服务浏览、筛选、创建、编辑、审核等真实任务。
|
||
- 列表页必须考虑空状态、加载态、错误态和分页或数据量增长。
|
||
- 管理页的危险操作必须有确认弹窗。
|
||
- 移动端至少保证主要阅读、筛选和提交流程可用。
|
||
- 不在工具型页面中加入大 hero、宣传区、装饰性卡片堆叠。
|
||
|
||
交互规则:
|
||
|
||
- 成功、失败、权限不足、登录过期要给出明确反馈。
|
||
- 上传、提交、删除、批量操作要有 pending 状态,避免重复提交。
|
||
- 需要选择班级的页面,应与 `use-active-class` 等现有机制保持一致。
|
||
|
||
## 6. API 与数据契约
|
||
|
||
后端响应模型应由 `app/schemas/` 定义,前端类型应在 `src/lib/types.ts` 中保持同步。
|
||
|
||
约定:
|
||
|
||
- API 路径统一放在 `/api/...` 下。
|
||
- 新增字段时同时检查 model、schema、service、API、前端 type、表单、列表展示。
|
||
- 日期时间字段使用明确语义,例如 `created_at`、`updated_at`、`start_time`、`end_time`。
|
||
- JSON 字符串字段已有历史用法时,可沿用模型中的 helper 方法;新增复杂结构时优先评估是否需要独立表。
|
||
- 不把数据库内部字段、密码 hash、验证码 hash、密钥配置返回给前端。
|
||
|
||
## 7. 数据库与迁移
|
||
|
||
数据库相关改动必须遵守:
|
||
|
||
- 修改 `app/db/models.py` 后必须新增 Alembic migration。
|
||
- migration 文件命名要包含日期或清晰语义。
|
||
- migration 要能从旧库升级,不假设空库。
|
||
- 对生产已有数据的字段变更要考虑 backfill、默认值和 nullable 策略。
|
||
- 不直接删除历史字段或表,除非确认没有线上依赖,并在 migration 中清楚表达。
|
||
|
||
SQLite 是当前部署默认数据库,避免使用 SQLite 不支持或行为差异明显的 SQL 特性,除非同时处理兼容方案。
|
||
|
||
## 8. 安全规范
|
||
|
||
- 密钥、SMTP、COS、JWT 等配置只通过 `.env` 和环境变量提供,不提交真实值。
|
||
- JWT secret 生产环境必须覆盖默认值。
|
||
- 上传能力必须限制文件类型、大小与访问路径,避免任意文件执行或路径穿越。
|
||
- 邮箱验证码、密码、token 等敏感值只存 hash 或安全派生值。
|
||
- 日志中不得打印密码、验证码、完整 token、COS secret。
|
||
- CORS 配置应随部署域名收敛,不为方便调试长期开放任意来源。
|
||
|
||
## 9. 开发工作流
|
||
|
||
开始修改前:
|
||
|
||
- 先读相关 route、service、schema、model、前端 page/component/type。
|
||
- 确认是否已有相同模式,优先复用。
|
||
- 用 `rg` 搜索模块名、权限名、API 路径和类型定义,避免漏改。
|
||
|
||
实现时:
|
||
|
||
- 小步提交代码,保持每次改动有明确目的。
|
||
- 不做与需求无关的大重构。
|
||
- 不删除用户已有改动。
|
||
- 不引入新依赖,除非能明显降低复杂度,并更新安装与构建说明。
|
||
- Python 代码遵循当前项目风格和类型标注;TypeScript 避免 `any`,优先定义明确类型。
|
||
|
||
交付前至少检查:
|
||
|
||
- 前端:`npm run lint`,重要 UI 改动再跑 `npm run build`。
|
||
- 后端:能启动应用;涉及数据库时跑迁移;核心 service 改动要用脚本或测试验证主路径。
|
||
- API 契约:前后端字段、错误处理、权限处理一致。
|
||
- 浏览器体验:关键页面没有明显布局破损、重复提交、空白状态。
|
||
|
||
## 10. 新功能 Checklist
|
||
|
||
新增一个业务模块时,按顺序检查:
|
||
|
||
- 数据模型是否需要新增表或字段。
|
||
- Alembic migration 是否完整。
|
||
- Pydantic schema 是否覆盖创建、更新、读取。
|
||
- service 是否包含权限、班级边界、业务校验。
|
||
- API router 是否挂载到 `app/main.py`。
|
||
- 前端 type 是否同步。
|
||
- API client 调用是否使用 `src/lib/api.ts`。
|
||
- 页面是否接入侧边栏、权限可见性、模块启用状态。
|
||
- 是否有加载、空、错、成功状态。
|
||
- 是否需要通知、上传、分页或搜索。
|
||
- 是否更新常量、权限集合和文案。
|
||
|
||
## 11. Agent 行为准则
|
||
|
||
后续 agent 在本仓库工作时,应遵守:
|
||
|
||
- 用中文与项目维护者沟通,技术名词可保留英文。
|
||
- 先理解项目边界,再动手改代码。
|
||
- 发现需求与权限、安全、数据隔离冲突时,主动指出并给出更安全的实现。
|
||
- 能直接完成的任务直接实现,不只给建议。
|
||
- 修改前说明将改哪些区域;修改后说明改了什么、如何验证、还剩什么风险。
|
||
- 遇到 Next.js、React、FastAPI、SQLAlchemy 等版本敏感问题时,以本仓库依赖版本和官方文档为准。
|
||
- 保持代码和文档简洁,避免过度抽象。
|