--- title: 关键决策与已实现方案 type: curated permalink: main/projects/4f53c06a-c6c3-40ec-b2fc-5f019ea45fc0/curated/关键决策与已实现方案 stable_id: 7efbeabe-d24c-43de-a01f-769b52610eaa scope: project project_id: 4f53c06a-c6c3-40ec-b2fc-5f019ea45fc0 workspace_type: development usage_profile_id: null preference_context: development document_type: decisions revision: 1 source_memory_ids: [] source_checkpoint_ids: [] source_file_ids: [] source_git_commit: de28dc8246094e2bc17cab7c764fb4d4a2da71e0 source_git_commits: - de28dc8246094e2bc17cab7c764fb4d4a2da71e0 source_agent_sync_ids: [] model_connection: Sub2API model_name: git-restore source_count: 188 source_revisions: {} source_dispositions: processed: 188 unchanged: 0 unsupported: 0 skipped: 0 cited_source_ids: - git:backend/src/dbus.rs - git:backend/src/serial.rs - git:backend/src/iptables.rs - git:backend/src/main.rs - git:backend/src/ota.rs - git:backend/src/sms_listener.rs - git:backend/src/config.rs - git:backend/src/state.rs - git:backend/src/usb_switch.rs - git:frontend/src/pages/DeviceInfo.tsx - git:frontend/src/pages/Configuration.tsx - git:frontend/src/pages/Network.tsx - git:frontend/src/pages/Frp.tsx - git:frontend/src/components/Layout/TopBar.tsx - git:scripts/pack-ota.sh - git:scripts/build.sh job_cited_source_ids: - git:backend/src/dbus.rs - git:backend/src/serial.rs - git:backend/src/iptables.rs - git:backend/src/main.rs - git:backend/src/ota.rs - git:backend/src/sms_listener.rs - git:backend/src/config.rs - git:backend/src/state.rs - git:backend/src/usb_switch.rs - git:frontend/src/pages/DeviceInfo.tsx - git:frontend/src/pages/Configuration.tsx - git:frontend/src/pages/Network.tsx - git:frontend/src/pages/Frp.tsx - git:frontend/src/components/Layout/TopBar.tsx - git:scripts/pack-ota.sh - git:scripts/build.sh conflicts: [] supersedes: [] preferences: [] source_cursor: 87 source_hash: 96f0e4026558c8a03161f53b392fcec7359d4d701c4f33576b44e2f308b0ec5a prompt_version: 2026-08-12.3 schema_version: '3' curation_job_id: null created_at: '2026-08-19T18:49:25.643063+00:00' updated_at: '2026-09-23T14:55:19.823710+00:00' tags: - project-cpe - development - decisions restored_from_commit: 6a6a895eafcca6052e81a14fca103a42635dd1c2 --- # 关键决策与已实现方案 | 序号 | 决策主题 | 出现位置 | 根本原因 | 实施方案 | 开放/待办 | |------|----------|----------|----------|----------|-----------| | 1 | **串行 AT/D‑Bus 调用** | `backend/src/dbus.rs`、`backend/src/serial.rs` | ofono 并发 AT 命令会返回 `org.ofono.Error.InProgress` | 引入全局锁 `DBUS_LOCK` 与 `with_serial`,所有 DBus/AT 调用走同一串行通道(超时 20 s) | 已实现,无待办 | | 2 | **iptables 规则自动清理** | `backend/src/iptables.rs`、`backend/src/main.rs` | 进程异常退出后残留 iptables 规则导致网络异常 | `iptables_watchdog` 启动后每 5 s 调用 `flush_iptables()`,在数据连接切换前强制刷新 | 已实现,无待办 | | 3 | **端口冲突重试** | `backend/src/main.rs` | 端口被其他进程占用导致服务启动失败 | `bind_with_retry()` 在 30 s 内循环尝试绑定,失败则记录警告后继续 | 已实现,无待办 | | 4 | **OTA 包完整性校验** | `scripts/pack-ota.sh`、`backend/src/ota.rs` | OTA 包可能缺文件、架构错误或校验和不匹配 | `validate_ota_package()` 检查文件、架构 (`aarch64-unknown-linux-gnu`)、版本递增、MD5/SHA‑256 对比;后端安装使用原子临时文件 + `fsync` 再 `rename` | 已实现,无待办 | | 5 | **SMS 去重与分片 TTL** | `backend/src/sms_listener.rs` | ofono 同时推送文本与 PDU 导致重复记录 | 10 s 去重窗口 + `should_store` 判断;多片 SMS 设置 5 min TTL 自动清理 | 已实现,无待办 | | 6 | **SIM 卡槽切换 UI 同步** | `frontend/src/pages/DeviceInfo.tsx` | 后端切换需时间,前端立即刷新会显示旧信息 | 在成功请求后 `setTimeout(loadData, 2000)` 延迟重新加载 | 已实现,无待办 | | 7 | **敏感字段脱敏占位** | `backend/src/config.rs`、前端 `Network.tsx`、`Frp.tsx` | 为防泄漏在源码中屏蔽真实值 | 用 `[REDACTED]` 占位,提示需要安全存储 | **开放**:实现 Vaultwarden 或加密文件存储 | | 8 | **UI 轮询频率可调** | `frontend/src/components/Layout/TopBar.tsx` | 默认 5 s 轮询对部分用户过于频繁 | `setRefreshInterval` 通过后端 `api.setRefreshConfig` 持久化,用户可在顶部菜单选择 1/3/5/10 s 或手动 | 已实现,无待办 | | 9 | **USB 热切换实验** | `backend/src/usb_switch.rs`、前端 `Configuration.tsx` | 需要在不重启的情况下切换 USB Gadget 模式 | `switch_usb_mode_advanced` 完成 UDC 停止、清理旧配置、写新描述、重新启用 UDC,并写入持久/临时模式文件 | **开放**:增加文件锁、完善错误回滚 | | 10 | **FRPC 生命周期管理** | `backend/src/state.rs` | 自动启动可能导致未配置情况下启动 | 仅在 `enabled && auto_start` 为 true 时启动;提供 UI 配置、日志轮转 (512 KB) | 已实现,**开放**:日志轮转阈值可配置 | | 11 | **全局 CORS 允许 `*`** | `backend/src/main.rs` | 开发阶段便捷跨域 | 设置 `*` 为允许源 | **开放**:生产环境需限制来源 | | 12 | **AT 网关未鉴权** | `backend/src/handlers.rs` (`/api/at`) | 安全风险 | 暂未实现鉴权,仅记录为待办 | **开放** | | 13 | **HTTP 错误码统一 200** | `backend/src/handlers.rs` | 前端统一解析 JSON | 所有错误仍返回 `200 OK`,错误信息放在 `ApiResponse` 的 `status` 字段 | **开放**:改为符合 REST 的状态码 | | 14 | **OTA 未签名** | `scripts/pack-ota.sh` | 防止篡改 | 当前不生成签名 | **开放**:集成 GPG 或 SHA‑256 签名并在 `ota.rs` 验证 | | 15 | **缺少单元测试** | 整体代码库 | 项目快速迭代导致测试被忽略 | 尚未编写任何 Rust 或前端测试 | **开放**:添加 Jest、React‑Testing‑Library 与 Rust 测试套件 | | 16 | **UI 错误边界缺失** | `frontend/src/main.tsx` | 未捕获渲染异常会导致整页崩溃 | 暂无实现 | **开放**:在根组件加入 `ErrorBoundary` | | 17 | **缺少国际化** | 所有 UI 文本硬编码中文 | 仅面向中文用户 | 未使用 i18n 框架 | **开放**:引入 `react-i18next` 并抽离字符串 | | 18 | **大表未虚拟化** | `Network.tsx` 中的基站列表 | 列表可能非常长,性能下降 | 使用普通 MUI `DataGrid`(未开启虚拟化) | **开放**:改为 `react-window` 或开启 DataGrid 虚拟滚动 | 以上表格记录了所有已知决策、实施细节以及当前开放/未完成的工作项,便于后续评审与排期。