diff --git a/docs/superpowers/specs/2026-09-08-ios-native-ipa-design.md b/docs/superpowers/specs/2026-09-08-ios-native-ipa-design.md new file mode 100644 index 0000000..0b273c5 --- /dev/null +++ b/docs/superpowers/specs/2026-09-08-ios-native-ipa-design.md @@ -0,0 +1,193 @@ +# iOS 原生 IPA 改写设计 + +日期:2026-09-08 + +## 目标 + +把 multi-simadmin 的管理能力改写为独立 iPhone 应用,而不是为现有 Web 服务做一个远程客户端或 WebView 壳。应用面向 iOS 16+ 和 TrollStore 安装环境,构建流程产出未签名 IPA;Apple 证书、开发者账号、TestFlight 和上架签名不在本项目范围内。 + +原生应用直接连接用户配置的各 SimAdmin 实例,本地承担实例注册、连接状态、消息归档、通知队列、任务历史、审计、日志和维护能力。不要求用户先运行 8788 控制台服务。现有 Web 前端与 Node API 保持不变,直到 iOS 版本验证后再另行决定发布关系。 + +## 已确认决策 + +- 形态:SwiftUI 原生应用。 +- 最低系统:iOS 16.0。 +- 构建产物:`MultiSimAdmin.ipa`,默认不签名,后续由用户用 TrollStore 或自有证书处理。 +- 功能范围:优先保持现有控制台与 Hub 能力,但移除不适用于 iPhone 前台的定时/常驻能力。 +- 全局访问密码:移除;实例自身的登录凭据仍保留并安全存储。 +- 现有 UI 风格:移植为 iOS 原生组件,不照搬浏览器布局。 + +## 架构 + +新增 `apps/ios`,包含独立 Swift 应用。结构分为五层: + +1. **App 层**:SwiftUI 应用入口、导航、生命周期和全局错误提示。 +2. **Presentation 层**:节点、消息、通知、日志、操作、设置等 SwiftUI 视图与 view model。 +3. **Domain 层**:实例、连接、消息、通知、操作、审计、维护等领域服务和值类型。 +4. **Upstream 层**:`URLSession` 访问 SimAdmin 实例,管理实例会话 Cookie、超时、响应解析和安全路径白名单。 +5. **Persistence 层**:SQLite 持久化本地控制面数据;实例密码等敏感值使用 iOS Keychain。 + +数据库采用 GRDB 管理迁移与查询,避免手写 SQLite C API。凭据使用 Keychain 的应用私有可迁移项,不进入数据库明文、日志、备份预览或导出文件。 + +应用不内嵌 Node.js。iOS 版本的消息、通知、任务和审计语义按现有控制面模型重新实现,保留核心字段和用户可见行为。 + +## 导航与界面 + +iPhone 主导航使用底部 Tab: + +- **节点**:总览、筛选、批量选择、添加/编辑实例、实例详情和设备模块。 +- **消息**:跨实例短信归档、会话、发送、删除、手动同步和发送队列。 +- **通知**:通道、规则、队列、投递日志和手动投递/重试。 +- **日志**:运行日志、连接日志、诊断和审计。 +- **设置**:实例管理入口、分组/标签、操作目录、维护、备份、应用信息。 + +界面移植现有设计语言: + +- 画布使用浅灰 `#f3f5f8`,主要内容使用白色卡片和柔和描边。 +- 顶部使用深色品牌栏,内容区保持浅色高对比。 +- 主操作按钮使用现有青绿色系统,危险操作使用现有红色系统。 +- 统一普通、紧凑、大号控件高度和圆角;同屏并排的主要操作必须尺寸一致。 +- 使用 SF Symbols 表达刷新、筛选、添加、删除、发送、密钥和状态,不使用文字包住所有图标。 +- 卡片、表格、表单和确认弹窗按 iPhone 动态字体、安全区、横竖屏和 Assistive Access 语义适配。 + +## 功能映射 + +### 实例与节点 + +- 添加、编辑、删除实例,支持名称、地址、标签、分组和实例密码。 +- 连接测试、登录、登出、在线/离线/需登录/降级状态和快照新旧程度。 +- 批量选择、批量测试、批量删除、分组筛选、标签筛选、状态筛选和搜索。 +- 节点资源摘要、手机号、温度、版本、新鲜度和最新短信预览。 +- 删除实例前先尝试释放 Hub 绑定;无法访问时按现有规则区分“跳过释放”与“失败”。 + +### 设备模块 + +实例详情保留上游设备能力模块:总览、蜂窝、SIM、通话、eSIM、WiFi Calling、设备网络、OTA、消息、通知、自动化历史、配置和备份。每个模块按现有上游端点读写,使用统一的加载、空态、无权限、超时和确认流程。 + +高风险动作沿用操作目录中的风险等级和确认文案;系统重启、基带重启、服务重启等动作必须明确显示目标实例。 + +### 消息 + +- 直接拉取实例短信列表、会话、统计和详情。 +- 发送短信、批量删除、清空、按方向筛选和分页。 +- 本地归档跨实例消息,保留方向、号码、内容、时间、状态、来源实例和同步时间。 +- 发送队列保留离线重试记录,但只在前台刷新、进入消息页或用户点击“发送”时处理。 + +### 通知 + +- 管理通知通道、规则、队列和投递日志。 +- 支持基于连接状态、短信和操作事件的手动评估。 +- “立即投递”“重试”“重试全部”“清空”只在应用前台执行。 +- 投递成功、失败和重试状态进入本地队列/日志表。 + +不使用 iOS 远程推送、后台任务调度或常驻网络轮询。 + +### 操作、任务与审计 + +- 移植操作目录、准备/执行两段式协议、确认令牌、版本检查和风险等级。 +- 操作准备写入本地数据库;应用退出时把未完成任务标记为终止或未知结果。 +- 保留任务列表、任务详情、条目结果、尝试记录、取消、重试和手动 reconcile。 +- 审计事件记录操作者、请求、目标、结果、参数摘要和异常原因。 + +定时任务创建与自动触发移除。已有调度模型只保留为历史只读视图;新的“手动执行”入口不创建周期任务。 + +### 日志与系统 + +- 连接日志、运行日志和诊断汇总进入日志中心。 +- 支持筛选、清空、修剪、导出和详情展开。 +- 系统维护显示数据库、组件数量、可回收空间、应用版本和平台信息。 +- 手动清理、`VACUUM`、校验、备份、恢复、导入、导出和删除备份。 +- 自动备份、自动日志修剪和自动数据保留调度移除;保留策略仅作为手动清理的默认参数。 + +### 分组、标签与身份 + +- 设备分组和标签完整本地管理,并用于节点筛选、通知规则和批量操作。 +- 设备身份记录用于识别异常换绑和重复身份,前台刷新时更新。 +- 授权模式支持自动与手动;手动模式在检测到身份变化时要求确认。 + +## 定时能力的移除边界 + +以下行为不实现: + +- 应用启动后的周期网络轮询。 +- iOS 后台任务、静默推送唤醒、常驻 Socket 或后台同步。 +- Cron 表达式解析与周期执行。 +- 自动备份、自动队列投递、自动日志清理。 +- 控制台自更新。 + +以下行为保留: + +- 进入前台、下拉刷新、页面切换或用户点击时执行一次同步。 +- 用户主动触发队列投递、备份、清理和 reconcile。 +- 前台期间页面可见时的按需状态刷新。 + +## 上游访问与安全 + +- 上游请求只允许显式注册的方法和路径,不提供任意 URL 代理。 +- 响应大小、超时、JSON 结构和敏感字段按现有上游网关边界限制。 +- 实例密码存入 Keychain;会话 Cookie 只保存在内存,不写入 SQLite 或日志。 +- 登录会话按实例隔离;修改实例地址后立即清空旧会话。 +- 日志不输出 Cookie、Authorization、密码、确认令牌、完整短信正文或敏感通知配置。 +- 短信和通知正文在列表中支持脱敏显示,详情页按现有显隐交互显示原文。 + +iOS 允许访问用户明确输入的 HTTP SimAdmin 实例地址。设置页必须显示“HTTP 明文传输”警告;HTTPS 和受信任内网地址不做额外降级提示。 + +## 数据模型与迁移 + +SQLite 保留以下核心表,字段可按 Swift 领域模型调整,但不得丢失现有用户语义: + +- 实例:`instances`、`instance_tags`、`tag_registry`、`device_groups`。 +- 状态:`status_snapshots`、`capabilities`、`connection_logs`、`device_identities`。 +- 消息:`sms_messages`、`sms_outbox`。 +- 通知:`notification_channels`、`notification_rules`、`notification_deliveries`、`notification_queue`。 +- 操作:`jobs`、`job_items`、`job_attempts`、`operation_preparations`、`audit_events`。 +- 设置:`app_settings`、维护保留策略。 + +首次启动创建 iOS 版本 1 迁移。不导入现有 Node 服务数据库作为第一版要求;后续可在设置页提供数据库导入兼容层。导入时必须拒绝无法识别的 schema 版本,并在写入前创建安全备份。 + +## 构建 IPA + +新增 Swift Package `apps/ios` 和构建脚本 `scripts/build-ios-ipa.sh`。Swift Package 是 iOS 源码与依赖的单一事实来源,不引入 XcodeGen 或检入的 Xcode 工程文件。 + +1. 使用 `swift build --configuration release --triple arm64-apple-ios16.0` 和 iPhoneOS SDK 编译 `MultiSimAdmin` 可执行文件。 +2. 组装 `Payload/MultiSimAdmin.app`,包含可执行文件、`Info.plist`、资源包和应用图标。 +3. `Info.plist` 声明 iOS 16 最低版本、iPhone 方向、深浅色外观、ATS 例外和启动屏,但不声明后台模式。 +4. 压缩为 `build/ipa/MultiSimAdmin.ipa`。 +5. 输出 IPA 路径、大小和 SHA-256。 + +构建脚本不得要求证书或描述文件。如果目标环境需要伪签名,由用户使用 TrollStore 或自有工具处理;仓库脚本不默认修改二进制签名。 + +## 错误处理 + +- 网络失败显示实例名、可读原因和重试操作,不中断其他实例刷新。 +- 单个实例失败只影响该实例卡片或详情,不使节点总览整页失败。 +- 上游 401 显示“需要登录”,403 显示权限受限,404 显示不支持,超时明确区分网络不可达。 +- 删除、恢复、重启、清空和高风险操作使用统一确认弹窗,显示目标数量与不可恢复提示。 +- 数据库迁移失败时保持只读启动屏,提示备份文件位置,不自动删除旧数据。 + +## 测试与验收 + +XCTest 覆盖: + +- 实例创建、地址校验、版本冲突、密码保存、登录会话隔离和删除补偿。 +- 上游路径白名单、超时、错误状态、Cookie 注入和响应解析。 +- 短信归档、去重、发送、删除、队列前台 flush 和失败重试。 +- 通知规则评估、队列处理、通道投递和日志写入。 +- 操作准备/执行、确认令牌、任务结果、审计和中断任务恢复。 +- 数据库迁移、备份导出、恢复预览和敏感字段排除。 +- UI 层验证核心页面可达、空态/错误态存在、按钮尺寸一致、脱敏状态正确。 + +构建验收: + +- iOS 16 Simulator 可安装并启动。 +- 390、768 和 1024 点宽度下无横向溢出、文字截断或控件重叠。 +- `scripts/build-ios-ipa.sh` 在干净构建目录产出未签名 IPA,并输出 SHA-256。 +- 应用不请求定位、相机、麦克风、通讯录或后台刷新权限。 + +## 非目标 + +- 不实现 App Store 发布、TestFlight、推送证书或开发者签名。 +- 不在 iPhone 上运行 Node.js、Fastify 或现有 SQLite 服务端。 +- 不实现后台常驻、Cron 自动化、自动备份或控制台自更新。 +- 不支持多用户、远程 Web 登录或浏览器访问 iPhone 内的控制面。 +- 不移除实例自身密码能力;只移除 multi-simadmin 的全局访问密码。