Files
Mdeical_Sur_Report/AGENTS.md
admin 2a86d9f5e4 Raise report upload request size limits
- Configure NestJS with an explicit JSON and urlencoded body parser limit controlled by API_BODY_LIMIT.

- Set the default API body limit to 100mb for report HTML, key frames, template images, and Data URL file uploads.

- Add a matching Nginx client_max_body_size 100m limit so Docker web proxy no longer rejects large report saves first.

- Document the new request body limit in README, deployment docs, progress notes, environment example, and AGENTS context.

- Rebuild and verify Docker web/api with a large report save through the Nginx /api proxy.
2026-05-02 03:29:46 +08:00

380 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI 编码助手项目说明
本文件面向 AI 编码助手。阅读者应假设对该项目一无所知。以下信息基于当前仓库实际文件、脚本和源码;不要把早期设计目标当作已实现事实。任何代码和功能修改都要落实到文档和测试上。如果生成 git commit 信息,要逐个列点把所有修改都列上,重要的、大的修改放前面,不重要的、小的修改列在后面。
## 项目一句话
这是一个“手术图文病历报告系统”。当前登录认证已接入 NestJS Session API、PostgreSQL 用户表和数据库 Session Store工作台统计、报告、报告媒体、模板、字段库、模板图片资源、视频/关键帧文件、用户、部门权限、系统设置、签名文件、AI 对话和讯飞语音听写已优先接入后端 API/代理。开发模式仍保留本地兼容回退,不能把前端权限和本地缓存当作生产安全边界。
## 当前技术栈
- React 19
- TypeScript 5.8
- Vite 6
- Tailwind CSS 4
- React Router DOM 7
- Lucide React
- Vitest + jsdom + Testing Library
- Playwright
- NestJS + Prisma + PostgreSQL 后端骨架
- Docker + Nginx
## 运行脚本
```bash
npm install
npm run dev # Vite dev server, 0.0.0.0:3001
npm run server:dev # build and start NestJS API, 0.0.0.0:3100
npm run server:build # tsc -p server/tsconfig.json
npm run lint # tsc --noEmit
npm run test # vitest run
npm run test:e2e # playwright test
npm run build # vite build
npm run prisma:generate
npm run prisma:migrate
npm run prisma:seed
```
修改代码后至少运行:
```bash
npm run lint
npm run test
```
如果改动构建、依赖、路由、样式或部署相关内容,也运行:
```bash
npm run build
```
如果改动后端源码、Prisma schema、认证、权限或 API 契约,也运行:
```bash
npm run server:build
npm run prisma:generate
```
后端化、权限或关键用户流程变更时也运行:
```bash
npm run test:e2e
```
## 默认账号
| 用户ID | 密码 | 角色 |
| --- | --- | --- |
| `admin` | `123456` | 超级管理员 |
| `manager` | `123456` | 管理员 |
| `0001` | `123456` | 医生 |
默认数据由 `src/pages/Login.tsx` 首次进入时初始化。
## 主要业务脉络
1. 用户进入 `/` 登录页。
2. 登录页初始化默认用户、模板、字段、图片资源和系统设置。
3. 登录页通过 `AuthContext` 调用后端 `/api/auth/login`,后端写入 HttpOnly Session Cookie。
4. 登录成功后前端把后端安全用户 DTO 映射成兼容 `User`,写入 `localStorage.currentUser`,跳转到 `/dashboard`
5. `AuthProvider` 启动时通过 `/api/auth/me` 恢复会话;侧边栏优先读取 Auth Context回退 `currentUser.role` 展示不同菜单。
6. 报告编辑器使用模板 HTML 生成报告正文,通过 `data-bind` 字段把侧边表单和正文智能字段同步。
7. 视频上传后使用浏览器 `<video>``<canvas>` 预览/抽帧,同时优先通过 `/api/files` 上传视频和关键帧文件,关键帧可插入报告图片占位符。
8. AI 面板把消息和图片上下文发送到 `/api/ai/chat`,后端读取系统设置中的共用 OpenAI 兼容 Provider 并代理调用 `/chat/completions`,返回内容可注入 AI 可编辑区域。
9. 语音听写把麦克风音频发送到 `/api/speech/iat` WebSocket后端读取系统设置中的讯飞配置、生成鉴权 URL 并转发讯飞 IAT 结果。
10. 报告保存优先调用 `POST/PATCH /api/reports`,后端保存到 PostgreSQL仅开发/显式回退模式下 API 不可用时回退 `localStorage.reports`
11. 报告管理页优先调用 `GET /api/reports`,后端按角色过滤报告;前端支持搜索、筛选、历史恢复、打印和 JSON 导出。
12. 模板管理页优先调用 `GET/POST/PATCH/DELETE /api/templates` 管理模板 HTML调用 `/api/library/fields` 维护字段库,并通过 `/api/files` 上传模板图片资源。
13. 用户管理页优先调用 `GET/PATCH /api/users` 等接口维护用户、角色、部门和模板授权;签名图片通过 `/api/users/:id/signature` 上传为后端文件资源。
14. 系统设置页优先调用 `GET/PATCH /api/settings/system` 维护抽帧策略、默认模板、AI Provider 和讯飞语音配置。
## 功能真实性判断
详细清单见 `docs/features.md`。处理需求时应区分:
- 真实可用本地初始化、字段绑定、JSON 导出等。
- 真实集成:后端 Session 登录、Dashboard API、报告 API、模板 API、用户/部门 API、设置 API、签名文件 API、审计日志 API、AI 代理、讯飞语音代理、浏览器打印/PDF、视频抽帧。它们有真实代码路径但依赖后端服务、浏览器能力、权限、有效密钥、网络或人工保存。
- 前端体验控制:页面级角色守卫和菜单隐藏已接入 Auth Context但不能替代后端 API 权限。
## 当前安全边界
本项目不能按生产安全系统理解:
- 后端账号使用 Argon2 哈希;开发回退模式下 `localStorage.users` 仍保留兼容缓存和旧演示密码字段。
- 页面级权限在前端用于体验控制,不能抵御绕过;生产安全边界以后端 API 权限校验为准。
- 报告和模板 HTML 保存时已做服务端白名单清洗;前端仍使用 HTML 渲染,继续修改时要留意 XSS 和打印兼容。
- AI Key 和讯飞语音密钥已由后端代理使用,普通用户读取系统设置时不会返回真实密钥。
- 当前 demo mode 后端默认值包含演示用第三方服务凭据,生产化前必须替换或移除,并轮换曾经暴露过的密钥。
- 视频和关键帧文件已优先进入后端文件资源;报告保存时通过 `ReportMedia` 关系表关联,新建报告保存前仍依赖浏览器对象 URL 预览。
- `VITE_ENABLE_LOCAL_FALLBACK` 控制生产构建是否允许本地兼容回退;开发模式默认允许,生产默认关闭。
涉及生产化、后端化、用户化时,优先阅读 `docs/backendization-plan.md``docs/security.md`
## 文件结构
```text
.
├── AGENTS.md # AI 编码助手上下文和协作约定
├── README.md # 面向开发者的项目说明
├── package.json # 依赖与 npm scripts
├── package-lock.json # npm 锁文件
├── prisma.config.ts # Prisma 7 CLI 配置
├── vite.config.ts # Vite/Tailwind/React/Vitest 配置
├── playwright.config.ts # Playwright E2E 配置,启动/复用 3001 前端和 3100 测试 API
├── tsconfig.json # TypeScript 配置
├── index.html # Vite HTML 入口
├── e2e/
│ ├── helpers.ts # E2E 真实 API 登录和造数工具
│ ├── audit-and-route-guards.spec.ts
│ ├── login.spec.ts
│ ├── report-permissions.spec.ts
│ ├── report-revision.spec.ts
│ └── personal-template.spec.ts
├── public/
│ ├── favicon.ico
│ └── logo_square.png
├── src/
│ ├── App.tsx # 路由表
│ ├── main.tsx # React 挂载入口
│ ├── index.css # 全局样式、Tailwind 主题和组件类
│ ├── types.ts # User/Report/Template/SystemSettings/FormField 等类型和默认配置
│ ├── api/
│ │ ├── audit.ts # 审计日志 API 封装
│ │ ├── client.ts # 前端 API client统一 envelope/错误/Cookie
│ │ ├── dashboard.ts # 工作台统计 API 封装
│ │ ├── reports.ts # 报告列表、详情、保存、删除 API 封装
│ │ ├── templates.ts # 模板列表、详情、保存、删除 API 封装
│ │ ├── users.ts # 用户、部门和模板授权 API 封装
│ │ ├── settings.ts # 系统设置 API 封装
│ │ ├── files.ts # 签名文件 API 封装
│ │ ├── library.ts # 字段库 API 封装
│ │ ├── ai.ts # AI 模型列表和对话代理 API 封装
│ │ ├── speech.ts # 讯飞语音 WebSocket 代理地址封装
│ │ └── client.test.ts
│ ├── auth/
│ │ ├── AuthContext.tsx # 登录态、login/logout/me、currentUser 兼容同步
│ │ ├── backendUser.ts # 后端安全用户 DTO 到前端 User 的映射
│ │ └── backendUser.test.ts
│ ├── config/
│ │ └── runtime.ts # 本地兼容回退开关
│ ├── components/
│ │ ├── Sidebar.tsx
│ │ └── Sidebar.test.tsx
│ ├── pages/
│ │ ├── Login.tsx # 登录和默认数据初始化
│ │ ├── AuditLogs.tsx # 审计日志查看
│ │ ├── Dashboard.tsx # 工作台统计和快捷入口
│ │ ├── ReportEditor.tsx # 核心报告编辑器、抽帧、AI、语音、保存
│ │ ├── ReportManage.tsx # 报告列表、筛选、历史、导出、删除
│ │ ├── ReportView.tsx # 报告查看和打印
│ │ ├── TemplateManage.tsx# 模板、字段库、图片资源、导入导出
│ │ ├── UserManage.tsx # 用户、角色、部门、模板权限、签名
│ │ ├── SystemSettings.tsx# 抽帧、AI、语音、默认模板设置
│ │ ├── Login.test.tsx
│ │ └── ReportManage.test.tsx
│ ├── utils/
│ │ ├── storage.ts # localStorage/sessionStorage 封装
│ │ ├── permissions.ts # 前端角色/报告/模板可见性判断
│ │ ├── defaultContent.ts # 默认手术记录 HTML 模板
│ │ ├── print.ts # iframe 打印工具
│ │ ├── storage.test.ts
│ │ ├── permissions.test.ts
│ │ ├── defaultContent.test.ts
│ │ └── print.test.ts
│ └── test/
│ └── setup.ts # Vitest/jsdom 全局 mock
├── server/
│ ├── prisma/
│ │ ├── schema.prisma # PostgreSQL 数据模型
│ │ └── seed.ts # 默认医院、部门和账号 seed
│ ├── src/
│ │ ├── main.ts # NestJS API 启动入口
│ │ ├── app.module.ts
│ │ ├── audit/ # 审计日志写入和查询 API
│ │ ├── auth/ # 登录、me、logout 接口
│ │ ├── dashboard/ # 工作台统计 API
│ │ ├── demo/ # 演示模式默认模板、AI 和语音配置
│ │ ├── reports/ # 报告 API、DTO、metadata 映射和测试
│ │ ├── templates/ # 模板 API、DTO、权限映射和测试
│ │ ├── users/ # 用户、部门和模板授权 API、DTO 映射和测试
│ │ ├── settings/ # 系统设置 API 和 schema 测试
│ │ ├── files/ # 签名文件上传和受控读取 API
│ │ ├── library/ # 字段库 API、schema 和测试
│ │ ├── ai/ # OpenAI 兼容模型列表和对话代理 API
│ │ ├── speech/ # 讯飞 IAT WebSocket 代理和帧处理测试
│ │ ├── health/ # GET /api/health
│ │ ├── permissions/ # 后端权限策略和测试
│ │ ├── prisma/ # PrismaService
│ │ └── session/ # express-session 的 Prisma Store
│ └── tsconfig.json
├── docs/
│ ├── README.md
│ ├── installation.md
│ ├── requirements.md
│ ├── design.md
│ ├── component-structure.md
│ ├── permissions.md
│ ├── api-contract.md
│ ├── features.md
│ ├── testing.md
│ ├── data-storage.md
│ ├── deployment.md
│ ├── security.md
│ ├── progress.md
│ ├── backendization-plan.md
│ └── modules/
│ ├── auth-and-users.md
│ ├── report-editor.md
│ ├── report-management.md
│ ├── template-management.md
│ └── system-settings.md
├── Dockerfile
├── Dockerfile.server
├── docker-compose.yaml
└── nginx.conf
```
`node_modules/``dist/` 是生成物或依赖目录,不应作为源码结构维护。
## 关键源码说明
### `src/types.ts`
定义核心数据结构:
- `User`
- `Report`
- `CapturedFrame`
- `Template`
- `SystemSettings`
- `AiProviderConfig`
- `XfSpeechConfig`
- `FormField`
也包含默认字段、默认 AI Provider 和默认讯飞配置。
### `src/utils/storage.ts`
封装浏览器存储。常规键使用 JSON`systemSettings` 做 XOR + Base64 混淆并兼容历史明文 JSON。注意这不是安全加密。
### `src/utils/permissions.ts`
集中封装当前前端权限判断。报告范围规则为:医生看本人报告,管理员看本部门报告,超级管理员和超时管理员看全部报告。模板范围规则为:超级管理员/超时管理员可见全部模板,医生和管理员可见本部门模板以及本人个人模板。
### `src/utils/defaultContent.ts`
默认报告模板 HTML。包含
- `.field-value[data-bind]` 智能字段
- `.image-placeholder` 图片占位符
- `.ai-region[data-ai-id]` AI 可编辑区域
### `src/pages/ReportEditor.tsx`
最大、最复杂的文件。包含:
- 报告表单状态
- `contentEditable` 富文本正文
- 字段双向同步
- 图片占位符填充
- 视频上传、自动抽帧、手动截帧
- AI 对话和 AI 区域改写
- 讯飞语音听写
- 草稿保存和恢复
- 报告保存、完成、历史记录
- 打印和导出
修改它时要非常小心,优先补测试或文档说明。
### `src/api/client.ts`
统一前端 API 请求封装:
- 默认请求相对路径 `/api/...`
- Vite 开发模式通过 `VITE_API_PROXY_TARGET` 代理 API默认 `http://localhost:3100`
- 请求带 `credentials: 'include'`,用于后端 HttpOnly Session Cookie。
- 解包后端 `{ data }` 响应,错误时抛出 `ApiError`
### `src/auth/AuthContext.tsx` 和 `src/auth/backendUser.ts`
前端认证入口。`AuthProvider` 提供 `login``logout``refresh`,并在登录或恢复会话后把后端用户同步成当前前端 `User`
- 后端 `doctor` 映射为前端 `user`
- 后端 `departmentName` 映射为前端 `department`
- 保留本地签名等迁移期字段;模板授权优先来自后端部门权限。
### `server/src`
后端第一阶段骨架。当前已实现健康检查、认证接口、报告 API、报告媒体关系、模板 API、字段库 API、用户/部门 API、设置 API、通用文件/签名文件 API、AI 代理、讯飞语音代理、PrismaService 和权限策略前端登录、报告、模板、字段库、模板图片资源、用户管理、系统设置、签名上传、AI 对话和语音听写已接入后端接口/代理。新增后端功能时优先按模块拆分:`auth``reports``templates``library``users``files``settings``ai``speech`
API 默认 JSON/urlencoded 请求体上限为 `100mb`,由 `API_BODY_LIMIT` 控制Nginx 同步配置了 `client_max_body_size 100m`,用于承载迁移期报告 HTML、图片/关键帧和通用文件 Data URL 上传。
### `server/prisma/schema.prisma`
PostgreSQL 数据模型。当前覆盖 `Tenant``Department``User``UserSession``AppSession``Report``ReportMedia``ReportHistory``Template`、模板部门授权、`FileResource``SystemSetting``AuditLog`。Prisma 7 连接配置在根目录 `prisma.config.ts` 中。
## 数据存储键
详见 `docs/data-storage.md`。常见键:
- `currentUser`
- `users`
- `templates`
- `reports`
- `systemSettings`
- `formFieldsConfig`
- `imageAssets`
- `customTimeFormats`
- `multiSelectOptions`
- `anesthesiaOptions`
- `reportEditorDraft_${username}`
- `sessionStorage.restore_${reportId}`
## 测试现状
当前测试覆盖:
- 登录默认初始化和后端禁用账号错误展示
- 前端 API client 响应/错误处理、Dashboard API 封装和语音代理地址生成
- 后端用户 DTO 到前端兼容用户映射
- 角色菜单过滤
- 报告管理按角色过滤
- 管理员本部门报告范围和医生本人报告范围
- 模板可用范围,含部门模板和医生个人模板
- Playwright E2E 通过真实后端 API seed 覆盖登录、报告权限、报告修订版本、医生个人模板、路由守卫和审计日志
- 后端权限策略覆盖报告、模板、用户管理和管理员创建规则
- 后端 Dashboard 统计按角色范围过滤
- 后端报告 metadata 兼容映射和 `ReportMedia` 视频/关键帧组装
- 后端报告 schema 区分草稿和完成状态,草稿可暂缺患者姓名/住院号,完成报告必须填写
- 后端模板 DTO 和权限资源映射
- 后端用户 DTO 和部门模板授权映射
- 后端系统设置 schema 校验
- 后端 AI 入参和讯飞语音代理帧处理
- 后端 HTTP 集成测试覆盖 API prefix、登录 session、受保护 API actor 传递
- 后端真实 PostgreSQL 集成测试覆盖 Auth、Dashboard、Reports、ReportMedia、Templates、Files、HTML 清洗、审计写入和审计查询权限
- 存储封装
- 默认模板结构和字段契约
- 打印入口
测试文档见 `docs/testing.md`
## 文档维护规则
如果改动功能、数据结构、脚本、部署、安全边界或测试:
- 更新对应 `docs/` 文档。
- 如功能真实性变化,更新 `docs/features.md`
- 如后端化方向变化,更新 `docs/backendization-plan.md`
- 如新增/修改测试,更新 `docs/testing.md`
- 如运行方式、端口、账号、部署变化,更新 `README.md`
## 开发注意事项
- 优先使用现有风格和现有工具,不要引入大框架替换,除非任务明确需要。
- 不要把前端权限当作安全边界。
- 不要继续扩大前端内置密钥的使用面。
- 不要把大量 Base64 图片或视频数据长期作为生产方案。
- 报告/模板 HTML 改动要考虑 XSS、打印样式、字段绑定和历史兼容。
- 当前 `document.execCommand` 虽然过时,但编辑器依赖它;替换编辑器需要单独规划。
- 生成物 `dist/` 和依赖目录 `node_modules/` 不要手工维护。