Skip to content

Latest commit

 

History

History
425 lines (309 loc) · 17.7 KB

PLAN.md

File metadata and controls

425 lines (309 loc) · 17.7 KB

Pace 项目规划

1. 项目定位

  • 项目名称:Pace
  • 产品定位:原生 Android + 原生 iOS 的每日预算记账 App。
  • 核心价值:让用户随时知道今天还可以花多少钱,并用尽量少的操作记录账单。
  • 产品口号:Know what you can spend today.
  • 隐私定位:账本数据只保存在用户设备本地;用户主动导出后,导出文件由用户自行管理。
  • AI 定位:AI 是可选的输入和分析辅助,不是账本事实来源,也不能绕过用户确认直接写入账本。

2. 仓库与协作

  • 主仓库:https://github.com/CarlOpenLab/pace.git
  • 当前分支:main
  • 协作方式(2026-10-26 改:不再走 Pull Request):
    1. 有仓库写权限时,做完的改动直接提交并推送 main,不另开分支、不提交 Pull Request。
    2. 没有仓库写权限时,Fork CarlOpenLab/pace,在 Fork 中开发,再向上游 main 推送。
    3. 不绕 PR 不等于不用验:谁推送谁负责把该截的图、该量的数放进频道,出了问题是当场能说清哪一步漏的。半成品不推。
    4. 发布:版本号在三处一起改(iosApp/project.yml 的 MARKETING_VERSION、README 徽标、CHANGELOG),打完 tag 再推。
  • 当前仓库状态:现有代码是 React + TypeScript + Vite 的离线优先 Web/PWA 原型,包含本地 IndexedDB、账单导入、分类和统计能力。目标产品需要逐步演进为原生 Android 与原生 iOS App;现有 Web 原型可作为业务规则、数据模型和交互验证参考,不能视为最终移动端实现。

3. 目标平台与技术方向

Android

  • Kotlin + Jetpack Compose。
  • Room/SQLite 保存本地账本。
  • Android Keystore 保护本地加密密钥。
  • WorkManager 处理可延迟的本地维护任务。
  • Android Notifications、App Widget、快捷方式和系统分享入口使用原生能力。

iOS

  • Swift + SwiftUI。
  • SwiftData/Core Data/SQLite 保存本地账本,最终只选一种实现。
  • Keychain 与系统 Data Protection 保护敏感数据。
  • BackgroundTasks 处理可延迟的本地维护任务。
  • WidgetKit、App Intents、Share Extension 使用原生能力。

跨端共享内容

两个客户端不共享 UI 运行时,但必须共享以下产品契约:

  • 数据字段和枚举定义。
  • 金额、日期、时区和货币规则。
  • 预算计算规则。
  • AI 草稿输入输出格式。
  • 导出 JSON 格式及版本迁移规则。
  • 重复账单检测规则。
  • 错误状态和验收案例。

4. 核心业务范围

4.1 每日预算

第一版采用固定每日预算:

今日剩余 = 今日预算 - 今日计入预算的净支出

规则:

  • 当日结余默认不结转到下一天。
  • 当日超支默认不自动扣减明日预算。
  • 修改默认预算从指定生效日开始,不重写历史预算。
  • 每笔支出可选择是否计入每日预算。
  • 不计入每日预算的支出仍计入总支出统计。
  • 首页必须展示预算、已花、剩余/超支及计算说明。
  • 预算引擎不依赖网络和 AI。

后续再评估动态周期预算:

周期剩余预算 / 周期剩余天数(含今天)

固定预算和动态预算必须作为明确的模式选择,不能同时展示含义不清的多个“剩余”数字。

4.2 账单

第一版支持:

  • 支出、收入、退款、转账类型。
  • 金额、货币、分类、发生时间、归属日期、备注。
  • 是否计入每日预算。
  • 新增、编辑、删除、撤销。
  • 补记历史账单。
  • 待分类账单。
  • 分类管理和最近使用分类。
  • 退款关联原账单,避免重复计算。
  • 转账和信用卡还款与消费分开,避免重复计入。

金额在内部使用最小货币单位保存,例如分;展示层再格式化金额,避免浮点误差。

4.3 统计

第一版支持:

  • 今日账单。
  • 按日期查看账单。
  • 本周和本月总支出。
  • 预算内支出与全部支出分开统计。
  • 分类排行。
  • 每日预算和实际支出对比。
  • 超支记录。

统计数字由本地确定性程序计算。AI 只能解释已经计算出的结果,不能自行替代账本查询和金额计算。

5. 本地数据与导出

