# 小脉健康项目交接报告（2026-07-17）

## 1. 本轮工作范围

本轮工作集中在以下三项：

1. 对医生端和管理员端进行患者端风格的轻量统一。
2. 检查并修复医生、登录账号、医生资料之间的同步逻辑。
3. 进行源码级逻辑检查和小范围自动化验证。

本轮没有生成 APK、没有进行真机或截图测试、没有启动 Web API、没有部署、没有推送远程代码，也没有修改真实数据库数据。

## 2. 医生端与管理员端 UI 改造

### 2.1 共用视觉层

新增后台共用展示组件：

- `health_app/lib/widgets/backoffice_ui.dart`
- `health_app/lib/utils/backoffice_formatters.dart`
- `health_app/lib/providers/backoffice_refresh_providers.dart`

统一内容包括：

- 使用患者端现有的紫蓝渐变和浅色页面背景。
- 使用白色圆角卡片、轻边框和统一阴影。
- 统一加载、空数据、加载失败和重试状态。
- 统一管理员端、医生端侧边栏的选中态。
- 对空姓名头像和不完整时间字符串进行安全展示。

### 2.2 医生端

已覆盖的主要页面：

- 工作台
- 患者列表与患者详情
- 问诊列表
- 报告列表与报告详情
- 随访列表与新增/编辑随访
- 医生资料
- 医生设置
- 医生侧边栏

已修复的页面问题：

- “新建随访”以前会被路由器当成缺少 ID 的详情页，现在可以正常进入新建模式。
- 新增或编辑随访后，返回列表会自动刷新。
- 随访和报告日期不再直接强制截取 16 个字符，避免空值或短字符串导致 `RangeError`。
- 空患者姓名不再因为直接读取第一个字符而导致崩溃。
- 患者列表加载失败后不再反复自动请求。
- 医生资料页面重建时不再反复覆盖用户正在编辑的输入内容。
- 停用医生登录后，工作台显示“账号已停用，新患者暂时无法选择您”的提示。

### 2.3 管理员端

已覆盖的主要页面：

- 医生管理
- 患者管理
- 新增医生
- 编辑医生
- 管理员侧边栏

已修复的页面问题：

- 管理员接口失败时不再无限显示加载状态。
- 医生列表增加“编辑”入口，复用新增医生表单。
- 新增或编辑医生后，返回列表会自动刷新。
- 停用和删除失败时显示后端返回的具体原因，不再静默失败。
- 删除确认文案改为安全规则：有绑定患者或问诊记录时只能停用，不能删除。
- 停用医生在管理员列表中继续显示“已停用”状态。

## 3. 医生账号三层数据同步

医生相关数据由以下三部分组成：

- `Doctor`：患者选择、医生展示和业务归属。
- `User(Role=Doctor)`：医生登录账号。
- `DoctorProfile`：医生端资料和医生实体关联。

本轮修改了 `backend/src/Health.Infrastructure/Admin/AdminService.cs`，规则如下。

### 3.1 新增医生

- 一次性创建 `Doctor`、医生登录 `User` 和 `DoctorProfile`。
- 三者使用相同的手机号和姓名，并建立正确 ID 关联。
- 手机号已被患者、医生或其他账号使用时拒绝新增。

### 3.2 编辑医生

- 手机号同步更新 `Doctor` 和登录 `User`。
- 姓名同步更新 `Doctor`、登录 `User` 和 `DoctorProfile`。
- 职称、科室同步更新 `Doctor` 和 `DoctorProfile`。
- 专业方向更新到 `Doctor`。
- 修改手机号前检查其他账号和医生是否已经占用。
- 医生登录资料缺失时拒绝局部修改，避免继续扩大不一致数据。

### 3.3 停用医生

- 同步更新 `Doctor.IsActive` 和 `DoctorProfile.IsActive`。
- 医生登录账号保持 `Role=Doctor`，仍可正常登录并服务已绑定患者。
- 患者与医生的原有绑定关系保持不变。
- 公开医生列表原本已经只查询 `Doctor.IsActive == true`，因此新患者注册时不会再看到已停用医生。
- 注册接口原本已经再次校验医生必须有效且启用。

### 3.4 删除医生

- 医生仍有绑定患者时拒绝删除。
- 医生已有问诊记录时拒绝删除。
- 无绑定患者和问诊记录时，删除 `Doctor`、对应登录 `User`、`DoctorProfile` 和刷新令牌。
- 有历史数据的医生应使用“停用”，不应通过物理删除清理。

## 4. 自动化验证

本轮最终验证结果：

- `flutter analyze`：通过，零问题。
- 后端 `Health.Tests`：56 项通过，0 项失败，0 项跳过。
- 医生/管理员 UI、路由和刷新相关测试：通过。

新增或更新的测试包括：

- `backend/tests/Health.Tests/admin_service_tests.cs`
- `health_app/test/backoffice_ui_test.dart`
- `health_app/test/backoffice_formatters_test.dart`
- `health_app/test/backoffice_refresh_test.dart`
- `health_app/test/app_router_test.dart`

