本文由 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_at
  • line_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 优先考虑录入速度和纠错的便捷性——因为目标是让记录消费的过程足够快,让人们能够持之以恒地坚持下去。