5.1 本地-only 原则

  • 不建立云端账本数据库。
  • 不要求注册账号才能记账。
  • 断网时完整支持新增、编辑、删除、预算计算和统计。
  • 正式账本只以设备本地数据库为事实来源。
  • 服务端(如未来存在 AI 网关)不得持久化完整账本。
  • 日志不得写入完整账单、备注、票据内容或 API 密钥。
  • App 删除、设备损坏或未导出时,用户需要承担本地数据丢失风险;产品必须在设置和导出流程中明确说明。

5.2 导出

第一版必须支持:

  • CSV:便于 Excel、Numbers 等工具查看和分析。
  • JSON:包含完整账单、分类、预算规则、历史预算版本、货币、时区、退款关联和格式版本号,用于恢复。

导出流程:

  1. 用户主动选择导出格式。
  2. App 在本地生成文件。
  3. 通过 Android 文件选择器/分享面板或 iOS Files/分享面板交给用户保存。
  4. App 清理临时文件,不自动上传。

必须提示:用户若将文件保存到 iCloud Drive、Google Drive、微信或其他服务,导出副本将由对应服务管理,不再属于 App 的本地存储范围。

5.3 导入与恢复

虽然产品定位是本地账本,但 JSON 导入必须纳入第一版,否则导出不能承担真正的备份作用:

  • 支持从 JSON 或加密备份恢复。
  • 导入前预览账单数量、日期范围和预算设置。
  • 先校验整个文件,校验通过后再写入,不能因部分失败破坏现有账本。
  • 通过稳定 ID 和指纹检测重复记录。
  • 默认提供“合并到现有账本”和“替换当前账本”两个明确操作;替换前必须再次确认。
  • CSV 第一版主要用于查看和交换,不承诺能恢复所有预算关联信息。
  • 后续增加用户密码保护的加密备份文件。

6. AI 设计

6.1 首发 AI:自然语言生成待确认草稿

示例输入:

昨天午饭 28 元,晚上打车 16 元。

AI 应返回结构化草稿,至少包含:金额、类型、日期、分类、备注、是否计入预算、需要补充的信息。

流程固定为:

输入 → 解析 → 本地业务校验 → 待确认草稿 → 用户确认 → 本地正式入账

规则:

  • AI 不能直接新增、修改或删除正式账单。
  • 金额不明确、日期不确定或个人分摊不清楚时,必须要求用户补充。
  • 用户可逐笔修改草稿。
  • AI 失败、超时或无网络时必须回退到手动记账。
  • 重复点击确认不能产生重复账单。

6.2 隐私模式

提供两个明确模式:

  1. 本地隐私模式:账本内容不离开设备;使用手动记账,后续可评估设备端模型。
  2. AI 辅助模式:用户主动开启后,仅发送完成当前任务所需的输入或用户选定内容;正式账本仍只保存在本地。

默认采用本地隐私模式。开启云端 AI 前必须说明:当前输入可能离开设备,且第三方模型服务的处理规则由其服务条款决定。

现有 Web 原型中的 AI 分类接口需要按此规则重构:不能把完整账单历史默认发送给外部接口,也不能把用户 API Key 作为未来原生 App 的默认方案长期保存在客户端。

6.3 后续 AI 能力

按优先级推进:

  1. 一句话记账。
  2. 分类建议。
  3. 用户主动上传的截图/小票识别。
  4. 自然语言查询本地统计。
  5. 基于程序统计结果的消费复盘。
  6. 预算调整建议,仅生成方案,不自动修改设置。

7. 原生双端页面

两个平台核心页面保持同一业务信息和计算结果,但交互遵循各自平台规范:

  1. 首页:今日剩余/超支、预算、已花、记一笔、今日账单。
  2. 记账页:金额、分类、日期、备注、预算归属;支持 AI 输入。
  3. 账单页:按日期浏览、搜索、筛选、编辑和删除。
  4. 统计页:周/月、分类、预算对比。
  5. 预算设置:额度、模式、生效日期、预算归属默认值。
  6. 分类设置:新增、编辑、排序、默认归属。
  7. 导出与恢复:CSV、JSON、导入预览、数据删除。
  8. 隐私与 AI 设置:AI 模式、授权说明、日志与数据清理说明。

平台增强能力:

  • Android:桌面小组件、快捷方式、通知栏快速记账、系统分享入口。
  • iOS:主屏幕/锁屏小组件、Siri/App Intents、Share Extension、通知和后台刷新。

8. 开发阶段

阶段 0:需求和规则冻结

产出:

  • 预算规则文档。
  • 数据模型和枚举。
  • 跨端 JSON 导出格式。
  • AI 草稿格式。
  • Android/iOS 页面流程和设计稿。
  • 边界案例清单。

验收:任何账单变更都能说明如何影响预算、统计和导出文件。

