本文由 Gideon(AI)翻译自英文原版。
概述与愿景 链接到标题
一款全栈个人财务应用,将繁琐的手动记账转变为快速、智能的工作流程。用户通过拍照、文件上传、粘贴文字或手动录入的方式捕捉收据,AI 模型自动将商家名称、日期、地点以及每一条消费明细提取并整理到一个结构化、可编辑的数据库中。数据也可直接从 Costco 购买历史 API 获取,或通过 CSV 文件导入。最终呈现的是一份始终保持最新的个人消费台账——可搜索、可导出,并通过图表可视化——可在本地网络中的任何设备(包括手机)上访问。
愿景: 让记账变得足够轻松,让人们真正愿意去做,消除"我待会儿再记"与"结账时没有记录"之间的落差。
问题陈述 链接到标题
手动记账方式存在根本性缺陷:
- 纸质收据在被记录之前就已经丢失、褪色或被遗忘
- 表格录入既慢又容易出错,导致人们逐渐放弃
- 银行账单导出过于粗略——只显示商家总金额,而非单独的消费条目
- 现有应用需要订阅、云账号或向第三方共享数据
- 收据照片堆积在相册中,从未被整理成可用的数据
用户需要一款私有、自托管的工具,以最小的努力将任何收据——无论是实体还是电子版——转化为结构化、可查询的消费数据。
目标用户 链接到标题
主要用户:
- 希望对消费进行逐项管理、而不想订阅 SaaS 产品的个人或家庭
- 跟踪个人可报销费用的小企业主或自由职业者
需求与功能 链接到标题
收据录入
- 通过拖放或文件选择器上传图片文件(JPG、PNG、WEBP、HEIC、GIF)
- 直接从设备摄像头拍照(移动端友好;需要 HTTPS)
- 粘贴原始收据文字供 AI 解析
- 手动录入收据,包含头部字段(商家、日期、地点)和内嵌明细表格
AI 智能解析
- 将收据图片或文字发送至可选的 AI 模型:Anthropic Claude、OpenRouter、DeepSeek 或 Gemini(通过环境变量配置)
- 提取:商家名称、日期、地点、小计、税额、总额,以及所有明细(描述、数量、单价、总价、分类)
- 鲁棒的 JSON 提取机制,能处理包裹在散文或 Markdown 代码块中的模型响应
- max_tokens 设置为 4096,防止大型收据被截断
交易管理
- 在可搜索、可筛选的表格中查看所有明细
- 可对单张收据或全局切换只读/编辑模式
- 编辑模式下:内联修改任意字段(文字、数字、日期/时间、分类下拉)
- 向已有收据添加新明细
- 删除单条明细(立即生效)或批量删除选中行(保存时生效)
- 通过弹出框对所有选中行的某一列进行批量更新
- 将更改保存至 SQLite 数据库;所有更改按每次"保存"操作进行原子提交
- 将所有交易导出为 CSV
月度视图
- 按日历月份对消费进行分组展示
- 进度条可视化显示消费额与前期的对比
- 月份选择器,可浏览历史记录
分析
- 柱状图:每月消费总额
- 饼图:按分类划分的消费占比
- 折线图:消费趋势随时间的变化
- 商家消费明细表和每日消费明细
Costco 集成
- 输入 Bearer Token、Client ID 和 Client Identifier(从浏览器开发者工具中获取)
- Token 有效期徽章:实时倒计时显示剩余有效时间(Token 15 分钟后过期),状态颜色为绿/橙/红
- 获取模式:最近 N 天(7 / 14 / 30 / 60 / 90)或自定义日期范围(起始/截止日期选择器)
- 发现步骤:连接 Costco GraphQL API,对一张收据进行采样,列出所有可用字段及实时示例值
- 字段映射步骤:用户将每个 Costco 条目字段映射至应用列(描述、单价、总价、数量、分类,或跳过)
- 预览步骤:列出所有收据,并标记已导入项(通过 source_id 去重)
- 导入步骤:按条形码逐张获取完整收据详情,应用字段映射后保存至数据库
CSV 导入
- 上传任意 CSV 文件
- 根据常见列名别名(date、amount、merchant 等)自动检测列映射
- 手动映射 UI,附带实时预览行
- 导入时,按商家-日期分组创建对应收据及所有匹配明细
手动录入收据
- “添加收据"下的第四个标签页:手动录入
- 收据头部:商家(必填)、日期、地点
- 内嵌表格:可添加/删除行;列与交易表格一致(日期、描述、数量、单价、总价、分类)
- 表格底部自动计算合计金额
- 保存后在数据库中创建完整的收据和明细记录
基础设施
- HTTPS 开发服务器(自签名证书),供本地网络内的摄像头访问使用
- SQLite 数据库,含 receipts 和 line_items 表;source_id 列带有唯一部分索引以实现去重
- 四个 AI 提供商均为懒加载初始化,避免 dotenv 加载顺序问题
- 前后端通过单个
./start.sh命令同时启动
用户故事与验收标准 链接到标题
故事 1 — 通过摄像头拍照录入收据 作为手机用户,我希望拍一张收据照片,使其自动解析成消费明细。
- 摄像头标签页通过 HTTPS 激活设备后置摄像头
- 拍摄的图片发送至 AI;在标准网络连接下,10 秒内解析结果出现在交易审核面板中
- 收据上所有可见的明细均显示为可编辑行
故事 2 — 编辑并保存解析后的明细 作为用户,我希望能纠正 AI 解析的错误,并将结果保存至数据库。
- 点击编辑后,所有字段切换为内联输入框
- 修改值后点击保存,将其持久化至 SQLite 并返回只读模式
- 在同一收据内意外跳转时,未保存的更改不会丢失
故事 3 — 批量删除交易 作为用户,我希望选中多行并一次性删除。
- 选中所有行后点击删除,立即从 UI 中移除
- 点击保存后从数据库中删除;保存后不再重新出现
- 批量删除后取消编辑,原始行将恢复
故事 4 — 批量更新某列 作为用户,我希望一次性为 20 条选中的行设置相同的分类。
- 点击列标题按钮,打开该列的弹出框
- 输入值并确认后,更新所有选中行(或未选中时更新所有可见行)
- 更改立即反映在表格中,并在保存时持久化
故事 5 — 从 Costco 导入 作为 Costco 会员,我希望自动导入我的门店购买历史。
- 输入凭证并点击连接后,5 秒内获取收据并发现可用字段
- Token 有效期徽章实时显示剩余有效时间;15 分钟后变红
- 自定义日期范围选择器允许我选择任意起止时间窗口
- 已导入的收据被标记;只有新收据可被选择
- 导入完成后,所有明细出现在交易视图中
故事 6 — 手动录入收据 作为没有照片的用户,我希望直接手动输入收据内容。
- 手动录入标签页显示商家/日期/地点的头部表单,以及可编辑的明细表格
- 点击”+ 添加行"追加一条新的可编辑行;点击 🗑 删除某行
- 点击"保存收据"在数据库中创建记录,并在交易视图中显示该收据
故事 7 — 查看消费分析 作为用户,我希望按分类和月份查看我的消费去向。
- 分析标签页显示由实际数据库数据生成的柱状图、饼图和折线图
- 在月度视图中切换月份,将更新所有图表和进度条
技术栈 链接到标题
| 层级 | 技术 |
|---|---|
| 前端 | React 18 + TypeScript |
| 构建工具 | Vite + @vitejs/plugin-basic-ssl(HTTPS) |
| 样式 | 由 AI 决定 |
| 图表 | Recharts(柱状图、饼图、折线图) |
| HTTP 客户端 | Axios |
| 文件上传 | react-dropzone |
| 后端 | Node.js + Express(ES Modules) |
| 数据库驱动 | 暂时轻量,按需选择 |
| 文件处理 | 由 AI 决定 |
| AI — Anthropic | @anthropic-ai/sdk · Claude claude-opus-4-6(视觉) |
| AI — OpenRouter | OpenAI 兼容 · 多模型,支持视觉 |
| AI — DeepSeek | OpenAI 兼容 · 仅文字(不支持视觉) |
| AI — Gemini | OpenAI 兼容 · 支持视觉 |
| 数据库 | SQL 或单一 JSON 文件 |
| 外部 API | Costco ecom-api.costco.com · GraphQL |
数据库结构:
receipts:id、image_path、merchant、date、location、total、raw_response、source_id、created_atline_items:id、receipt_id、description、quantity、unit_price、total_price、category、date、merchant、location
成功标准 链接到标题
功能性
- 在手机上拍摄的收据照片,端到端在 15 秒内生成正确分类的明细
- 对任意字段的编辑和保存能够正确持久化至数据库,并在完整页面刷新后仍然有效
- 批量删除所有行并保存后,交易表格为空,无残留数据
- Costco 导入正确去重已导入的收据,仅导入新收据
- 分析图表无需手动刷新即可反映当前数据库状态
可靠性
- AI 响应解析成功,即使模型将 JSON 包裹在散文、代码块或说明性文本中(多阶段 extractJSON 函数)
- Token 过期通过倒计时徽章提前告知用户,避免在导入过程中意外出现 401 错误
- 所有 API 失败均显示可见的错误提示;不允许静默吞噬错误
性能
- 应用在本地网络连接下 2 秒内加载完成
- 针对最多 10,000 条明细,SQLite 查询在 100 毫秒内返回结果
自托管简便性
- 全栈通过单一命令(
./start.sh)启动 - 无需云账号、无需订阅、无需外部数据库
- 可在本地 Wi-Fi 网络上通过 iOS 和 Android 移动浏览器(HTTPS)访问
Claude Code 总结 链接到标题
个人记账应用是一款自托管、AI 驱动的收据追踪系统,专为那些希望对消费进行逐项精细管理、同时不依赖云服务或付费订阅的个人用户而设计。
这款应用的核心,是填补银行账单导出和记账应用所留下的空白:它们告诉你在 Costco 花了 359 美元,却不告诉你其中 87 美元是一箱橄榄油。通过结合 AI 视觉解析、直接的 Costco API 集成,以及完全可编辑的交易台账,该应用将每一张收据——无论是拍照、手动输入、粘贴文字还是从零售商 API 获取——都转化为结构化、可查询的数据。
该系统刻意保持务实:它在 MacBook 或家用服务器上本地运行,可通过同一 Wi-Fi 网络上的任意手机访问,所有数据存储在一个易于备份的 SQLite 文件中。AI 层可在四个提供商之间自由切换,确保用户不被某一个厂商锁定。Costco 集成体现了真实的使用场景——很多家庭会在大型仓储超市进行大量采购,这些消费值得在条目级别加以追踪,而不仅仅是收据总额。
技术栈采用 React、TypeScript、Node.js、Express 和 SQLite,选择刻意简洁:文档完善、易于理解、便于扩展。UI 优先考虑录入速度和纠错的便捷性——因为目标是让记录消费的过程足够快,让人们能够持之以恒地坚持下去。