Files
Mdeical_Sur_Report/工程分析/经验记录.md

73 lines
3.8 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.
# 经验记录
> 本文档用于沉淀项目修改过程中遇到的关键问题及解决方案。
> 每次执行工作流 Step 5 后,按四段式追加新记录。
> 执行修改前必须阅读本文档,避免重复踩坑。
---
## 记录格式
```markdown
## [{Year}-{Mon}-{Day}-{Hour}-{Min}-{Sec}] 问题简述
### A. 具体问题
(描述遇到的现象或错误)
### B. 产生问题原因
(根因分析)
### C. 解决问题方案
(具体的解决步骤或代码改动)
### D. 后续如何避免问题
(预防措施、规范建议、检查清单项)
```
---
## 历史记录
### [2026-04-20-10-14-09] Web Crypto API 异步性与 storage 同步接口冲突
### A. 具体问题
需求要求将 `systemSettings` 的加密从 XOR 升级为 Web Crypto API AES-GCM同时维持 `storage.get/set` 的同步调用签名。但 `crypto.subtle` 的所有加解密操作均为异步 Promise若直接将 `storage.get/set` 改为 async将导致 ReportEditor.tsx、Login.tsx 等数十处调用点需要同步改为 await改动面极大且风险不可控。
### B. 产生问题原因
Web Crypto API 是浏览器原生标准,设计为全异步 API无法像 crypto-js 那样提供同步调用。而项目早期设计时 `storage` 模块全部为同步接口,未预留异步扩展点。
### C. 解决问题方案
采用"启动时预解密 + 内存缓存"的折中方案:
1.`storage.ts` 中新增异步 `init()` 函数,在应用启动(`main.tsx``await storage.init()`)时预解密 `systemSettings` 到模块级内存缓存 `systemSettingsCache`
2. `storage.get('systemSettings')` 改为从缓存同步返回,`storage.set('systemSettings')` 改为更新缓存并触发异步持久化(不阻塞调用方)。
3. 其他 key 的读写保持原样,完全不受影响。
4. 该方案无需修改任何业务组件中 `storage.get('systemSettings')` 的调用方式。
### D. 后续如何避免问题
- 若未来再次遇到"必须引入异步存储操作"的需求,优先评估能否用"启动预加载 + 内存缓存"模式规避接口签名变更。
- 若必须改异步接口,应将影响范围限制在单一 key如新增 `getAsync/setAsync`),而非全局改动 `storage.get/set`
- 在需求分析阶段增加"接口兼容性影响评估"子项,提前识别同步/异步冲突。
---
### [2026-04-20-10-14-09] 旧数据兼容密钥与"消除硬编码"验收标准冲突
### A. 具体问题
安全加固的验收标准要求"构建产物中不再出现任何硬编码密钥字符串"。但实现 AES-GCM 迁移时,必须保留旧 XOR 密钥 `MedicalReportSys2024` 才能解密历史 localStorage 中的 `systemSettings` 数据。首次修改后构建产物扫描发现该字符串仍然存在。
### B. 产生问题原因
数据迁移需求(兼容旧 XOR 密文)与安全需求(消除硬编码密钥)表面上互斥。根源在于旧密钥是以明文常量形式写死在源码中的,构建产物必然包含该字符串。
### C. 解决问题方案
将旧 XOR 密钥同样移入构建阶段环境变量 `LEGACY_STORAGE_KEY`,通过 `vite.config.ts``define` 注入:
- 构建产物中不再包含固定的 `"MedicalReportSys2024"`
- 若部署方需要兼容旧数据,在构建时配置 `LEGACY_STORAGE_KEY="MedicalReportSys2024"` 即可正常迁移。
- 若部署方不需要兼容(全新部署),留空即可,旧数据将以 JSON.parse 失败处理,回退到 fallback。
### D. 后续如何避免问题
- 任何涉及历史数据迁移的安全重构,必须在方案设计阶段同步考虑"旧密钥/旧算法常量是否需要保留"。
- 检查清单:若验收标准包含"构建产物无硬编码敏感字符串",则所有历史兼容所需的常量也必须环境变量化。
- `.env.example` 中应显式标注 `LEGACY_STORAGE_KEY` 的用途("Former XOR encryption key"),避免运维人员误删。
---