阶段 1:本地账本核心

  • Android 与 iOS 原生工程。
  • 本地数据库和数据迁移。
  • 预算引擎。
  • 手动记账。
  • 编辑、删除、撤销。
  • 首页、账单页、统计页。
  • 断网可用。

验收:重启 App、补记、编辑、删除、退款和跨日期后,两个平台的计算结果一致。

阶段 2:导出与恢复

  • CSV 导出。
  • 完整 JSON 导出。
  • JSON 导入预览和恢复。
  • 重复检测和事务性写入。
  • 数据删除和清空流程。

验收:导出后在全新安装环境恢复,账单、预算和统计结果保持一致。

阶段 3:可选 AI

  • 文本解析。
  • 多笔草稿。
  • 字段校验和追问。
  • 用户确认入账。
  • AI 关闭和失败回退。
  • 隐私提示。

验收:AI 只生成草稿;不明确的金额/日期不会被擅自写入;网络失败不影响手动记账。

阶段 4:原生体验增强

  • Android/iOS 小组件。
  • 系统分享入口。
  • 快捷记账。
  • 本地提醒。
  • 深色模式和无障碍适配。

阶段 5:发布准备

  • 真机测试和弱网测试。
  • 时区、午夜、跨年和货币测试。
  • 导出文件兼容性测试。
  • 隐私政策、权限说明和数据删除说明。
  • App Store 与 Google Play 发布资料。

9. 明确不纳入首发

  • 云端账本同步。
  • 银行、微信、支付宝自动读取流水。
  • 自动读取短信。
  • 家庭共享和多人账本。
  • 投资、借贷、资产负债管理。
  • 多币种汇率核算。
  • AI 自动修改或删除账单。
  • 复杂的周期预算和自动省钱承诺。

10. 关键验收标准

  • 飞行模式下可以完整手动记账和查看今日剩余。
  • Android 与 iOS 对同一组案例得出相同预算结果。
  • 账本不会因 AI 不可用而无法使用。
  • CSV 导出可被常用表格工具打开。
  • JSON 导出可以在新安装环境恢复完整账本。
  • 导入失败不会破坏已有数据。
  • App 不保存云端账本副本。
  • AI 默认关闭,开启前有明确的数据流向说明。
  • 用户确认前的 AI 结果永远只是草稿。
  • 删除、导出和恢复操作都有清晰的用户确认与错误提示。

11. 当前实施顺序

  1. 以本文件冻结 Pace 的产品边界和本地-only 原则。
  2. 从现有 Web 原型提取可复用的分类、解析、去重和统计业务规则。
  3. 先实现原生 Android/iOS 的本地账本闭环,不先做云服务。
  4. 再实现 CSV/JSON 导出和恢复。
  5. 最后接入可选 AI 草稿流程与平台专属能力。

12. 技术栈决策

Pace 采用“共享业务核心 + 双端原生 UI”的方案,满足 Android 和 iOS 都是原生客户端的要求,同时避免预算计算、导出恢复和日期规则在两端重复实现后产生差异。

12.1 客户端

  • Android:Kotlin + Jetpack Compose。
  • iOS:Swift + SwiftUI。
  • Android 状态与异步:ViewModel、Kotlin Coroutines、Flow、Navigation Compose;依赖注入优先使用 Hilt。
  • iOS 状态与异步:Observation/ObservableObject、Swift Concurrency、NavigationStack。
  • 本地数据库:SQLDelight + SQLite,Android 和 iOS 共用数据库结构与迁移版本;不同时引入 Room、SwiftData 和 Core Data。
  • 序列化:Kotlin Serialization,负责共享数据模型、JSON 导出格式和 AI 草稿协议。
  • 系统能力:Android 使用 Notifications、WorkManager、App Widget、快捷方式和 Storage Access Framework;iOS 使用 UserNotifications、BackgroundTasks、WidgetKit、App Intents、Share Extension 和 Files/Share Sheet。

12.2 共享核心

使用 Kotlin Multiplatform 共享以下模块,UI 和平台系统能力不共享:

shared/
├── money/       # 最小货币单位、金额计算与格式化规则
├── budget/      # 每日预算和后续动态预算
├── transaction/ # 账单模型、类型、退款和转账关联
├── statistics/  # 本地确定性统计
├── export/      # CSV/JSON 导出与版本迁移
├── import/      # 导入校验、预览、去重和事务性恢复
├── date-time/   # 时区、归属日和午夜边界
└── validation/  # 账单和预算业务校验

共享核心必须提供稳定、容易被 Swift 调用的 API;避免把复杂 Kotlin 内部实现类型直接暴露给 iOS。Android 与 iOS 对同一组预算案例必须得到相同结果。

