一个人的家庭账本:从第一性原理设计记账系统
记账软件很多,但没有一个按我的口径算账。佣金、贷款、信用卡、年付订阅混在一起,算出来的“本月支出”总是不对。所以我自己搭了一个:老乔的账房。
第一性原理
账房只回答三个问题:
- 钱从哪来——工资、客户佣金、投资盈亏。
- 钱去了哪——真实消费,按分类。
- 还欠多少——贷款剩余本金、信用卡欠款。
其余一切,都是为了让这三个数字准确。准确的前提只有一条:同一笔钱只算一次。
结构
五个入口,一个主按钮。
- 总览:本月收支、银行余额、贷款剩余本金、信用卡欠款。
- 流水:全部流水与佣金。服务端分页,每页 50 条;筛选后的合计按全量计算,不受分页影响。
- 图表:收支趋势与分类构成。
- 资产:贷款、信用卡、订阅。
- 设置:账户、分类、导入、说明。
- 记账:唯一的主按钮,随时记一笔。
记账口径
口径是账房的核心。规则写死在系统里,也写在“说明”页上。
- 信用卡:刷卡记支出;还款不计收支,只减少欠款。欠款 = 刷卡支出 − 还款。还款不必选来源账户。
- 花呗 / 借呗:本金不计收支,利息记支出。
- 房贷 / 车贷 / 银行贷款:每次还款拆成本金和利息。利息记支出;本金不是消费,只减少剩余本金。
- 房贷本金待补:本金尚未录入时显示“待补”,而不是 ¥0。总览只合计已知本金,并标注待补项;补录后自动纳入。
- 年付订阅:图表按 ÷12 摊销;实际付款记“不计收支”,避免重复计算。总览里的“订阅摊销”仅作年度概览参考,不计入本月支出。
- 月付订阅:只按实际扣款记支出,不再摊销。
- 收入:工资、客户佣金、股票盈亏按分类手动录入,佣金也支持表格导入。
- 支付宝导入:按交易号去重;交易关闭的跳过;退款冲减支出;“不计收支”不进合计。
- 账户余额:在设置里维护,带“截至”日期的余额参与总览银行合计。
数据与安全
- 数据一等:账户可增、改、停用,余额是一等数据,不由流水推算。
- 随时带走:流水可导出 CSV 和 Excel。
- 每日备份:服务器每天凌晨自动备份数据库;每次大改前另做全量备份。
- 登录保护:密码哈希存储,连续失败自动限流,所有表单带 CSRF 校验。
技术
FastAPI + Jinja2 + SQLite,单机部署,Nginx 反代,systemd 守护。没有前端框架,没有外部数据库。一个人的账本,不需要更多。
代码按职责拆成路由、服务、模板三层;每次改动跑自动化测试,全部通过才上线。
今天定型的内容
今天按四个阶段把账房从“能用”改到“可信”:
- 安全与基础:登录限流、CSRF、备份机制。
- 结构重构:代码拆分为模块,平滑切换上线。
- 视觉与交互:五项导航加一个主按钮,桌面与手机都能用。
- 功能与口径:账户管理、导出、每日备份、贷款拆本金/利息、年付摊销、房贷待补。
外加三个补丁:流水分页、贷款“记一笔还款”改为按钮、信用卡还款去掉来源账户。
还没做的
- 房贷剩余本金待补录。
- 年付摊销目前只作概览参考,是否进入月度支出口径,后续再定。
账房不追求功能多。它只要求一件事:打开它,看到的每个数字都是对的。