# 06-决策记录 本文件记录关键技术决策。格式参考 ADR。 状态说明: - `已采纳` - `待确认` - `废弃` ## ADR-001 - 使用 C# 与 ASP.NET Core Web API 状态:已采纳 日期:2026-07-02 背景: - 当前系统为 C#/.NET Framework + `.ashx`。 - 目标系统要求运行在 Linux。 - 前台通过 WebAPI 调用。 决策: - 新项目使用 C#。 - Web 框架使用 ASP.NET Core Web API。 - 运行时优先使用 .NET 10 LTS。 原因: - 与现有代码和团队知识体系最接近。 - ASP.NET Core 可跨平台运行。 - WebAPI、Swagger、JWT、HealthCheck、日志、Docker 支持成熟。 影响: - 旧 `.ashx` 不直接迁移,改为 Controller。 - 旧 `.NET Framework` 依赖需要替换为 .NET 跨平台库。 ## ADR-002 - 使用 Provider 策略支持多数据库 状态:已采纳 日期:2026-07-02 背景: - 目标支持 SQL Server、PostgreSQL、MySQL。 - 三种数据库在参数、分页、存储过程、函数、二进制字段、标识符引用方面存在差异。 决策: - 定义 `IDatabaseProvider` 抽象。 - 分别实现 `SqlServerProvider`、`PostgreSqlProvider`、`MySqlProvider`。 - 数据库差异只允许在 Provider 层处理。 原因: - 避免 Controller 和业务层散落数据库判断。 - 允许同一个 actionId 对不同数据库配置不同 SQL 或函数。 - 便于单独测试每种数据库。 影响: - 首期要设计好 `DbExecutionContext` 和参数模型。 - 不追求三种数据库完全共用同一段 SQL。 ## ADR-003 - 使用 actionId 白名单替代前台任意传 SQL/存储过程名 状态:已采纳 日期:2026-07-02 背景: - 旧系统 `Name/name` 可由前台传入。 - `Name/name` 可能是存储过程名、SQL 文本或表名。 - 存在较高安全风险。 决策: - 新接口以 `actionId` 作为业务动作标识。 - actionId 在后端白名单中配置 SQL、存储过程、参数、权限。 - legacy 接口也必须经过白名单。 原因: - 降低 SQL 注入和越权执行风险。 - 便于审计。 - 便于多数据库为同一个 action 配置不同实现。 影响: - 需要建设 action 配置。 - 前台后续要逐步从 `type/name/param` 迁移到 `actionId/parameters`。 ## ADR-004 - 保留 Legacy 接口作为迁移过渡 状态:已采纳 日期:2026-07-02 背景: - 现有前台可能大量依赖 `Type/Name/Param`。 - 一次性改前台和后端风险较大。 决策: - 新项目提供 `/api/v1/legacy/execute`。 - 兼容旧字段,但不允许任意执行。 - 高风险 Type 默认禁用或限制。 原因: - 降低迁移成本。 - 可逐个业务回归。 - 为前台改造争取时间。 影响: - 需要实现 `LegacyTypeRouter` 和 `LegacyParamParser`。 - 需要维护旧 Type 到 action 的映射。 ## ADR-005 - SQL Server 优先落地,再扩展 PostgreSQL 和 MySQL 状态:已采纳 日期:2026-07-02 背景: - 当前系统主要依赖 SQL Server。 - 直接同步完成三类数据库会扩大风险。 决策: - 第一阶段先实现 SQL Server Provider。 - 在 SQL Server 上跑通 legacy 兼容和 actionId。 - 再实现 PostgreSQL Provider。 - 再实现 MySQL Provider。 原因: - 先保证现有业务迁移可行。 - Provider 抽象可在 SQL Server 实战中校准。 - 后续数据库迁移按 action 渐进完成。 影响: - 多数据库不是第一天全部完成。 - 任务矩阵需要把三类数据库分开验收。 ## ADR-006 - 不自动翻译全部 SQL Server 存储过程 状态:已采纳 日期:2026-07-02 背景: - SQL Server、PostgreSQL、MySQL 语法和过程语义差异明显。 - 自动翻译容易造成隐性错误。 决策: - 不做全量自动 SQL 翻译。 - 按 actionId 逐个迁移。 - 每个 action 针对不同数据库配置独立 command。 原因: - 便于测试。 - 便于控制风险。 - 避免假兼容。 影响: - 迁移周期会按业务 action 分批推进。 - 需要建立回归测试样本。 ## ADR-007 - 统一 JSON 响应格式 状态:已采纳 日期:2026-07-02 背景: - 旧接口返回格式混杂:数组 JSON、`result=1/0`、`{code,message,data}`、文本、空响应、`NULL`。 决策: - 新 JSON API 统一返回: ```json { "code": "200", "message": "", "data": {}, "traceId": "" } ``` 原因: - 前台处理更简单。 - 错误更清晰。 - 审计和排障更方便。 影响: - legacy 兼容接口可短期保留旧格式,但新接口必须统一格式。 ## ADR-008 - 强制鉴权而不是 token 非空才校验 状态:已采纳 日期:2026-07-02 背景: - 旧代码中很多方法只在 `token` 非空时校验。 - 不传 token 时可能继续执行。 决策: - 新系统除登录、健康检查等公开接口外,默认都要求 JWT 鉴权。 - action 再做权限校验。 原因: - 明确安全边界。 - 防止前台漏传 token 导致绕过。 - 便于统一审计用户身份。 影响: - 前台必须接入登录和 Bearer Token。 - legacy 接口也默认要求 JWT。 ## ADR-009 - 高风险 Type 默认禁用或治理后开放 状态:已采纳 日期:2026-07-02 背景: 旧系统以下 Type 风险较高: - `3` - `4` - `7` - `22` - `1001` - `1002` - `3001` 决策: - 生产环境默认禁用。 - 如确需保留,必须在管理端、内网、强审计、白名单条件下开放。 原因: - 这些 Type 涉及直接 SQL、动态建表、命令执行。 - 多数据库迁移后风险会扩大。 影响: - 需要逐个找替代 action。 - 需要和前台确认是否仍在使用。 ## ADR-010 - 文件存储优先支持数据库二进制,后续可扩展对象存储 状态:待确认 日期:2026-07-02 背景: - 旧系统文件上传下载通过数据库存取 byte[]。 - 新系统需要兼容旧业务。 - 大文件放数据库可能影响性能和备份。 决策: - 首期兼容数据库二进制。 - 设计 `FileService` 时预留对象存储或文件系统扩展。 原因: - 首期降低迁移成本。 - 后续可按文件大小和业务类型分流。 待确认: - 是否有大文件场景。 - 是否已有对象存储、NAS 或 MinIO。 - 是否要求文件加密和病毒扫描。 ## ADR-011 - 新移植代码目录独立使用 `MesUniversalApi` 状态:已采纳 日期:2026-07-02 背景: - 当前仓库根目录同时包含旧 WebSite、旧类库、分析资料和管理文档。 - 如果直接在旧系统目录中混合创建新 WebAPI 代码,后续盘点、验收和回归会变得混乱。 决策: - 新移植项目统一放在 `MesUniversalApi/`。 - `working/` 继续保留旧系统分析资料。 - `working1/` 继续保留项目管理文档。 原因: - 代码边界清晰。 - 旧系统可继续作为回归基线。 - 便于后续单独初始化 git 仓库、部署和验收。 影响: - `T002` 及后续所有新代码、测试、部署和工具脚本都从 `MesUniversalApi/` 开始。 - 不在 `MES_Manage/`、`02DataLinkMesWork/` 等旧目录中直接展开新 WebAPI 开发。 ## ADR-012 - 在 .NET 10 SDK 到位前只做基线准备,不用低版本临时落地 状态:已采纳 日期:2026-07-02 背景: - 新项目目标运行时已确定为 `.NET 10`。 - 当前开发机仅检测到 `.NET SDK 9.0.311`。 决策: - 在 `.NET 10 SDK` 安装到位前,只做文档、目录、任务、证据和资产盘点准备。 - 不以 `net9.0` 或更低版本临时创建正式项目骨架。 - 待 `.NET 10 SDK` 安装后,再在 `MesUniversalApi/` 中创建 `global.json` 和正式项目文件。 原因: - 避免先建低版本项目再返工升级。 - 避免把环境缺口误判为代码问题。 - 保持目标技术基线一致。 影响: - 当前轮次不会生成可编译的 `net10.0` 项目代码。 - `T002` 的执行前置条件明确依赖 `.NET 10 SDK` 安装完成。 ## ADR-013 - 云仓库只提交迁移资料和新移植目录 状态:已采纳 日期:2026-07-02 背景: - 当前本地根目录同时包含旧系统源码、IDE 状态、二进制产物、压缩包、分析资料和新移植目录。 - 用户要求把当前迁移工作提交到云仓库。 决策: - 云仓库只跟踪 `working/`、`working1/` 和 `MesUniversalApi/`。 - 不把旧系统全量源码、`.vs/`、本地压缩包、凭据文件和其他本地产物推送到云仓库。 原因: - 保持仓库聚焦于迁移工作本身。 - 降低无关大文件和本地状态污染。 - 避免把本地凭据文件一并入库。 影响: - 云仓库是迁移工作仓库,不是旧系统完整备份仓库。 - 如果后续确需纳入某部分旧代码,应单独评估并更新范围控制规则。