docs: 补充仓库开发指南(AGENTS.md)
This commit is contained in:
@@ -1,14 +1,97 @@
|
|||||||
<!-- CODEGRAPH_START -->
|
# Repository Guidelines
|
||||||
## CodeGraph
|
|
||||||
|
|
||||||
In repositories indexed by CodeGraph (a `.codegraph/` directory exists at the repo root), reach for it BEFORE grep/find or reading files when you need to understand or locate code:
|
恭学教育基地管理系统(gongxue-base)——教培公司集训基地管理系统:宿舍水电费「人天数加权」计费、学生/班级/排课/考勤管理、学生档案(报读/成绩/花名册)、AI 助手与导入向导。代码注释、用户可见文案、commit message 均为中文。
|
||||||
|
|
||||||
- **MCP tool** (when available): `codegraph_explore` answers most code questions in one call — the relevant symbols' verbatim source plus the call paths between them, including dynamic-dispatch hops grep can't follow. Name a file or symbol in the query to read its current line-numbered source. If it's listed but deferred, load it by name via tool search.
|
## Project Overview
|
||||||
- **Shell** (always works): `codegraph explore "<symbol names or question>"` prints the same output.
|
|
||||||
|
|
||||||
If there is no `.codegraph/` directory, skip CodeGraph entirely — indexing is the user's decision.
|
npm workspaces 单体仓库(monorepo),Turborepo 编排:
|
||||||
<!-- CODEGRAPH_END -->
|
|
||||||
|
|
||||||
## Ant Design X
|
| 包 | 技术栈 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| `apps/server` | NestJS 11 + TypeORM 0.3 + MySQL | REST API,JWT + RBAC 权限 |
|
||||||
|
| `apps/admin` | React + Vite + antd + TanStack Query + zustand | 管理后台 SPA |
|
||||||
|
| `packages/typescript-config` | 共享 tsconfig(base/nestjs/react-vite) | 各包 extends 使用 |
|
||||||
|
|
||||||
修改 AI 助手、SSE 消息、运行时技能、附件或 Agent 工具前,先读取 `docs/skills/ant-design-x/SKILL.md`,优先使用项目已安装的 Ant Design X 组件与 SDK。
|
远端:Gitea(`git.gongxue100.com`,wangziqi/gongxue-base)。`main` 为受保护分支,改动经分支 + PR(`tea` CLI 合并,rebase 风格)。
|
||||||
|
|
||||||
|
## Architecture & Data Flow
|
||||||
|
|
||||||
|
```
|
||||||
|
admin (axios /api, Bearer token) → NestJS controllers → services → TypeORM repos → MySQL (utf8mb4)
|
||||||
|
```
|
||||||
|
|
||||||
|
- **后端**:`app.module.ts` 显式列出全部实体;TypeORM `migrationsRun: true` + glob 自动发现迁移;`synchronize` 仅当显式 `DB_SYNCHRONIZE=true`(生产禁用)。全局前缀 `/api`,`ValidationPipe({ transform: true })`,`/api/classes` 路由放宽 body 上限 2mb(花名册批量导入)。
|
||||||
|
- **权限**:服务端 `@RequirePermission('module:action')` + CASL 策略守卫;前端 `usePermission()` + `<PermissionButton permission="...">`。权限码由 RbacSeedService 播种。
|
||||||
|
- **前端**:react-router 懒加载页面;数据请求走 TanStack Query(`useApiQuery`/`useApiMutation`,`api/queryKeys.ts` 统一 key);全局状态 zustand(`store/user` 存 token,`store/permission` 存权限)。
|
||||||
|
- **认证**:JWT;axios 拦截器自动带 token,401 跳登录。
|
||||||
|
|
||||||
|
## Key Directories
|
||||||
|
|
||||||
|
- `apps/server/src/` — 按功能模块分目录:`auth`、`rbac`、`students`、`classes`、`exams`、`archive`(学生档案:报读/成绩/学习记录/附件/花名册同步)、`attendance`、`rooms`、`bills`、`wallets`、`imports`(导入向导)、`ai-chat`、`ai-config`、`agent-tools`、`integration`、`sync`、`operation-logs` 等
|
||||||
|
- `entities/` — 全部 TypeORM 实体;`migrations/` — 迁移文件(时间戳前缀);`common/` — dayjs(UTC+8 固定)、mime、`with-audit-log` 等
|
||||||
|
- `apps/admin/src/` — `pages/`(路由页面)、`components/`(含 `EditableCell` 可编辑单元格体系)、`api/`、`hooks/`、`store/`、`layouts/`、`ui/`、`utils/`、`test/`
|
||||||
|
- `.gitea/workflows/` — `ci.yml`(PR 校验)、`dependency-check.yml`(npm audit)、`deploy.yml`(PM2 部署)
|
||||||
|
- 根目录 — `deploy.sh`(部署脚本)、`ecosystem.config.cjs`(pm2)、`turbo.json`
|
||||||
|
|
||||||
|
## Development Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 根目录(turbo 透传)
|
||||||
|
npm run dev # 并行起 server(3000) + admin(3002)
|
||||||
|
npm run build / lint / typecheck / format / test
|
||||||
|
|
||||||
|
# 后端(apps/server)
|
||||||
|
npm run dev -w @gongxue/server # SEED_DEV=true nest start --watch
|
||||||
|
npm run start:prod -w @gongxue/server # node dist/main(PM2 用这个)
|
||||||
|
npm run test -w @gongxue/server # jest,全部 *.spec.ts
|
||||||
|
npm run migration:generate -w @gongxue/server -- src/migrations/Name # 生成迁移(-d datasource.ts)
|
||||||
|
npm run migration:run -w @gongxue/server # 执行迁移(部署时也跑)
|
||||||
|
|
||||||
|
# 前端(apps/admin)
|
||||||
|
npm run dev -w @gongxue/admin # vite :3002,代理 /api → :3000
|
||||||
|
npm run test -w @gongxue/admin # vitest run
|
||||||
|
```
|
||||||
|
|
||||||
|
开发环境数据库:`.env`(gitignore,仅服务器保留生产版)。`apps/server/.env` 有本地开发配置(DB_PASSWORD 等),服务启动时 `dotenv` 加载。
|
||||||
|
|
||||||
|
## Code Conventions & Common Patterns
|
||||||
|
|
||||||
|
- **实体**:表名复数 snake_case;列用 `@Column({ name: 'snake_case' })`;`student` 关系多用 `eager: true`;状态枚举用 TS enum(如 `ClassStatus`);唯一约束用 `@Unique`。
|
||||||
|
- **迁移**:`MigrationInterface`,文件名 `{timestamp}-{Name}.ts`;**必须幂等**——用 `hasColumn()`/`hasTable()`/`information_schema` 守卫再改结构。新增迁移文件零登记(glob 自动发现)。注意 `rank` 等 MySQL 保留字列名要反引号。
|
||||||
|
- **DTO**:class-validator 装饰器链(`@IsOptional() @IsString()` 等),更新用 `PartialType(CreateXxxDto)`;数值上限与列宽对齐(如 `decimal(5,2)` → `@Max(999.99)`),否则超范围写库报 500。
|
||||||
|
- **服务**:构造器注入 `@InjectRepository(Entity)` + 服务类;跨表写操作用 `dataSource.transaction(async (manager) => ...)`;业务错误抛 `BadRequestException`/`NotFoundException`(中文消息)。
|
||||||
|
- **审计**:controller 里包 `withAuditLog(this.logService, req, (result) => ({ module, action, targetId, targetType, detail }), () => service.method(...))`。
|
||||||
|
- **权限**:路由 `@RequirePermission('student:edit')` 等;`student:view`/`student:edit` 是档案读写常用码。
|
||||||
|
- **前端数据流**:组件内 `useApiMutation(fn, { invalidate: [['archive', studentId]] })`——变更后按 query key 失效重取;错误提示统一走 `ui/app-message`(`message.success/error`),不要在组件里重复 try/catch 弹窗。
|
||||||
|
- **可编辑单元格**:`EditableCell` editor 类型 `text|number|select|date|multi-select|tags`;`serializeEditableValue`/`normalizeEditableValue` 负责提交/展示值转换;`editableValuesEqual` 判空提交。
|
||||||
|
- **日期**:后端 `common/dayjs` 固定 UTC+8(`dayjs().utcOffset(8).format('YYYY-MM-DD')`);前端 dayjs 加载 zh-cn locale 与 antd 面板插件。
|
||||||
|
- **commit message**:`type(scope): 中文描述`(如 `feat(server):`、`fix(admin):`、`refactor(server):`),scope 为 `server`/`admin`。
|
||||||
|
|
||||||
|
## Important Files
|
||||||
|
|
||||||
|
- `apps/server/src/main.ts` — bootstrap:全局前缀、ValidationPipe、body 上限、helmet/compression/cors
|
||||||
|
- `apps/server/src/app.module.ts` — 模块注册 + TypeORM 配置(entities 显式数组、migrations glob + `migrationsRun: true`)
|
||||||
|
- `apps/server/datasource.ts` — CLI 迁移 DataSource(glob 实体/迁移,根目录 + 本地 `.env` 双加载)
|
||||||
|
- `apps/server/src/entities/student-enrollment.entity.ts` — 报读实体(`class_id` 关联班级,花名册同步的源)
|
||||||
|
- `apps/admin/src/api/index.ts` — axios 实例(baseURL `/api`、token 注入、401 登出)
|
||||||
|
- `apps/admin/src/App.tsx` — 路由表(lazy 页面 + `PermissionRoute`)
|
||||||
|
- `ecosystem.config.cjs` — pm2 应用 `gongxue-backend`(`apps/server/dist/main.js`)
|
||||||
|
- `deploy.sh` / `.gitea/workflows/deploy.yml` — 部署(见下)
|
||||||
|
- `README.md` — 功能模块总览
|
||||||
|
|
||||||
|
## Runtime/Tooling Preferences
|
||||||
|
|
||||||
|
- **Node 22 + npm 11**(workspaces,`packageManager: npm@11.12.1`;CI 容器 `node:22.22.0-bookworm`),无 `.nvmrc`/engines 锁定
|
||||||
|
- **Turborepo**:`turbo.json` 任务 `build`/`dev`/`lint`/`test`/`format`/`typecheck`
|
||||||
|
- **MySQL 8**,库名 `dorm_billing_v2`(生产 `jidi.gongxue100.com` 对应实例),`utf8mb4`,迁移记录在 `migrations` 表
|
||||||
|
- **TypeScript** `~6.0.2`(server),共享配置 `packages/typescript-config`(`strictNullChecks: true`)
|
||||||
|
- **Gitea Actions**:runner `nonlocal-runner`(个人作用域,标签 `ubuntu-latest` 等,宿主机直跑无容器——deploy job 依赖此访问 PM2/部署目录)。CI job 显式声明 `container: node:22.22.0-bookworm`
|
||||||
|
- **tea CLI**:PR 创建/合并(`tea pr create`/`tea pr merge -s rebase`)、触发 workflow(`tea actions workflows dispatch`,需 Gitea ≥1.25;旧版用 API POST `actions/workflows/deploy.yml/dispatches`)
|
||||||
|
- 部署:手动 dispatch「PM2 本地部署」workflow 或 `./deploy.sh <ssh_host>`;生产目录 `/www/wwwroot/jidi.gongxue100.com`(workflow 默认值,可用仓库变量 `REMOTE_DIR` 覆盖);顺序为 `git pull → npm ci → build → migration:run → pm2 startOrReload → 健康检查(401/200)`,迁移失败在 PM2 重载前中止
|
||||||
|
|
||||||
|
## Testing & QA
|
||||||
|
|
||||||
|
- **后端**:Jest + ts-jest,`testRegex: .*\.spec\.ts$`,测试文件与源码同目录(`*.spec.ts` 就近放置)。Repo 约定:`npm run test -w @gongxue/server -- --runInBand --forceExit`(CI 用)。服务测试用 jest.fn 构造 repo mock(新增构造参数会破坏 spec,需同步补 `{} as never` 占位)。关键服务有边界测试(`archive.boundaries.spec.ts`、`archive.enrollment-roster.spec.ts` 等)。
|
||||||
|
- **前端**:Vitest + `@vitest/browser` + Playwright(`src/test/setup.ts`),组件测试含截图快照(`__screenshots__/`)。
|
||||||
|
- **CI**(`.gitea/workflows/ci.yml`,PR → main 触发):`npm ci → lint → typecheck → build admin → server tests`。
|
||||||
|
- **变更验证惯例**:UI 改动在浏览器验证;服务端逻辑跑相关 spec;迁移改动在本地库实跑并查 `migrations` 表;全量回归 `npx jest --silent`(server,约 155 suites/1200+ tests)。
|
||||||
|
|||||||
Reference in New Issue
Block a user