说明：`dotnet test` 会自动编译测试程序集，但本轮没有执行发布构建，没有生成 Android APK/AAB，也没有执行 iOS 构建。

## 5. 数据库核对结果

本轮只进行了只读连接检查，没有修改数据库。

- 项目本地配置指向 `localhost:5432 / health_manager`。
- 本机 PostgreSQL 没有运行，因此无法读取本地实际数据。
- 开发 API `http://10.4.237.12:5000` 当前无法连接。
- 正式 API `https://erpapi.datalumina.cn/xiaomai/api/doctors` 可以访问，但公开接口返回的启用医生数量为 0。
- 交接资料显示正式数据库和备份方案尚未最终配置。

因此目前无法确认数据库中是否已经存在以下旧数据问题：

- `Doctor` 存在但没有医生登录 `User`。
- `DoctorProfile` 缺失或关联错误。
- 三层手机号、姓名或启用状态不一致。
- 重复医生手机号。
- 患者 `DoctorId` 指向不存在的医生。

新代码可以防止以后继续产生这些不一致，但不会自动修改已有数据。获得生产 PostgreSQL 只读连接或实际数据库备份后，应单独执行数据核对。

## 6. 仍未解决的高优先级问题

### P0：固定管理员验证码

`backend/src/Health.Infrastructure/Auth/AuthService.cs` 仍保留固定管理员手机号和固定验证码 `000000`。上线前必须移除，管理员需要使用受控的创建和认证方式。

### P0：短信服务仍是开发实现

`backend/src/Health.Infrastructure/Services/sms_service.cs` 只向服务端控制台输出验证码，没有接入真实短信服务。生产环境不会把验证码返回 App，因此普通用户无法正常接收验证码。

### P0：问诊 SignalR Hub 未鉴权

`backend/src/Health.WebApi/Hubs/ConsultationHub.cs` 没有强制 JWT 身份验证，也没有校验用户或医生是否属于指定问诊。调用者可以传入 `senderType` 和 `senderName`，存在加入其他问诊、伪造医生消息和写入数据库的风险。

### P1：医生聊天错误复用患者聊天流程

医生问诊列表进入的 `DoctorChatPage` 复用了患者端 `consultationChatProvider`：

- 把问诊 ID 当成医生 ID。
- 调用患者配额接口。
- 尝试创建新问诊。
- 发送消息时使用患者身份。
- 医生需要回复的 `WaitingDoctor` 状态反而不能发送。

医生实时问诊目前不能视为可用功能。需要拆分独立医生聊天 Provider 和页面，并与 Hub 鉴权一起处理。

### P1：AI SSE 鉴权和上传文件隐私

此前检查发现：

- AI SSE 接口允许从 query token 中直接读取 JWT claims，没有完整验证签名、签发者、受众和有效期。
- 上传的医疗图片和报告通过 `/uploads` 静态公开访问。
- 附件本地路径解析缺少完整的目录边界和文件归属校验。
- CORS 当前允许任意来源并携带凭据。

这些问题应在正式上线前统一修复。

### P1：iOS 蓝牙流程仍需修复和真机验证

此前检查发现 iOS 页面仍请求 Android 风格蓝牙权限，并调用仅 Android 支持的 `FlutterBluePlus.turnOn()`。iOS Pods 也需要在 macOS 上重新安装并验证。当前 Windows 环境不能证明 iOS 构建和真机蓝牙可用。

## 7. Apple 医疗硬件审核准备

如果首版明确只支持欧姆龙 J735，建议准备：

- J735 当前有效的医疗器械注册或批准材料。
- 小脉健康 App 与 J735 的联调测试报告。
- 真实 iPhone、J735 和当前版本 App 的完整配对及测量演示视频。
- App、审核说明、兼容设备清单和宣传文案全部明确首版支持范围。

注册证只能证明血压计本身合规，不能替代 App 与硬件联调测试报告和演示视频。

## 8. 建议后续顺序

1. 修复固定管理员验证码并接入正式短信服务。
2. 拆分医生聊天流程并为 SignalR Hub 增加 JWT、角色和问诊归属校验。
3. 修复 AI SSE 鉴权、上传文件访问控制、路径边界和 CORS。
4. 获得真实数据库只读连接，核对并修复旧医生账号数据。
5. 在 macOS 和真实 iPhone 上修复并验证 iOS 蓝牙流程。
6. 准备 J735 监管材料、联调报告和真实设备演示视频。
7. 完成正式服务器、数据库、短信、对象存储、域名和 HTTPS 配置后，再进入发布构建和应用商店提交。

## 9. 当前操作边界

- 本轮代码修改和本交接报告均未进行新的 Git 提交或远程推送。
- 没有执行数据库迁移。
- 没有写入、更新或删除真实数据库数据。
- 没有生成或上传发布安装包。
- 没有启动需要额外关闭的前端或后端常驻服务。
