Files
silk/开发交接记录.md
T

664 lines
39 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.
# 开发交接记录
> **用途**:按 AGENTS.md 沟通规则,每完成一项交付(功能/模块/部署)后在此追加「做了什么、设计思路与决策依据、验证结果、回滚点」,供同事快速了解项目进展并接手。
> **阅读顺序**:时间倒序(最新在上);先看「当前状态与剩余事项」了解全局,再按需阅读各模块明细。
## 总体背景
- 项目:智慧蚕房环境监测与智能调控系统(monorepo:`server-go` / `web` / `miniapp` / `wvp`)。
- 《后续工作计划》(2026-08-11 更新)确定混合架构:现有 Go 底座 + Python AI 微服务(`ai-service/`,规划中);生产环境全部上云,本地仅开发/训练/测试。
- **YOLO 训练相关(计划 #1-4:数据集修复、训练环境、上传、基线训练)因物理机问题挂起**,当前按用户要求优先做「独立性强、见效快」的模块。
- 开发服务器:`100.83.103.1`Ubuntu 22.04,用户 `pan`),通过 NetBird VPN 访问;部署规则见 AGENTS.md「部署到开发服务器」章节。
---
## 2026-08-12 补充:Web 知识库图谱预览与保存修复(故障排查 #三十二)
### 做了什么
- 修复 Web 知识库「蚕病百科」两个问题:编辑页图谱预览打不开(CSP 拦截跨源 S3 图片)、提交后 `imageUrl` 未保存(表单未注册该字段)。
- `web/src/pages/Knowledge.tsx`:「症状图谱图片」后新增隐藏 `Form.Item name="imageUrl"`,保证 `form.validateFields()` 提交时携带图片 URL。
- `web/server.cjs`CSP `img-src` 放行 `http://100.83.103.1:7480`(开发 S3 源)。
- 已部署并重启前端(新 bundle `index-CSVEb7gG.js`),并按用户确认直接改库把白僵病已上传的图谱 URL 补绑到 `diseases.image_url`
### 思路与决策
- 根因定位:日志显示上传 200、PATCH 200,但 `image_url` 为空 → 定位为前端表单未注册 `imageUrl`antd `validateFields()` 只返回已注册字段),以及 CSP 跨源拦截预览。
- 修复方式:用隐藏 `Form.Item` 注册字段(antd 标准做法),避免手工拼请求体;CSP 采用放行开发 S3 源,生产切云 OSS/COS 时再替换为 OSS/CDN 域名或改同源代理。
- 数据补绑:用户明确选择「直接改库」,回滚点为备份的 `diseases` 表 dump 与逐行 UPDATE 反向语句。
### 验证
- `web``npm run lint` 通过(仅既有无关警告)、`npm run build` 通过。
- 机制红绿验证:用 rc-field-form 验证 `validateFields()` 会丢弃未注册的 `imageUrl`,注册/合并后可携带。
- 部署验证:`http://localhost:5174/` 200CSP 头含 `http://100.83.103.1:7480`;新 bundle 200`/api/v1/health` 200bundle 中可见 `name:"imageUrl", hidden:!0`
- 数据验证:`UPDATE 1`;查询确认白僵病 `image_url` 已绑定;图片匿名 GET 200image/jpeg)。
- API 冒烟:admin 登录成功,`GET /api/v1/knowledge/diseases` 返回白僵病 `imageUrl` 已绑定(密码不写入文档)。
### 回滚点
- 前端:`/home/pan/backups/web-20260812-1605/`(旧 dist、server.cjs、web.log)恢复后重启 node。
- 数据:`diseases` 表 dump `/home/pan/backups/diseases-20260812-1605.dump`;或执行 `UPDATE diseases SET image_url=NULL, updated_at=now() WHERE id='17b1cae4-21cc-4996-9db3-96f785aef800';`
## 2026-08-12 模块:知识库初始版(计划 #10)
### 做了什么
- 后端(server-go):
- 新增 `Disease`(蚕病百科)与 `KnowledgeArticle`(知识文章)两张表;
- 种子数据:9 个蚕病条目(4 类核心病种:核型多角体病、白僵病、软化病、微粒子病 + 5 个扩展病种)+ 1 篇 AI 结果解读,启动时幂等写入;
- CRUD API`/api/v1/knowledge/diseases``/api/v1/knowledge/articles`(列表支持 category/kind/keyword 过滤);
- 权限:新增 `knowledge:read` / `knowledge:write`admin/operator 可写,viewer/farmer 只读。
- Web:新增「知识库」菜单页(蚕病百科 + AI 结果解读双 Tab,可增删改)。
- 小程序:设置页新增「知识库」入口 → 列表页 → 详情页。
### 思路与决策
- 选择理由:知识库是规格书 P0、完全独立、不依赖 YOLO 训练产物,符合「独立性强、见效快」的推进原则。
- 内容来源:全部取自规格书《蚕病智能防控平台规格说明书》3.6(知识库模块)、3.1.4(风险分级阈值)、附录 11.1(蚕病参考信息)、3.8(处置方向/排查清单),不自行编造。
- 「防治指南」字段是按规格书 3.8 的处置方向(内源扩散/外源侵入措施)与分病种排查清单整理的加工内容,非原文逐字。
- 权限设计沿用现有 RBAC 权限码模式,管理端可编辑、农户端只读。
### 验证
- 种子数据完整性测试(TDD 红→绿):核心 4 病种齐全、必填字段非空、名称唯一、AI 解读存在;`go test/build/vet` 通过。
- Web `npm run lint && npm run build`、小程序 `npm run build:weapp` 通过。
- 部署后冒烟:登录 admin → `GET /api/v1/knowledge/diseases` 返回 9 条;`articles?kind=ai_guide` 返回 1 条;DB 计数 diseases=9 / articles=1。
### 部署与回滚
- 首次部署 2026-08-12;回滚点:DB dump `/home/pan/backups/silk-20260812-1111.dump`、旧二进制 `server-go-linux.bak`、旧 dist 打包;完整记录在服务器 `/home/pan/backups/rollback-20260812/README.md`
- 相关提交:`13df3d5`(实施计划)、`50dcd65`(测试 RED)、`8e30234`(种子数据)、`3afc34d`API/权限/迁移)、`b8af17d`Web)、`93aa4ee`(小程序)。
---
## 2026-08-12 补充:LAMP 操作教程(规格书 P0)
### 做了什么
- 后端:`lamp_guide` 种子文章(原理、适用场景、设备清单、5 步操作流程、结果判读、各病种检测靶标现状);
- 小程序:知识库列表增加「LAMP 教程」入口;修复详情页对非 disease 类型(如 lamp_guide)误走病种接口的问题;
- Web 无需改动(文章 Tab 已支持 `lamp_guide` 类型)。
### 思路与决策
- LAMP 教程是规格书 3.6 的 P0 项,且 LAMP 是「目前蚕业领域最务实的分子检测方案」(规格书 3.3.2.1),优先补齐;
- 内容全部取自规格书 3.3.2.1(含操作流程表、设备清单、病种靶标研究现状),无编造;
- 规格书要求「视频+图文」,当前先做图文,视频素材后续补充。
### 验证与回滚
- 新增存在性测试(TDD 红→绿),5 个种子测试全过;`build:weapp` 通过;二次部署后 `ai_guide=1``lamp_guide=1`API 冒烟返回教程内容。
- 相关提交:`0d3124f`(种子数据)、`8bb93ad`(小程序入口 + 类型判断修复);回滚见服务器 README(旧二进制 `server-go-linux.old-20260812-2`)。
---
## 2026-08-12 补充:症状图谱图片上传(规格书 P0)
### 做了什么
- 后端:`POST /api/v1/knowledge/images`multipart 字段 `file`,限 jpg/jpeg/png/webp、≤5MB,权限 `knowledge:write`),写入 S3 `silk-images` 桶,对象键 `knowledge/<日期>/<随机>.ext`,返回可公开访问的 URL
- 配置:新增 `S3_BUCKET_IMAGES`(默认 `silk-images`);
- Web:病种编辑表单增加「症状图谱图片」上传 + 预览;
- 小程序:病种详情页顶部展示症状图。
### 思路与决策
- 规格书只规定「蚕病百科要有症状图谱」和通用图片存储链路(对象存储 + CDN),没有规定图谱图片来源;采用「通用上传能力 + 后续多来源导入」策略,避免手动塞数据库;
- 素材来源三方向(后续):YOLO 训练数据集选图、专家/合作单位素材、巡检照片沉淀;
- 存储复用现有 S3 服务(开发 Ceph、生产云 OSS/COS 仅改配置);
- v1 先做「每病种一张主图」(单 `imageUrl`),多图图谱后续用子表扩展。
### 踩坑记录(重要)
- **Ceph 的 bucket 级 public-read 不覆盖对象读取**,必须给对象本身设置 public-read`PutObjectInput.ACL`),否则 Web/小程序无法直接展示图片;生产 OSS 同样注意桶策略或 CDN 配置。
- 服务器上运行中的二进制不能被 `cp` 覆盖(`text file busy`)→ 必须先 `mv` 旧文件再 `cp` 新文件。
### 验证与回滚
- 5 个单元测试(大小/扩展名/Content-Type/键生成)TDD 红→绿;三端构建通过;
- 部署冒烟:上传 1x1 PNG → URL 匿名 GET 200`image/png`)→ 病种 `imageUrl` 绑定成功(测试数据已清空);
- 相关提交:`c8aa213`(上传接口)、`3bb1efa`Web+小程序)、`7647705`(对象公开读修复);回滚见服务器 README(旧二进制 `server-go-linux.old-20260812-5`)。
---
## 2026-08-12 模块:饲养阶段风险提示(计划 #13)
### 做了什么
- 后端:新增 `GET /api/v1/knowledge/stage-hints?stage=young|grown|late5|pupa`(只读 GET,天然幂等),返回该阶段高发病种(含病种 id,可直接跳知识详情);不传 stage 返回全部;
- 种子数据:4 个阶段(小蚕期 young / 大蚕期 grown / 5龄后期 late5 / 蛹期 pupa)及其高发病种与原因;
- 小程序:知识库页新增「饲养阶段风险提示」区块——龄期选择器 + 提示卡片,点击病种跳详情。
### 思路与决策
- 选择理由:规格书 3.2.2 的 P1 项,独立、见效快,直接复用蚕病知识库;
- 内容来源:规格书附录 11.1 高发阶段 + 3.2.3 蚕病环境风险规则(如核型多角体病 5龄后期温度突变 >30℃/<20℃ 诱发),无编造;
- 幂等性:新增接口为只读 GET,天然幂等;后续新增写接口时按需实现幂等(如幂等键);
- v1 用选择器而非自动联动:自动按蚕房龄期提示需等「蚕匾/批次管理」(#7,含龄期记录)落地后接入;
- Web 端本次未加,保持快速交付,后续需要再补。
### 验证与回滚
- 5 个单元测试(阶段 key 合法、病种引用存在、按阶段过滤、未知阶段报错)TDD 红→绿;`go test/build/vet``build:weapp` 通过;
- 部署冒烟:`all=4` 阶段;`grown` 返回软化病 + 核型多角体病(含 id);`young` 返回曲霉病提示;未知阶段 400
- 相关提交:`6d9cfc7`(后端)、`6dc6c27`(小程序);回滚见服务器 README(旧二进制 `server-go-linux.old-20260812-6`)。
---
## 2026-08-12 补充:知识库其余内容(SERS 教程 / 四季防控提醒 / 「其它未知」病种)
### 做了什么
- 种子数据:`sers_guide` 教程(原理、适用场景、设备清单、4 步操作流程、与 LAMP 对比);`seasonal_tip` 春夏秋冬 4 篇防控要点;`diseases` 新增「其它/未知(不确定但有异常)」条目(AI 检出异常但无法归入已知病种时的引导,建议分子检测确认)。
- 小程序:知识库页教程区合并展示 AI/LAMP/SERS(按类型徽标);新增「季节性防控提醒」区块——当前季节高亮卡片 + 全部季节列表。
- Web 无需改动。
### 思路与决策
- 内容来源:SERS 取自规格书 3.3.2.2;季节提醒取自附录 11.1 季节性流行规律(春蚕期核型多角体病多发、夏秋高温闷热质型/浓核/软化病多发、湿度>75% 真菌病暴发、温湿度波动诱发潜伏感染);「其它/未知」对应规格书 AI 检测输出类别(3.1.3)。
- 季节匹配用文章标题前缀约定(春季/夏季/秋季/冬季),未新增 schema 字段,保持简单;后续如需按节气推送可扩展。
- 幂等性:均为种子数据,无新增写接口。
- 专家经验沉淀(P1)暂缓:依赖专家会诊(#18)功能落地后才能沉淀历史案例。
### 验证与回滚
- 种子测试共 10 个全过(新增 SERS/四季/其它未知 3 个用例,TDD 红→绿);三端验证通过;
- 部署冒烟:`sers=1``seasonal=4``diseases=10`(含 other 类别);
- 相关提交:`a5caa48`(后端种子)、`62fbbaf`(小程序);回滚见服务器 README(旧二进制 `server-go-linux.old-20260812-7`)。
---
## 2026-08-12 模块:AI 巡检闭环后端(计划 #5 + #6)
### 做了什么
- `ai-service/`FastAPI + ONNX Runtime 检测服务骨架(`GET /health``POST /detect` 返回框/类别/置信度)。默认 `MODEL_MODE=mock`MockDetector 返回固定结果并校验图片可解析);`ONNXDetector` 已实现 YOLOv8 常见输出格式解析(letterbox + NMS),训练恢复后放 `models/best.onnx` 即切真实推理,接口不变。
- Go 后端:AI client`AIClient.Detect`multipart 上传 + 超时/错误处理);`inspection_records` 表;`POST/GET /api/v1/inspections`——图片存 S3 `silk-images/inspections/` → 调 `/detect` → 写记录;`Idempotency-Key` 幂等;`roomId` 校验。
- 权限:`inspection:create` / `inspection:read`;配置 `AI_SERVICE_BASE`
### 思路与决策
- 按规格书 3.1:AI 服务只做检测(框/类别/置信度),**风险评分留在 Go 端**(#9 公式),职责单一;
- 幂等性:`/detect` 无状态天然幂等;`POST /inspections` 用客户端 `Idempotency-Key`(唯一索引)+ 并发冲突兜底,重试不会产生重复巡检记录;
- YOLO 训练挂起不阻塞:mock 模式先跑通端到端链路,模型就位后只改环境变量;
- 图片复用 `silk-images` 桶(`inspections/` 前缀),不新建桶;
- 踩坑记录:服务器缺 `python3.10-venv`(需 apt 安装);pip 直连慢,改用清华镜像;原 `.gitignore` 全局 `*.py` 规则会忽略 ai-service,已加例外。
### 验证与部署
- 本地:ai-service pytest 6/6Go 新增 AI client 3 用例 + UUID 校验用例,`go test/build/vet` 通过;
- 服务器:ai-service 部署 `/home/pan/ai-service`:8000mock`start.sh`),pytest 6/6health 200Go 第六次部署(schema 变更前 pg_dump `silk-20260812-1635.dump`);
- 冒烟:巡检创建 201mock healthy/0.95)→ 同 key 重试返回同记录 → 列表 → 图片 URL 200;非法 roomId 400(测试数据已清理);
- 相关提交:`99137a6``b89ad5e`ai-service + gitignore)、`210bd6c`(Go 对接);回滚见服务器 README(旧二进制 `server-go-linux.old-20260812-9`)。
### 说明
- 巡检风险分级(绿/黄/橙/红)与评分引擎属计划 #9,本期只落数据字段;
- 小程序拍照巡检 UI#8)下一轮再做。
---
## 2026-08-12 模块:小程序拍照巡检(计划 #8)
### 做了什么
- 新增 `pages/inspection/`:拍照/相册选图(压缩)→ 预览 → 上传 `POST /api/v1/inspections`multipart,自动生成 `Idempotency-Key` 防重复)→ 结果卡片(AI 类别 + 置信度 + 风险提示文案)→ 巡检历史列表(最近 10 条)。
- 设置页「监控管理」新增「拍照巡检」入口;`app.config.ts` 注册页面。
### 思路与决策
- 复用 #5/#6 已部署的后端接口,本期纯小程序端,无服务端改动;
- 上传用 `Taro.uploadFile`(不是通用 request 封装),因为需要文件流 + 自定义头(Authorization / Idempotency-Key);
- 幂等键客户端生成(时间戳 + 随机串),弱网重试不会重复创建巡检记录;
- 结果展示先按二分类(healthy/sick)映射,风险分级(绿/黄/橙/红)等 #9 评分引擎落地后接入;7 类病种扩展后补充类名映射。
### 验证
- `npm run build:weapp` 编译通过;后端接口此前已冒烟(创建→幂等重试→列表→图片 200)。
- 相关提交:`8274cc8`
---
## 2026-08-12 模块:风险评分引擎(计划 #9)
### 做了什么
- `risk.go`:评分公式(0.5/0.2/0.15/0.15 权重,0-100 钳制)、分级(绿/黄/橙/红)、阶段系数(Room.Stage 粗映射)、环境系数(湿度/温度规则,取自规格书 3.2.3)。
- 巡检创建(`POST /api/v1/inspections`)时自动计算:AI 置信度取检测结果最大值;带 `roomId` 时按房间阶段 + 最新温湿度算系数;结果写入 `risk_score` / `risk_level`
### 思路与决策
- 公式与分级阈值完全按规格书 3.1.4,不自行调整;
- 评分在 Go 端(AI 服务只做检测),保持职责单一;
- 环境系数 v1 用「最新一条温湿度」按规则打分(规格书 3.2.3 的连续 3 天判定留待后续);
- 整齐度偏离度暂无数据源(需蚕匾/批次管理 #7 后才有),本期恒为 0
- 阶段系数用 Room.Stage 粗映射,等 #7 龄期字段落地后细化。
### 验证与部署
- 5 个单元测试(TDD 红→绿);`go test/build/vet` 通过;
- 第七次部署:冒烟——带房间 57.5(yellow)、不带房间 47.5yellow);
- 相关提交:`93301f0`;回滚见服务器 README(旧二进制 `server-go-linux.old-20260812-10`)。
---
## 2026-08-12 模块:蚕匾/批次/饲养记录管理(计划 #7)
### 做了什么
- 后端:`trays` / `batches` / `rearing_records` 三表 + CRUD(按 roomId/batchId 过滤),批次删除级联删除饲养记录;权限 `tray/batch/rearing:read/write`
- Web:新增「批次管理」页——批次管理 Tab(含饲养记录弹窗)、蚕匾管理 Tab、按蚕房筛选。
- 小程序:蚕房详情页展示「蚕匾」与「当前批次」只读区块。
### 思路与决策
- 按规格书 3.5:蚕房→蚕匾→批次层级,饲养记录挂批次(品种/来源/龄期/桑叶/密度);
- 批次带 `instar`(龄期 1-5)与 `status`(饲养中/已上蔟/已结束),为 #9 阶段系数与 #13 自动风险提示预留数据源;
- CRUD 沿用现有 room.go 模式(bindUpdates、uuid 校验复用 `isUUID`);删除批次时级联删除饲养记录,避免孤儿数据;
- v1 范围外:消毒记录(P1)、蚕种来源全链(P2)、产量统计(P1)。
### 验证与部署
- 三端构建通过;第八次部署(schema 变更前 pg_dump `silk-20260812-1720.dump`);
- 冒烟:蚕匾/批次/饲养记录创建→列表→删除均 200,批次删除后饲养记录级联为 0;
- 相关提交:`362a70b`(后端)、`0a5e2b1`(Web+小程序);回滚见服务器 README。
---
## 2026-08-12 模块:微信订阅消息骨架(计划 #11)
### 做了什么
- 后端:`wechat_bindings` 表 + `/wechat/binding|bind|subscribe``WechatService`code2session、access_token 内存缓存、订阅消息发送);巡检风险非绿时异步触发(未配置/未授权静默跳过)。
- 小程序:「消息订阅」设置页(绑定、授权订阅、状态展示)。
### 思路与决策
- 按用户选择先做**骨架 + 环境变量占位**:`WECHAT_APPID/WECHAT_SECRET/WECHAT_TEMPLATE_*` 默认空,未配置时接口返回明确中文错误,触发逻辑静默跳过,不影响主流程;
- 微信订阅消息为一次性订阅:每次触发需用户先 `wx.requestSubscribeMessage` 授权,小程序端已实现授权流程,模板 ID 占位待替换;
- access_token 内存缓存(提前 60 秒过期),避免每次发送都换 token;
- 订阅消息 data 用 `thing1`(等级)/`thing2`(评分)占位字段,正式模板字段不同时改 `BuildSubscribeData`
### 验证与部署
- 微信服务 6 个单测(TDD 红→绿),`go test/build/vet` 通过;`build:weapp` 通过;
- 第九次部署(schema 变更前 pg_dump `silk-20260812-1730.dump`);冒烟:binding 未绑定、bind 返回「微信未配置」502、巡检触发不崩溃;
- 相关提交:`921b185`(后端)、`bdf0515`(小程序);回滚见服务器 README(旧二进制 `server-go-linux.old-20260812-12`)。
### 待办
- 提供 AppID/Secret + 订阅消息模板 ID,替换占位后联调真实推送;
- 告警产生时的推送触发点(当前只接了巡检)。
---
## 2026-08-12 模块:和风天气接入与高发病天气预警(计划 #12)
### 做了什么
- 后端:和风天气客户端(`/v7/weather/now` 实时 + `/v7/weather/3d` 预报);规则引擎(规格书 3.2.3);`weather_alerts` 表 + `/weather/now``/weather/alerts`;启动即评估一次 + 每 30 分钟定时写入。
- Web 告警中心与小程序告警页新增天气预警展示。
### 思路与决策
- 数据源按用户确认选用和风天气(QWeather,devapi 免费版);`location` 支持经纬度或 LocationID
- 未配置(`QWEATHER_API_KEY/LOCATION` 为空)时接口返回明确错误、定时任务跳过,不阻塞主流程(与微信骨架同一模式);
- 规则 v1:白僵病(湿度≥80% + 连续阴雨)、核型多角体病(温度突变,`stage=late5` 升级)、软化病(湿度>75% 提示);微粒子病依赖蚕种来源/消毒记录,待 #7 数据联动;
- 预警写入不按天去重(v1),前端只展示最近几条,后续可加去重策略。
### 验证与部署
- 规则/客户端 9 个单测(TDD 红→绿),三端构建通过;
- 第十次部署(schema 变更前 pg_dump `silk-20260812-1745.dump`);冒烟:`/weather/alerts=[]``/weather/now` 未配置 502 明确提示;
- 相关提交:`c7f18c1`(后端)、`c4fad42`(Web+小程序);回滚见服务器 README。
### 待办
- 提供和风天气 API Key 与默认位置后启用真实数据与定时预警;
- 微粒子病规则(蚕种来源标记 + 消毒记录缺失)待批次/消毒数据接入。
---
## 2026-08-12 模块:LAMP 检测管理(计划 #14)
### 做了什么
- 后端:`lamp_tests` / `lamp_test_steps` 表 + CRUD、步骤更新、结果照片上传(S3 `lamp/` 前缀)、结果录入(自动置 `resulted`);新建任务单自动生成标准 5 步。
- Web:LAMP 检测管理页(列表/新建/步骤/结果+照片)。
- 小程序:LAMP 检测页(技术员:步骤勾选、结果拍照、结果保存)。
- Web 构建:`manualChunks` 代码拆分(修复 rolldown WASM 内存超限)。
### 思路与决策
- 按规格书 3.3.2.1 固化 5 步流程,任务单创建时自动生成,避免人工漏步;
- 结果枚举(阳性/阴性/无效)与颜色判读提示(天蓝=阳性/紫罗兰=阴性)取自规格书;AI 图像判读模型训练未开始,v1 为人工录入 + 拍照留证,接口已为 AI 判读预留(后续在 ai-service 加端点);
- 结果录入通过 PATCH 的 `result` 字段触发状态流转(pending/testing → resulted + resultedAt),保证状态一致性;
- 删除任务单级联删除步骤。
### 验证与部署
- 步骤/结果枚举 2 个单测;三端构建通过(web 构建含代码拆分修复);
- 第十一次部署(schema 变更前 pg_dump `silk-20260812-1800.dump`);冒烟:创建→5 步→步骤完成→照片→resulted→列表→级联删除全 200
- 相关提交:`c6e5a76`(后端)、`d626f9d`(Web+小程序+构建拆分);回滚见服务器 README。
---
## 2026-08-12 模块:交叉验证 AI vs LAMP(计划 #15
### 做了什么
- `CrossValidate` 纯逻辑 + `AIClassFromDetections`;LAMP 结果录入后自动与同房间最近巡检比对并回写 `cross_status/cross_reason``GET /lamp-tests/:id/cross-validation` 详情接口;Web/小程序展示比对结论。
### 思路与决策
- 按规格书:一致 → 确认诊断;不一致 → 升级专家会诊;
- 关联策略:同房间最近一条巡检记录(v1),后续可按批次/时间窗细化;
- 无关联巡检或 LAMP 判读无效时置「不一致/待确认」并给出原因,避免静默;
- 交叉验证在结果落库后执行,保证读取到最新 result。
### 验证与部署
- 2 组单测(矩阵 + AI 归纳,TDD 红→绿);三端构建通过;
- 第十二次部署(schema 变更前 pg_dump `silk-20260812-1815.dump`);冒烟:negative→consistent、positive→inconsistentAI 健康 + LAMP 阳性→建议会诊);
- 相关提交:`1798b29`;回滚见服务器 README。
---
## 2026-08-12 模块:耗材管理(计划 #16)
### 做了什么
- 后端:`consumables` 表 + CRUD、`/consumables/alerts`(低库存/临期 30 天)、`/consumables/purchase-suggestions`;模型方法 `LowStockAlert/ExpiringAlert/PurchaseSuggestion`
- Web:耗材管理页(列表 + 预警 + 采购建议)。
### 思路与决策
- 阈值语义:`quantity < min_quantity` 才预警(等于不预警);采购建议 = 补足到安全阈值(向上取整),避免小数库存;
- 效期预警窗口 30 天(含已过期),临期与过期统一 `expiring` 类型;
- 规则放模型层方法,纯逻辑可单测;
- 小程序端按方案暂不做,等技术员 Web 后台(#17)统一规划。
### 验证与部署
- 3 个单测(TDD 红→绿);三端构建通过;
- 第十三次部署(schema 变更前 pg_dump `silk-20260812-1830.dump`);冒烟:低库存→low_stock + 建议 7、临期→expiring
- 相关提交:`65c993a`(后端)、`716e5e9`(Web);回滚见服务器 README。
---
## 2026-08-12 模块:技术员巡检记录页(计划 #17)
### 做了什么
- 后端:`GET /inspections` 返回 `roomName` 联查;
- Web:「巡检记录」页(列表 + 详情抽屉:原图、检测框/置信度、风险分与等级)。
### 思路与决策
- #17 的检测任务处理(#14)与耗材(#16)已在 Web 落地,本期补齐「巡检复查」入口,使技术员后台闭环;
- 详情用抽屉而非独立页,复用列表数据,减少接口调用;
- `roomName` 用非持久化字段在查询时联查,不改变表结构。
### 验证与部署
- 三端构建通过;第十四次部署;冒烟:列表 roomName=蚕房1#、detections=1
- 相关提交:`42ff238`;回滚见服务器 README。
### 阶段二小结
- 环境监测 + LAMP + 技术员后台(#12 天气、#13 阶段提示、#14 LAMP、#15 交叉验证、#16 耗材、#17 技术员后台)全部落地。
---
## 2026-08-12 模块:专家会诊(计划 #18)
### 做了什么
- 后端:`consultations` 表 + CRUD、受理/出方案/归档接口;关联 LAMP 任务创建时自动打包病例快照(房间名/巡检/LAMP/批次/天气预警 jsonb,避免引用漂移);状态流转校验。
- Web:专家会诊页(列表、病例快照详情抽屉、受理/出方案/归档)。
### 思路与决策
- 快照用 jsonb 固化:会诊时打包当时的数据,后续巡检/检测变化不影响历史病例;
- 触发来源:LAMP 交叉验证不一致可一键发起(传 `lampTestId` 自动带快照);巡检红/橙手动发起(本期不做自动);
- 状态机显式校验,非法流转直接 400;
- 专家角色当前由 admin/operator 承担(系统角色未扩展专家,规格书 2.4 的专家端暂以 Web 管理员操作);出方案后微信订阅消息触发点待 #11 凭证到位后接入。
### 验证与部署
- 状态流转 + 快照序列化 2 组单测(TDD 红→绿);三端构建通过;
- 第十五次部署(schema 变更前 pg_dump `silk-20260812-1845.dump`);冒烟:创建(快照含 lamp+inspection+roomName)→受理→出方案→归档全通过;
- 相关提交:`bf734c1`(后端)、`12a8964`(Web);回滚见服务器 README。
---
## 2026-08-12 模块:分子检测扩展(计划 #19)
### 做了什么
- `lamp_tests` 增加 `method/extra_data`qPCR Ct 自动判读(`JudgeQPCR`,阈值可配);SERS 光谱数据上传(S3 `spectrum/`);`spectrum_entries` 光谱库(CRUD + 上传);高光谱 `hyperspectral` 预留。
- Web:分子检测页(方式选择、qPCR 判读、SERS 上传)+ 光谱库 Tab;小程序展示方式。
### 思路与决策
- 按规格书 3.3「检测方式可插拔」:不重建表,扩展现有检测任务表(method + extra_data),保持 #14/#15/#18 关联不变;
- qPCR 判读规则用通用阈值(默认 Ct<35 阳性)且阈值可配,判读原因落 extraData 便于追溯;
- SERS 光谱先做「数据回传 + 光谱库框架」,比对/识别算法待光谱数据库积累后接入(ai-service 预留);
- 高光谱本期只留方法位,等检测数据标准。
### 验证与部署
- `JudgeQPCR`/光谱校验/`buildDataKey` 3 组单测(TDD 红→绿);三端构建通过;
- 第十六次部署(schema 变更前 pg_dump `silk-20260812-1900.dump`);冒烟:qPCR Ct[32,38]→positive、SERS 光谱 URL、光谱库增查删;
- 相关提交:`7bb87dd`(后端)、`3cd1b82`(Web+小程序);回滚见服务器 README。
---
## 2026-08-12 模块:多检测方式推荐引擎(计划 #20)
### 做了什么
- `RecommendMethod` 纯逻辑 + `GET /detection-methods/recommend`;Web 分子检测新建弹窗内置推荐工具。
### 思路与决策
- 规则量化自规格书 3.3.2/11.2(时间/成本/难度);加权评分:常规平衡 3/4/3,紧急与最快提高时间权重,新手提高难度权重,低成本提高成本权重;
- 高光谱「理论可行待验证」:有其他方式时不推荐,仅有高光谱时才给出并注明;
- 纯计算接口无 DB 依赖,便于前端即时交互与后续扩展(如按批次/房间数据自动带参)。
### 验证与部署
- 6 个推荐矩阵单测(TDD 红→绿);三端构建通过;
- 第十七次部署(无 schema 变更);冒烟:low_cost→LAMP、fastest→SERS、紧急无 SERS→LAMP、仅高光谱→待验证提示;
- 相关提交:`47a2da3`;回滚见服务器 README。
---
## 2026-08-12 模块:疫病溯源(计划 #21)
### 做了什么
- `trace_records` 表 + CRUD;一级自动溯源(环境回溯/历史关联/传播推断 → 初报 + 来源判定);二级分病种排查清单(规格书 3.8.3)→ 分析报告;三级专家/实验室备注;Web 溯源页。
### 思路与决策
- 按规格书 3.8 三级架构:一级自动(数据聚合 + 规则)、二级人工排查(清单作答统计内源/外源倾向 + 置信度)、三级专业记录(字段预留);
- 环境回溯 v1 用房间最近温湿度样本(≥80% 高湿 / >30℃ 或 <20℃ 温度突变);连续多日判定待数据积累后细化;
- 历史关联用同房间同病种 resulted LAMP 记录(JSONB `@>` 匹配),90 天窗口;
- 清单答案统计:内源倾向项答「是」计内源分,「否」计外源分,反向亦然,未答计未知;结论附置信度;
- 区域关联(同乡镇)留待 #22 热力图数据接入。
### 验证与部署
- 5 组溯源规则单测(TDD 红→绿);三端构建通过;
- 第十八次部署(schema 变更前 pg_dump `silk-20260812-1920.dump`);冒烟:创建→清单 4 项→auto(reported/内源/0.6)→清单提交(analysis/0.725);
- 相关提交:`dc97d1c`(后端)、`5ce99ab`(Web);回滚见服务器 README。
---
## 2026-08-13 模块:区域发病统计(计划 #22)
### 做了什么
- `rooms.region` 字段 + `GET /trace-records/region-stats`(近 N 天按区域聚合);Web 溯源页顶部柱状图 + 病种饼图;蚕房表单区域字段。
### 思路与决策
- 区域数据由蚕房管理录入(不自动解析位置字符串,避免误判);
- v1 用 ECharts 统计图表表达热力趋势;真正乡镇/县级地图(GeoJSON 底图 + 坐标)需要地图服务或离线数据,后续按需接入;
- 聚合纯逻辑独立(分组/降序/空区域剔除),便于单测与前端复用。
### 验证与部署
- 2 组聚合单测(TDD 红→绿);三端构建通过;
- 2026-08-13 第一次部署(schema 变更前 pg_dump `silk-20260813-0010.dump`);冒烟:SmokeTown total=2、DiseaseA/B 各 1
- 相关提交:`7949f90`(后端)、`9c5af92`(Web);回滚见服务器 README。
---
## 2026-08-13 模块:蚕房健康画像与年度发病统计(计划 #24)
### 做了什么
- `/health-profiles/:roomId`(巡检/LAMP/事件聚合 → 健康分 + 评级);`/trace-records/monthly-stats`(年度按月发病);Web 蚕房「健康画像」抽屉 + 溯源页年度折线图。
### 思路与决策
- 健康分扣分制:红 -25/橙 -12/黄 -4、LAMP 阳性率 -30、会诊 -10、溯源 -8,钳制 0-100;评级 优≥85/良≥70/中≥55/差;
- 月度聚合复用 trace_records(发病事件)按 `to_char(created_at,'YYYY-MM')` 分组;
- 踩坑记录(重要):Gin 不允许在 `:id` 参数节点下再挂子路由(`/rooms/:id/health-profile``/rooms/:id` 冲突 panic)→ 独立路径;同名路由注册函数重复注册会 panic;用 `apply_patch` 新增文件时若文件已存在会覆盖旧文件(原 `health.go``/health` 路由被覆盖,已恢复);handler 读取路由参数必须与 `:param` 命名一致。
### 验证与部署
- 3 组单测(TDD 红→绿);三端构建通过;
- 2026-08-13 第二次发布(含 4 处修复);冒烟:蚕房1# score=96 优(risk 黄 1);
- 相关提交:`cbcb22e`/`ccda60e`(功能)、`725d98a`/`492d1ef`/`3e9916a`/`008a7b1`(修复);回滚见服务器 README。
---
## 2026-08-13 模块:Web 测试基建(计划 #27)
### 做了什么
- Web 引入 Vitestjsdom),`npm test` 命令;`utils/format.ts` 公共函数 + 3 个单测;巡检页接入公共函数。
### 思路与决策
- 测试基建先搭最小可用(vitest + jsdom),纯函数优先测试(TDD 红→绿),组件测试等后续按需补;
- 抽取内联映射为公共函数,既便于复用也给了首批可测单元;
- Go 侧测试骨架此前已随各模块建立(model/service/handler 均有单测)。
### 验证与部署
- `npm test` 3/3、lint、build 全过;无后端/schema 变更,Web 已同步部署;
- 相关提交:`0e6dc00`;回滚见服务器 READMEweb `dist.old-20260813-4`)。
---
## 2026-08-13 模块:ai-service 扩展(#23 骨架 + #26
### 做了什么
- `POST /stream-detect`:OpenCV 拉流抽帧(3 帧)→ 检测,返回帧数与检测列表(骨架,未接正式巡检编排);
- `GET /metrics`:模型模式/uptime/请求数/平均延迟 + nvidia-smi GPU 信息。
### 思路与决策
- #23 按计划二期,本期只做能力骨架:接口形态先定(url → 抽帧检测),视角数据与巡检任务编排待补;
- #26 监控先做服务级指标 + GPU 可选采集(nvidia-smi 存在即读,不存在返回 null),不依赖具体 GPU 型号;
- 顺带发现:开发服务器经 nvidia-smi 可读到 NVIDIA 940MX 2GB,说明本地非 T4 环境也能做基础 GPU 监控。
### 验证与部署
- pytest 8/8TDD 红→绿);ai-service 更新至开发服务器;
- 冒烟:health okmetrics 返回 GPU 信息;stream 无 url 被拒(400/422);
- 相关提交:`156b670`;回滚:ai-service 源码 git 恢复 + 重启 start.sh。
---
## 2026-08-13 决策:时序存储(计划 #25)
### 结论
MVP 沿用 IoTDB(现状);TDengine 作为生产规模化候选(先基准测试再评估)。
### 思路与依据
- IoTDB 已部署运行、代码已接入且带 PostgreSQL 降级兜底;当前量级无性能瓶颈;
- TDengine 优势(标准 SQL/聚合快/生态活跃)主要在后续复杂分析报表阶段体现,换入需承担迁移与运维成本;
- 规格书 5.2 倾向 TDengine,但《后续工作计划》本身标注「不阻塞 MVP」,属可延后决策。
### 后续触发条件
聚合报表/BI 需求复杂化、单机性能瓶颈、生产上云规划时 → 做同数据量基准测试(吞吐/延迟/成本/许可)再定;若切换采用「双写灰度 + 数据对账」迁移,并重写时序读写层。
---
## 2026-08-13 文档同步:README 与后续工作计划
### 做了什么
- `README.md`:补充已完成功能的核心能力章节(1.8-1.17)、权限码数量(36)、技术栈(Go 1.23 / FastAPI+ONNX+OpenCV / Vitest)、目录结构(ai-service)、后端模块表(12 个新模块)、环境变量表(S3_BUCKET_IMAGES、AI_SERVICE_BASE、WECHAT_*、QWEATHER_*)、本地开发命令(npm test)。
- `后续工作计划.md`:按实际完成状态勾选 #5-#24#27#23/#26 标为骨架完成,#1-4 标注「挂起:物理机问题」,顶部加完成状态说明。
### 思路
- 说明文档(README)与进度文档(后续工作计划)长期未随功能迭代更新,本次一次性同步到 2026-08-13 状态;
- 详细设计/验证/回滚仍以 `开发交接记录.md` / `变更记录.md` 为准,README 只做概览。
### 相关提交
`待提交`(README、后续工作计划、变更记录、开发交接记录)。
---
## 2026-08-13 文档同步(第二轮):README / 部署指南 / 故障排查
### 做了什么
- README:API 概览表补 12 组新接口;权限矩阵补 20 个新权限码;新增 12.6 ai-service 本地开发、12.7 开发服务器部署摘要。
- 部署指南(物理机):架构图补 ai-service:8000;新增「13. 部署 ai-service」章节。
- 故障排查处理记录:追加 8 类近期踩坑(NetBird 登录过期/隧道闪断、pip 国内源、rolldown WASM 内存、ETXTBSY、Gin 路由冲突/重复注册/文件覆盖/参数名、PowerShell 中文 JSON、tar 时间戳、SSH 命令后台化)。
### 说明
- 文档按「现状可用」原则更新,详细命令与回滚以 `开发交接记录.md` / 服务器 README 为准。
### 相关提交
`README.md``部署指南(物理机).md``故障排查处理记录.md``变更记录.md``开发交接记录.md`
---
## 环境与踩坑备忘(新同事必读)
- **VPN**:开发服务器经 NetBird 访问;服务 Running 后需 `netbird up`,登录走 SSO(管理端 `115.191.19.95:6680`)。
- **npm**:本机 npm 12 默认禁止 remote tarball,安装需 `npm install --allow-remote=all`miniapp 因 webpack 版本冲突需再加 `--legacy-peer-deps`(不改 package.json)。
- **服务器代码形态**:开发服务器**没有 silk 主仓库 git**(仅有 wvp-src),代码回滚以「文件备份 + 本地 commit」为准;部署前必做 pg_dump(涉及 schema 变更时)并保留旧二进制/旧 dist。
- **服务启动**:后端 `start.sh`(导出环境变量后 nohup 启动);注意 `start.sh``WVP_API_BASE=18978` 与当前 WVP 实际端口 `18080` 不一致(既有问题,未修)。
- **数据库**:服务器 PostgreSQL 实际为 **14**(部署指南写 16,以实际为准);库名 `silk`,用户 postgres;默认管理员 `admin / silk@123`README/config 默认值,部署指南里的 admin123 已过时)。
- **部署流程与回滚命令**:见 AGENTS.md「部署到开发服务器」章节与服务器 `/home/pan/backups/rollback-20260812/README.md`
---
## 当前状态与剩余事项
### 知识库(#10)内部剩余
- ~~SERS 操作教程(P1)~~、~~季节性防控提醒(P2)~~、~~「其它/未知」类别~~:已于 2026-08-12 完成;
- 专家经验沉淀(P1):依赖专家会诊(#18)落地后沉淀历史案例,暂缓;
- 多图图谱(每病种多张)待扩展;
- 图谱图片素材等待三个方向(数据集/专家/巡检)导入。
### 下一候选模块(方案已给出、待用户确认)
- ~~饲养阶段风险提示(#13~~:已于 2026-08-12 完成(见上方模块记录)。
### 计划中的其他模块(按《后续工作计划》)
- AI 巡检闭环:#5 ai-service、#6 Go 对接、#7 蚕匾/批次管理、#8 拍照巡检、#9 风险评分引擎、#11 推送;
- 环境监测 + LAMP#12 天气接入、#14 LAMP 检测管理、#15 交叉验证、#16 耗材管理、#17 技术员后台;
- 专家诊断 + 溯源:#18 专家会诊、#19 qPCR/SERS/高光谱、#21 疫病溯源、#22 区域热力图、#23 摄像头流巡检;
- 数据分析与运维:#24 健康画像、#25 时序存储决策、#26 GPU 监控、#27 测试基建。