尝试独立开发的我,给父亲做了个农田管理应用
起点
我的父亲在临近退休的前一年,承包了一小片农田,大约40亩。用他的话说叫找点事干,等下一年退休了就是熟手了,万一玩不转也可以迅速掉头去当保安。看他兴致勃勃,我也只能做一些精神鼓励。
一天晚上我看他饭也不吃,就在翻自己的记录,这里多少钱那里多少钱,有时候还要去对账单。正好我在练习写代码,觉得这是一个很好的实战机会,便自告奋勇承担起了开发一个应用来帮他管理的责任。
一开始我认为这是个非常简单的应用,一些增删改查足够了。即使我几乎不会代码,照着文档做一个 CRUD Boy 还不是手到擒来。但我没想到这几乎是一个无底洞,耗费了我大量精力。不过作为练习工具依然非常值得。不如就叫它 My Farming 吧!
应用设计
最开始,应用的设计很简单,独立开发三件套之记账。“我在 X 年 X 月 X 日进行播种活动,消费 400 元”,这太简单了对吧?当我把这个想法跟我的用户一提,我的用户说:“对的没错,种子400元,人工400元。”
怎么还有人工?简单,800元,打个人工标签,打个种子标签,记账不都是这么做的。
“我前几天找熟人帮我找人,请吃饭花了200。”
诶,怎么还有前几天的事?麻烦起来了——如果再回头修改那一笔支出,没办法区分到底钱花在哪里了,而且要手动计算 400+400+200=1000。这很不优雅。
所以我计划将播种作为一个独立的活动,然后在其中关联支出。支出不作为标签存在,而是一条单独的数据,这样就变成了”我在 X 年 X 月 X 日进行播种活动,关联支出:种子 400 元,人工 400 元”。未来如果要修改,就修改”播种”这条记录而不是直接修改财务流水,在播种的关联里新增一笔人工 200 元。
敲定后,业务逻辑是这样的:点击新增农事活动,填入表单,保存,大功告成——了吗?
开始开发
第一阶段:Next.js + SQLite
没错,第一阶段。
设计数据库,seed,开始开发,本地验证,一气呵成,新的问题来了。
播种,你播种了什么?播种在哪块地上?我明年打算再包一块地,你这不够啊。
好吧,继续设计数据库,增加地块,增加作物名称。Seed,开发,验证,一气呵成!
不对啊,我种了玉米,怎么施肥的时候又给花生施肥了?我在地块上把玉米改成花生,播种记录里怎么还是玉米啊?
修改数据约束,业务逻辑,seed,开发,验证,一气呵成!
不对啊,我这里怎么能播种两次啊?我咋看今年花了多少钱啊?我咋看玉米挣了多少钱花生挣了多少钱啊?不对啊……
我意识到,我需要重新梳理业务,不能做一个简单的记账工具。它和普通年度记账不太一样,需要一个更贴合农业的模型。
最终的核心设计思路是:以周期为单位管理农业活动。从整地或播种开始,记录施肥、浇水、除虫等过程,到最终采收结束。每个活动是预先定义好的,不能自定义输入,这样也顺带解决了手动填写名称容易出错的问题。每一个活动可以关联对应的财务费用,例如一次施肥可以同时记录人工费用和肥料费用;采收时关联收入,周期结束后自动计算 ROI。用地块约束周期,用周期约束活动。可选设置周期的预算,根据预算使用情况展示细微的 UI 差别。
第二阶段:Next.js + Prisma + SQLite + 上线
定下业务逻辑后,在边开发边测试的过程中对数据和业务进行细微调整,但都没有跳出框架。此时我认为可以先上线,在使用中逐步完善,毕竟只有 1 个用户。然后发现,上线才是独立开发最大的敌人,没有之一。
为了阅读方便,本文不涉及上线遇到的问题。
开发初期选择 SQLite,数据存在本地,配置简单,是合理的起点。但我作为2025年才开始写代码的人,一定要追求新、稳、最佳实践!旧的设计要扫到历史垃圾堆里,没有学的必要。所以引入了 ORM,技术架构变成了 Next.js + Prisma + SQLite。
第三阶段:迁移至 PostgreSQL
上线后,核心的 APP 跑在我本地的 NAS 上,我对自己的设备有种莫名其妙的不信任,所以开始尝试使用云数据库。各大善人都提供有免费额度,对我来说足够用了,例如 Vercel。于是迁移到云端 PostgreSQL。这个决策本身没有问题,是真实需求驱动的。
但从这一步开始,我开始有了野心。项目的推进方向悄悄发生了偏移——从”让家人用起来”变成了”做一个正式的产品”。
第四阶段:引入 Logto 认证
第三阶段之后,项目的问题变成了”任何知道网址的人都能访问,且是同一套数据”。虽然可以用 Nginx Basic Auth 或其他简单验证方案,但体验并不友好,我觉得我的用户可能记不住。
既然已经是一个正式产品的方向,又有安全需求要引入认证,为什么不直接支持多用户呢?于是引入了 Logto 做身份认证,支持邮箱或用户名密码登录。
Logto 是一个非常棒的产品,强烈建议去尝试一下! Logto · Modern auth infrastructure for developers
手机号也是备选方案——我理解程序员对手机号验证有多痛恨,但不得不说,手机号验证在国内的接受程度确实更高。
此时我应该意识到,我可能已经过度设计了——在当前阶段引入 Logto 并没有比 Nginx Basic Auth 高明多少,但我却沉浸在未来多用户使用的臆想中。
第五阶段:发现真正的问题
引入 Logto 后,我的父亲反馈说现在需要登录才能用,而我还没有下定决心启用手机号验证,邮箱他不熟悉,用户名密码也记不住,极大地降低了他的打开频率。
也许,我该重新考虑多用户的必要性了。我是什么时候走偏的?
- 开发初期选择 SQLite,没有问题;
- 迁移到云端 PostgreSQL,没有问题;
- 拦截未认证的访问,且预判未来有多用户需求,引入了 Logto,好像也没有问题;
- 影响用户使用频率,出现了问题。
为了解决某个问题会引入越来越多的组件或功能,随着功能堆叠开始暴露新问题,这是独立开发中很常见的决策模式:把预想中的未来需求当作当下要解决的问题。反映到我的项目上,就是应用多了一道登录流程,反而成了额外的障碍。
问题在哪里
回顾每一个技术决策,单独来看都有合理的依据:SQLite 迁移到 PostgreSQL,是真实的数据安全需求;引入认证,是对多用户场景的合理预判。但每一次解决问题都带来了新的问题,这也说明了没有银弹,你得到什么就必然失去什么。
问题不在于某一步选错了技术,而在于缺少每次决策后的”回顾”,导致失之毫厘,差之千里。问题是在真正开始使用之后才暴露出来的,而不是在设计阶段被发现的。
现在的方向
当前版本是 Next.js + Prisma + PostgreSQL + Logto 的在线版本,已足够稳定,只需要我的用户记一下账号密码。等我下定决心启用手机验证,在 Logto 中开启就可以解决这个问题了。
下一阶段我打算在此基础上进行一次重构,转向离线优先架构。会在保持业务逻辑不变的前提下重新思考技术方案选型,带来新的优化:纯离线应用,服务端只做应用分发,支持 PWA,注册用户可以在线同步。数据模型里已经加入了 isDeleted 和 updatedAt 字段,当前不参与任何业务逻辑——这总不至于算是过度设计了吧。
活动类型里也许会再增加一个”销售”活动,也许还要增加”库存管理”,有时候采收后不一定能马上出售。当然,这些都排在离线方案落地之后。
更新
2026年5月更新
我的用户因为对电子设备不太熟悉,最终选择了一个更简单的方案—— 让我来操作,他只负责告诉我今天做了什么。
某种意义上,我成了他的人工智能……
为了让更多的人成为“人工智能”,我会继续优化这个项目……
离线优先架构已经落地。现在的 My Farming 是一个纯离线应用,数据存储在浏览器本地,无需注册,打开即用,服务端只负责分发应用本身。
为了避免数据丢失,提供了导入导出功能。在线同步功能正在规划中,届时注册用户可以跨设备访问数据。
现在允许在已经结束的周期里补充记录销售行为,更符合实际活动。
Demo 仍然是文章中描述的服务器分发版本,正式版请访问:https://farm.feegr.cn
尝试一下
如果你对 My Farming 感兴趣,可以访问 demo 版本体验一下,demo 版本里有数据。
Demo: https://demo-farm.feegr.cc
同时我也在为开源做准备,如果你想提前获得仓库访问权,可以直接给我发邮件。
WIYA 2026 © Feegr