一个人的家庭账本:从第一性原理设计记账系统

一个人的家庭账本:从第一性原理设计记账系统

记账软件很多,但没有一个按我的口径算账。佣金、贷款、信用卡、年付订阅混在一起,算出来的“本月支出”总是不对。所以我自己搭了一个:老乔的账房。

第一性原理

账房只回答三个问题:

  1. 钱从哪来——工资、客户佣金、投资盈亏。
  2. 钱去了哪——真实消费,按分类。
  3. 还欠多少——贷款剩余本金、信用卡欠款。

其余一切,都是为了让这三个数字准确。准确的前提只有一条:同一笔钱只算一次。

结构

五个入口,一个主按钮。

  • 总览:本月收支、银行余额、贷款剩余本金、信用卡欠款。
  • 流水:全部流水与佣金。服务端分页,每页 50 条;筛选后的合计按全量计算,不受分页影响。
  • 图表:收支趋势与分类构成。
  • 资产:贷款、信用卡、订阅。
  • 设置:账户、分类、导入、说明。
  • 记账:唯一的主按钮,随时记一笔。

记账口径

口径是账房的核心。规则写死在系统里,也写在“说明”页上。

  • 信用卡:刷卡记支出;还款不计收支,只减少欠款。欠款 = 刷卡支出 − 还款。还款不必选来源账户。
  • 花呗 / 借呗:本金不计收支,利息记支出。
  • 房贷 / 车贷 / 银行贷款:每次还款拆成本金和利息。利息记支出;本金不是消费,只减少剩余本金。
  • 房贷本金待补:本金尚未录入时显示“待补”,而不是 ¥0。总览只合计已知本金,并标注待补项;补录后自动纳入。
  • 年付订阅:图表按 ÷12 摊销;实际付款记“不计收支”,避免重复计算。总览里的“订阅摊销”仅作年度概览参考,不计入本月支出。
  • 月付订阅:只按实际扣款记支出,不再摊销。
  • 收入:工资、客户佣金、股票盈亏按分类手动录入,佣金也支持表格导入。
  • 支付宝导入:按交易号去重;交易关闭的跳过;退款冲减支出;“不计收支”不进合计。
  • 账户余额:在设置里维护,带“截至”日期的余额参与总览银行合计。

数据与安全

  • 数据一等:账户可增、改、停用,余额是一等数据,不由流水推算。
  • 随时带走:流水可导出 CSV 和 Excel。
  • 每日备份:服务器每天凌晨自动备份数据库;每次大改前另做全量备份。
  • 登录保护:密码哈希存储,连续失败自动限流,所有表单带 CSRF 校验。

技术

FastAPI + Jinja2 + SQLite,单机部署,Nginx 反代,systemd 守护。没有前端框架,没有外部数据库。一个人的账本,不需要更多。

代码按职责拆成路由、服务、模板三层;每次改动跑自动化测试,全部通过才上线。

今天定型的内容

今天按四个阶段把账房从“能用”改到“可信”:

  1. 安全与基础:登录限流、CSRF、备份机制。
  2. 结构重构:代码拆分为模块,平滑切换上线。
  3. 视觉与交互:五项导航加一个主按钮,桌面与手机都能用。
  4. 功能与口径:账户管理、导出、每日备份、贷款拆本金/利息、年付摊销、房贷待补。

外加三个补丁:流水分页、贷款“记一笔还款”改为按钮、信用卡还款去掉来源账户。

还没做的

  • 房贷剩余本金待补录。
  • 年付摊销目前只作概览参考,是否进入月度支出口径,后续再定。

账房不追求功能多。它只要求一件事:打开它,看到的每个数字都是对的。