12.3 金额与时间

  • 金额禁止使用 Double 作为账本计算类型。
  • 账单金额保存为最小货币单位的 Long,同时保存 currency。
  • 账单至少保存 occurredAt、localDate、timezone、createdAt 和 updatedAt。
  • 预算按用户时区的 localDate 计算,不能依赖服务器时间。
  • 导入、导出和 AI 解析都必须经过共享核心校验。

12.4 本地数据保护

  • Android 使用 Android Keystore 保护本地加密密钥。
  • iOS 使用 Keychain 和系统 Data Protection 保护敏感数据。
  • 正式账本只写入设备本地数据库,不建立云端账本同步服务。
  • 导出文件由用户主动通过系统文件选择器或分享面板保存;App 不自动上传。
  • 数据库迁移、备份恢复和加密导出必须可测试、可回滚或在失败时保持原数据不变。

13. AI 与 GLM 实施计划

后续使用 GLM 协助实现时,必须先以本文件及预算规则、数据模型、导出格式、AI 隐私规范为约束,不以生成代码替代产品规则确认。

13.1 AI 边界

  • AI 默认关闭,手动记账和本地统计不能依赖 AI。
  • AI 首发能力是“自然语言生成待确认账单草稿”。
  • AI 只能返回结构化草稿,不能直接写入、修改或删除正式账单。
  • 本地共享核心负责字段校验、金额计算、日期归属、重复检测和最终入账。
  • 金额、日期、分摊或账单类型不明确时,必须要求用户补充,禁止猜测。
  • AI 超时、网络失败、模型返回格式错误时,必须回退到手动记账。

13.2 GLM 接入方式

  • GLM 通过可替换的 AI Provider 接口接入,不把模型调用散落在页面或数据库代码中。
  • 模型密钥、请求地址和模型名称不能硬编码进原生客户端;如果使用远端 GLM 服务,密钥由受控服务端或用户明确配置的本地代理管理。
  • GLM 请求只携带完成当前任务所需的用户主动提交内容;默认不发送完整账本历史。
  • GLM 返回后先在本地解析为版本化草稿协议,再经过共享核心校验,最后进入用户确认页面。
  • 需要记录模型版本、协议版本和解析失败原因,但日志不得记录完整消费内容、备注、票据或密钥。
  • 如果要求“任何账本内容都不能离开设备”,则不得调用远端 GLM;只能使用设备端模型或本地规则解析。

13.3 GLM 开发顺序

  1. 先完成纯手动、本地离线记账闭环。
  2. 定义 AI 草稿 JSON Schema 和错误码。
  3. 用本地假数据实现 Provider 接口和确认流程,不连接真实模型。
  4. 接入 GLM,并验证结构化输出、拒答、不确定字段和超时回退。
  5. 用固定测试样例比较 Android/iOS 的解析和预算结果。
  6. 通过用户主动开启的隐私模式上线,不默认开启远端 AI。

13.4 给 GLM 的实现约束

每个实现任务应明确:

  • 修改范围和不应修改的目录。
  • 输入输出契约。
  • 离线行为和错误处理。
  • 数据是否允许离开设备。
  • 验收案例。
  • 需要运行的测试或真机验证。

GLM 生成代码后必须人工检查数据库迁移、金额精度、时区边界、导入事务、重复入账和隐私数据流;不能仅以“能编译”作为完成标准。

14. 推荐仓库结构

pace/
├── shared/          # Kotlin Multiplatform 共享业务核心
├── androidApp/      # Kotlin + Jetpack Compose 原生 Android 客户端
├── iosApp/          # Swift + SwiftUI 原生 iOS 客户端
├── web-prototype/   # 现有 Web/PWA 原型,迁移期间仅作参考
├── docs/
│   ├── BUDGET_RULES.md
│   ├── DATA_MODEL.md
│   ├── EXPORT_FORMAT.md
│   └── AI_PRIVACY.md
├── PLAN.md
└── README.md

当前 Web 原型尚未按该目录重组。重组前必须先保留可运行基线,并分阶段迁移,避免为了目录形式一次性破坏现有验证能力。

15. 技术栈验收标准

  • Android 使用 Jetpack Compose,iOS 使用 SwiftUI;不使用 Flutter 或 React Native 作为最终客户端 UI。
  • 预算、金额、日期、统计、导入和导出核心逻辑由 Kotlin Multiplatform 共享。
  • Android 和 iOS 对同一组固定案例输出一致。
  • 断网时手动记账、预算和统计完整可用。
  • CSV/JSON 导出和 JSON 恢复不依赖服务器。
  • GLM 不可用时 App 仍完整可用。
  • GLM 结果在用户确认前永远是草稿。
  • 远端 GLM 默认关闭,开启前显示明确的数据流向和隐私说明。