Files
Migu2.0/Doc/CODE_REVIEW_ISSUES_2026-05-29.md
T
zhaowei.huangandCursor 42978930ca feat: 迁入 MiGu.Server、平台前端与车辆列表 reflection 回退
从 Simple-FR 拆出 Platform.Server 并重命名为 MiGu.Server;frontends 源码与构建脚本迁入本仓库。地图监控在 projection/cars 失败或为空时回退 reflection 车辆列表;Simple 仓库已移除旧 Platform.Server。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 18:16:34 +08:00

285 lines
22 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 模型或开发者按项修复。
> **仓库路径**`E:\Work\Core\Simple-FR\Simple`
> **分支**`dev_simpleLite`(审核时)
> **审核日期**2026-05-29
> **审核范围**:后端 C#MiGu.Server、SimpleLite、SimpleCore 相关 diff);**不含**前端 Vue 全量审阅与 `dotnet build` 验证。
---
## 使用说明(给优化 AI
1.**优先级** 从高到低处理:`P0``P1``P2`
2. 每项包含:**问题 ID**、**文件**、**现象**、**建议改法**、**验收标准**。
3. 修改时遵循仓库现有风格;**不要**扩大无关重构范围。
4. 修复后在对应项下可勾选 `[x]`(本文件由人工维护勾选状态)。
---
## 问题总表(快速索引)
| ID | 优先级 | 状态 | 标题 | 主要文件 |
|----|--------|------|------|----------|
| ISSUE-10 | P0 | ✅ 已修复 | CarRepository 反序列化白名单可能过严 | `SimpleLite/Persistence/Repositories/CarRepository.cs` |
| ISSUE-05 | P1 | ✅ 已修复 | 项目/应用配置 API 未校验 writableViaApi | `SimpleLite/Web/ReflectionApiController.cs` |
| ISSUE-04 | P1 | 🔧 部分处理 | Launcher 等新文件未纳入版本库 | `MiGu.Server/Launcher/*` 等 |
| ISSUE-01 | P2 | 📝 已评估·可配置缓解 | 登录仍可能阻塞至 Readiness 超时 | `MiGu.Server/Controllers/AuthController.cs` |
| ISSUE-02 | P2 | 📝 已评估·维持现状 | Me/SwitchScope RunMode 复用实例时偏保守 | `MiGu.Server/Controllers/AuthController.cs` |
| ISSUE-03 | P2 | ✅ 已处理·README | 默认 admin 凭据(部署) | `MiGu.Server/appsettings.json` |
| ISSUE-06 | P2 | ✅ 已修复 | GET monitor-config 写副作用 | `SimpleLite/Web/ReflectionApiController.cs` |
| ISSUE-07 | P2 | 📝 已评估·待产品 | POST monitor-config 立即写盘 | `SimpleLite/Web/ReflectionApiController.cs` |
| ISSUE-08 | P2 | ✅ 已修复 | Toolbar GetState 响应格式不一致 | `SimpleLite/Web/WorkspaceToolbarApiController.cs` |
| ISSUE-09 | P2 | 📝 已评估·技术债 | 录制/图层 API 重复维护 | `MapEditApiController` + `WorkspaceToolbarApiController` |
| ISSUE-11 | P2 | 📝 已评估·观察项 | 高频 redraw 仍可能偶发旧帧 | `SimpleLite/Rendering/SimpleSceneRenderer.cs` |
| ISSUE-12 | P2 | 📝 已评估·待产品 | Online/Offline 远程 MethodMember 权限 | `SimpleLite/RCS/CarTypes/Car.cs` + 鉴权链 |
| ISSUE-13 | P2 | 📝 已评估·依赖升级 | GetPosition realtime 未启用 | `SimpleLite/Workspace/WorkspacePickSession.cs` |
| ISSUE-14 | P2 | 📝 已评估·环境项 | 2D 平移绑定依赖 CycleGUI 版本 | `SimpleLite/Workspace/WorkspaceViewModeService.cs` |
| ISSUE-15 | P2 | 📝 已评估·低优维持 | 表格双击为时间窗口模拟 | `SimpleLite/UI/WorkbenchTableRowUi.cs` |
| ISSUE-16 | P2 | 📝 已评估·待产品 | 底栏 CAD 入口已移除(产品确认) | `WorkspaceBottomBar.cs` 等 |
---
## P0 — 合并前建议先验证/修复
### ISSUE-10 — CarRepository 反序列化白名单可能过严
- **状态**[x] 已修复(2026-05-29
- **文件**`SimpleLite/Persistence/Repositories/CarRepository.cs``CarTypeBinder``JsonOpts`
- **现象**`TypeNameHandling.Auto` + 自定义 `ISerializationBinder` 白名单未包含 `System.String``System.Int32``System.Boolean` 等 BCL 基础类型。`customProps``JsonConvert.SerializeObject(car, JsonOpts)` 序列化**整辆车**,JSON 中泛型容器(如 `Dictionary<string, int>`)的 `$type` 可能含 `System.*`,反序列化时 `BindToType``SerializationException`
- **风险**:升级后 `LoadAllIntoSimpleLib` 部分车辆加载失败。
- **建议改法**(择一或组合):
1. 在白名单中增加安全 BCL 类型前缀/精确名:`System.String``System.Int32``System.Int64``System.Boolean``System.Single``System.Double``System.Decimal``System.DateTime` 等;或允许 `System` 下仅 primitive 与 `System.Collections.Generic` 的封闭列表。
2. 缩小序列化范围:勿对整个 `car` 使用 `TypeNameHandling.Auto`,仅对已知 DTO/字段序列化。
3. 提供 `RegisterAllowedNamespacePrefix("System")` 的文档说明(不推荐无限制放行整个 System)。
- **验收标准**
- 用**现有生产/测试库**中真实 `customProps` JSON 跑 `LoadAllIntoSimpleLib`,无 SerializationException。
- 恶意 `$type`(如 `System.Windows.Forms.*` gadget)仍被拒绝。
- **回归命令**(示例):加载含多车型、多插件的程序集后启动 SimpleLite 并打开车辆列表。
- **修复说明**2026-05-29):在 `CarTypeBinder` 新增精确类型白名单 `_allowedExactTypeNames`,放行安全的 BCL 基础类型(string/int/long/bool/float/double/decimal/DateTime/DateTimeOffset/TimeSpan/Guid/char/byte/short/Object/Enum/Nullable&lt;T&gt; 等);`IsAllowedRawName` 在命名空间前缀匹配前先做「精确全名」匹配。修复后泛型容器实参(如 Dictionary&lt;string,int&gt;、Dictionary&lt;string,object&gt;)在字符串层 `IsAllowedSerializedTypeName` 与已解析层 `IsAllowedResolvedType` 两条路径均不再误抛 `SerializationException`。因采用精确全名而非放行整个 `System.*` 前缀,`System.Windows.Forms.*` 等 gadget 链仍被拒绝。**仍需**用真实生产/测试库回归 `LoadAllIntoSimpleLib`
---
## P1 — 建议本轮一并处理
### ISSUE-05 — 项目/应用配置 API 未校验 writableViaApi
- **状态**[x] 已修复(2026-05-29
- **文件**`SimpleLite/Web/ReflectionApiController.cs`
- `SetProjectField``POST /project/fields/{field}`
- `SetAppConfigField``POST /app-config/fields/{field}`
- **现象**:仅检查 `FieldMember.locked``MapObjectFactory.IsSensitiveFieldNamePublic`**未**检查 `FieldMember.writableViaApi``SimpleCore/Scene.cs` 已新增,默认 `true`)。
- **对比**`MapObjectFactory.TryApplyField` 已拒绝 `writableViaApi == false`
- **建议改法**:在两处 setter 中读取 `FieldMember`,若 `!fm.writableViaApi` 返回 403 及明确文案;与 `TryApplyField` 日志风格一致。
- **验收标准**:对标记 `writableViaApi=false` 的字段,Web POST 返回 403,内存值不变。
- **修复说明**2026-05-29):在 `SetProjectField``Scene.conf`)与 `SetAppConfigField``Configuration.conf`)的 `fm.locked` 检查之后新增 `if (!fm.writableViaApi)` 拦截,命中即 `Diagnosis.Post` 记录并返回 403(内存值不变),与 `MapObjectFactory.TryApplyField` 的双层防御保持一致。注:前端字段列举(`ListFieldMembers` / 字段记录)暂未暴露 `writableViaApi`,如需「预先禁用不可写输入框」可后续在响应中增列该布尔值(属前端契约增量,未纳入本次范围)。
---
### ISSUE-04 — 新增文件未纳入 Git(提交遗漏)
- **状态**[~] 部分处理(2026-05-29):`.gitignore` 已补;编译必需的后端源文件待人工 `git add` + `commit`
- **路径**(审核时为 untracked):
- `MiGu.Server/Launcher/SimpleLiteLauncher.cs`
- `MiGu.Server/Launcher/SimpleLiteOptions.cs`
- `SimpleLite/Web/WorkspaceToolbarApiController.cs`
- `SimpleLite/Web/MonitorVisibilityConfig.cs`
- `SimpleLite/Workspace/CurveControlPointDragService.cs`
- (前端相关见下方「未审范围」)
- **现象**`AuthController` 依赖 `SimpleLiteLauncher` DI;未 add 则他人 clone 无法编译/运行。
- **建议改法**:确认属于本需求后 `git add``.codegraph/``.cursor/mcp.json``.gitignore` 决定是否提交。
- **验收标准**:干净 clone + build 能通过;Launcher 与 Toolbar 路由可访问。
- **处理进度**2026-05-29):
- ✅ 已补 `.gitignore`:忽略 `.codegraph/`(codegraph 本地索引缓存)与 `/SimpleCore/ref/`(同 `/ref/Ref` 的未知用途二进制),二者已从 untracked 列表移除。
- ✅ 已确认 `AuthController` 构造函数注入 `SimpleLiteLauncher`(第 69/72 行)→ `Launcher/*.cs` 为编译必需,必须入库。
- ⏳ 待人工执行(编译必需的后端源文件 + 本审核文档;单行命令,PowerShell/bash 均可):
```
git add MiGu.Server/Launcher/SimpleLiteLauncher.cs MiGu.Server/Launcher/SimpleLiteOptions.cs SimpleLite/Web/WorkspaceToolbarApiController.cs SimpleLite/Web/MonitorVisibilityConfig.cs SimpleLite/Workspace/CurveControlPointDragService.cs Doc/ .gitignore
```
- ❓ 需决策是否入库:`.cursor/mcp.json``.cursor/rules/codegraph.mdc`(团队是否共享该 MCP / 规则配置)。
- 📦 前端新文件(`frontends/apps/simple-platform-vue/**``workspaceToolbar.ts``MonitorSelectionPanel.vue``FieldMemberEditor.vue``CarStyleEditor*``ProjectPropertiesView.vue``MapMonitorConfigView.vue` 等)归「前端另开任务」范围,建议随前端审核一并 add。
- ⚠ 未执行 `git commit`:提交内容与时机由人工掌控。
---
## P2 — 按产品/环境决定或后续迭代
### ISSUE-01 — 登录仍可能阻塞至 Readiness 超时
- **状态**[~] 已评估(2026-05-29):现有配置即可缓解,暂不改代码
- **文件**`MiGu.Server/Controllers/AuthController.cs``Login``Task.Run(() => _launcher.MaybeStart(...))`
- **现象**`MaybeStart``WaitForProjectionReady` 默认最多 8000ms,登录请求仍等待该 Task。
- **建议改法**:缩短超时、登录先返回 + 前端轮询 `/projection` 就绪、或 fire-and-forget + `LaunchWarning` 已有字段提示。
- **验收标准**:登录 P95 延迟可接受;SimpleLite 未就绪时前端有明确降级(`Detached` / `LaunchWarning`)。
- **评估说明**(2026-05-29):报告建议的「缩短超时 / 登录先返回」**现有设计已通过配置支持**,无需改代码:`SimpleLiteOptions.ReadinessTimeoutMs`(绑定 `appsettings.json:SimpleLite.ReadinessTimeoutMs`,默认 8000)注释明确 `0 = 不等待(登录立即返回)``负值 = 无限等待``Login` 已用 `Task.Run` 释放请求线程,失败时回填 `Detached` + `LaunchWarning`。运维若需更快登录可将该值调小或置 0(代价:`RunMode` 可能暂不准,由 `LaunchWarning` 降级提示)。真正的「fire-and-forget + 前端轮询 `/projection`」属前后端协议改动,留作后续迭代。
---
### ISSUE-02 — Me / SwitchScope 的 RunMode 在复用外部 SimpleLite 时偏保守
- **状态**[~] 已评估(2026-05-29):当前保守映射为有意设计,维持现状
- **文件**`MiGu.Server/Controllers/AuthController.cs``Me``SwitchScope``ResolveRunMode`
- **现象**`ReusingExisting` / `ExternalReuseLaunchMode` 常归为 `WebEnabled`,与用户本次 `WebOnly` 选择可能不一致。
- **建议改法**:前端强依赖 `LaunchWarning`;或 HTTP 探针推断 displayMode(成本高)。
- **验收标准**:用户知悉「已有实例未应用新模式」;无静默错误状态。
- **评估说明**2026-05-29):`ResolveRunMode` / `Me` / `SwitchScope``ExternalReuseLaunchMode``ReusingExisting` 时归 `WebEnabled` 是**有意的保守降级**(代码注释已说明:复用既有实例时其真实 displayMode 不可知,归 WebEnabled 最不会误导用户「以为本地窗口不存在」)。用 HTTP 探针推断成本高且不可靠;前端已可凭 `LaunchWarning` 提示「已有实例未应用新模式」。结论:维持现状,作为前端体验项后续跟进,不改后端。
---
### ISSUE-03 — 默认 admin 凭据(部署安全)
- **状态**[x] 已处理(2026-05-29):已在 README 增加生产安全须知
- **文件**`MiGu.Server/appsettings.json``Auth:Users`
- **建议**:生产用环境变量/密钥管理覆盖;README 注明勿用默认密码。
- **处理说明**2026-05-29):已在 `MiGu.Server/README.md` 新增「安全须知(生产部署必读)」小节,明确 `admin/admin``ops/ops``Jwt.Secret`/`Internal.Token=REPLACE_ME` 仅供开发,并给出环境变量覆盖示例(`Auth__Users__admin__Password` 等)。`appsettings.json` 默认值保持不变以维持开箱即用的本地开发体验(属部署规范,非代码缺陷)。
---
### ISSUE-06 — GET monitor-config 写副作用
- **状态**[x] 已修复(2026-05-29
- **文件**`SimpleLite/Web/ReflectionApiController.cs``GetMonitorConfig`
- **现象**`monitorVisibility == null` 时 GET 会 `Configuration.conf.monitorVisibility = new MonitorVisibilityConfig()`
- **建议改法**:GET 只读快照,不写回 `Configuration.conf`;初始化放在 `Configuration` 构造/`FromFile`
- **验收标准**:多次 GET 不改变磁盘上的 `simple.json`(除非 POST)。
- **修复说明**2026-05-29):删除 `GetMonitorConfig` 中的 `Configuration.conf.monitorVisibility = conf;` 写回行,GET 改为纯只读快照。`monitorVisibility` 非 null 已由 `Configuration` 字段默认值(`= new()`,第 74 行)、构造函数(`??=`,第 32 行)与 `FromFile``??=`,第 46 行)三处共同保证,GET 无需补写。多次 GET 不再触碰 `Configuration.conf`,自然不会引发后续写盘。
---
### ISSUE-07 — POST monitor-config 每次全量写 simple.json
- **状态**[~] 已评估(2026-05-29):维持「保存即写盘」,待产品决定是否需要预览态
- **文件**`ReflectionApiController.PostMonitorConfig`
- **现象**POST 成功即 `Configuration.ToFile("simple.json")`,无单独「保存」步骤。
- **建议改法**:若需「预览再保存」,拆分为 PATCH 内存 + `POST /monitor-config/save`;与 `PostAlarmColors` / `SaveCarStyle` 模式对齐。
- **评估说明**2026-05-29):当前「POST 成功即写盘」行为正确(非 bug)。是否拆分为「预览态 + 显式保存」取决于产品对监控可见性配置的交互预期,拆分需新增 `POST /monitor-config/save` 端点并由前端配合「保存」按钮,属产品/前端联动改动。结论:维持现状,待产品确认是否需要预览态后再迭代。
---
### ISSUE-08 — WorkspaceToolbar GetState 响应格式不一致
- **状态**[x] 已修复(2026-05-29
- **文件**`SimpleLite/Web/WorkspaceToolbarApiController.cs``GetState`
- **现象**`GetState` 返回 `{ success, code, data }`;其它端点用 `ReflectionEnvelope<object>`
- **建议改法**:统一为 `ReflectionEnvelope`;或前端 adapter 层统一解析(若改 Vue 需另开任务)。
- **验收标准**`WorkspaceCanvasToolbar.vue`(未审)与 API 契约一致。
- **修复说明**2026-05-29):`GetState` 成功分支由手写匿名对象 `{ success, code, data }` 改为 `ReflectionEnvelope<object>.Ok(BuildStateAnon())`,输出补齐 `message` 字段。经核对前端 `workspaceToolbar.ts``Envelope<T>` 接口本就声明 `{ success, code, data, message }``unwrap` 在失败时读 `resp.message`——本次改动使后端与该契约完全对齐,`data``BuildStateAnon`)结构不变,前端仅多读到一个 `message` 字段,向后兼容,无需改 Vue。
---
### ISSUE-09 — 录制/图层 API 重复
- **状态**[~] 已评估(2026-05-29):逻辑已收敛到共享单例,维持双入口
- **文件**
- `SimpleLite/Web/MapEditApiController.cs``/layers``/recording/*``/playback/*`
- `SimpleLite/Web/WorkspaceToolbarApiController.cs`(同源能力)
- **建议改法**:抽取 `RecordingApiHelper` / 单 controller;或文档标明 MapEdit=地图编辑器、Toolbar=Embed iframe,避免双份逻辑漂移。
- **验收标准**:修一处行为两处一致,或 deprecate 其一。
- **评估说明**2026-05-29):核对两个 controller 后确认——`MapEditApiController``/objects/*``/layers``/recording/*``/playback/*`)与 `WorkspaceToolbarApiController``/toolbar/*`)**都只是薄 HTTP 封装**,真正的状态与逻辑均委托给共享单例 `PlaybackController` / `SimulationRecorder` / `RecordingLibrary` / `SimpleUI.LayerToShowRef`。因此「修一处行为两处一致」**本质已满足**(无逻辑漂移,仅路由壳与响应组装重复)。分工:MapEdit=地图编辑器全功能页,Toolbar=Embed/CanvasOnly iframe 精简栏。结论:维持双入口(强行合并会牵动两套前端),作为技术债记录;后续若消重可抽取 `RecordingApiHelper` 收拢响应组装。
---
### ISSUE-11 — 高频 redraw 仍可能偶发旧帧
- **状态**[~] 已评估(2026-05-29):观察项,未复现不改
- **文件**`SimpleLite/Rendering/SimpleSceneRenderer.cs`
- **现象**:已做 force 16ms、运动 33ms、`NotifyStateChanged` 直通;极端高频仍可能竞态。
- **建议**:仅在实际复现时合并 redraw 或加锁。
- **评估说明**2026-05-29):现有节流(force 16ms / 运动 33ms / `NotifyStateChanged` 直通)已覆盖常规场景;极端高频旧帧为理论竞态,未见稳定复现。盲目加锁可能引入渲染线程争用、得不偿失。结论:保持观察,待出现可复现用例再针对性合并 redraw 或加锁。
---
### ISSUE-12 — Car.OnlineCar / OfflineCar 经 Web 反射调用
- **状态**[~] 已评估(2026-05-29):需产品确认角色边界,未擅自加限制
- **文件**`SimpleLite/RCS/CarTypes/Car.cs`;调用链 `ReflectionApiController` + Platform 鉴权
- **建议**:确认 Platform 角色是否允许远程触发;必要时 MethodMember 加权限或 Web 层拦截。
- **评估说明**2026-05-29):`OnlineCar` / `OfflineCar``ReflectionApiController` 反射触发,已受 Platform JWT 鉴权链保护(需登录且具备相应 scope)。是否进一步收紧(仅 `role-platform`、或 `MethodMember` 增权限位)取决于产品对「远程上/下线车辆」的角色边界定义,属权限策略决策,不宜由代码审核单方收紧(可能误伤合法运营操作)。结论:待产品确认角色边界后再决定是否加 `MethodMember` 权限或 Web 层拦截。
---
### ISSUE-13 — GetPosition realtime 未启用
- **状态**[~] 已评估(2026-05-29):阻塞于 CycleGUI 协议,维持注释
- **文件**`SimpleLite/Workspace/WorkspacePickSession.cs`
- **现象**`getPos.realtime = true` 仍注释;依赖 `OnPickFeedback` 双路驱动拖动。
- **建议**:CycleGUI 协议支持后取消注释并删「尚未上线」说明。
- **评估说明**2026-05-29):`getPos.realtime = true` 依赖 CycleGUI 协议层支持,当前版本未提供,强行开启会导致拖动反馈异常;现有 `OnPickFeedback` 双路驱动已能正常工作。结论:阻塞于外部依赖(CycleGUI 升级),维持注释现状,待协议支持后取消注释。
---
### ISSUE-14 — 2D 平移绑定依赖 CycleGUI API
- **状态**[~] 已评估(2026-05-29):环境/版本项,建议补版本矩阵
- **文件**`SimpleLite/Workspace/WorkspaceViewModeService.cs``TryBind2DPanOnly`
- **现象**:反射 `SetWorkspaceBehaviour` 字段名;版本不匹配时 2D 右键可能仍改俯仰。
- **建议**:版本矩阵文档;失败时 UI 提示升级 CycleGUI。
- **评估说明**2026-05-29):`TryBind2DPanOnly` 经反射读 `SetWorkspaceBehaviour` 字段名,与 CycleGUI 版本强相关。本质是「运行环境/依赖版本匹配」问题,非代码逻辑缺陷。结论:作为环境项记录;建议在 CycleGUI 版本矩阵文档标注最低版本,并在反射失败时通过 UI 提示升级(可后续小改)。本轮不改逻辑以免误判版本。
---
### ISSUE-15 — 表格双击为 400ms 时间窗口模拟
- **状态**[~] 已评估(2026-05-29):可接受方案,维持
- **文件**`SimpleLite/UI/WorkbenchTableRowUi.cs`
- **说明**CycleGUI 无原生 DoubleClick;已有 `PruneExpiredClickTimestamps` 防泄漏。
- **评估说明**2026-05-29):CycleGUI 立即模式 UI 无原生 DoubleClick 事件,400ms 时间窗口模拟是合理的既定方案,且已有 `PruneExpiredClickTimestamps` 防时间戳泄漏。结论:方案可接受,维持现状,低优先级。
---
### ISSUE-16 — 底栏 CAD 入口已移除
- **状态**[~] 已评估(2026-05-29):非 bug,待产品确认无强依赖
- **文件**`WorkspaceBottomBar.cs``WorkspaceFloatingToolbar.cs`
- **说明**:CAD 仍可通过主菜单/插件;确认用户无强依赖底栏入口。
- **评估说明**2026-05-29):底栏 CAD 入口移除是产品调整(非缺陷),CAD 功能仍可经主菜单/插件访问。结论:非 bug,仅需产品确认用户无对「底栏 CAD 入口」的强依赖即可关闭。
---
## 已确认修复项(无需再改,供对照)
| 项 | 说明 |
|----|------|
| 脚本 KPI | `script` count 改为 `CarProgram.GetPrograms().Length` |
| 脚本 CRUD | Web 禁止新建/删除 script`ResolveObject` 走 CarProgram |
| 删 script 误删车 | `MapObjectFactory.DeleteByKind` script 分支独立返回 400 |
| JSON camelCase | `SetViewFilter` 用 DictionaryToolbar 用 `JsonSerializerCase.CamelCase` |
| 敏感字段 | `MapObjectFactory` 前缀黑名单 + `writableViaApi` |
| 项目保存路径 | `TryResolveSafeProjectPath` 白名单 |
| 对齐/选择解耦 | `WorkspacePointerSnap``AlignSnap*` |
| GetPosition 竞态 | `terminated` ReferenceEquals 防误删新会话 |
| 车体默认白色 | `WorkspaceViewportStyle` 纯白判定修复 |
---
## 未审范围(后续可另开审核任务)
- `frontends/apps/simple-platform-vue/**`(含 `DashboardView.vue` 等大 diff
- `SimpleLite/UI/ComposerDockPanel.cs` 大 diff
- `build-platform-frontend.bat`
- 全解决方案 `dotnet build` / 前端 `npm run build`
- 未跟踪前端文件:`workspaceToolbar.ts``WorkspaceCanvasToolbar.vue``CarStyleEditor*.vue`
---
## 给优化 AI 的推荐执行顺序
```
1. ISSUE-10(回归真实 DB → 修 binder 或序列化策略)
2. ISSUE-05writableViaApi 对齐)
3. ISSUE-04git add 缺失文件)
4. ISSUE-08 / ISSUE-09(若本轮动前端 Toolbar
5. 其余 P2 按产品排期
```
---
## 修订记录
| 日期 | 说明 |
|------|------|
| 2026-05-29 | 初版:基于会话 58 代码审核整理 |
| 2026-05-29 | 优化轮(会话 65):修复 ISSUE-10/05/06/08(代码改动);ISSUE-03 在 `MiGu.Server/README.md` 增「安全须知」、ISSUE-04 补 `.gitignore` 并给出 `git add` 命令(后端必需文件待人工提交);ISSUE-01/02/07/09/11/12/13/14/15/16 完成评估并记录决策。`dotnet build SimpleLite/SimpleLite.csproj` 通过(0 错误 / 282 预存警告)。 |