周三上午,运营主管打开 Riviera 工业 ERP,打算把上周采购的几批铝型材和紧固件做成客户报价。系统里没有这条路径——他只能导出材料清单,手动计算单价乘数量,再临时塞进一个通用报价模板。同一时间,设备维护排期表还是用共享表格在管,下一次注塑机检修的提醒全靠日历闹钟。

这不是大企业的遗留问题,而是一个正在公开构建的独立开发者项目的真实状态。项目的创建者在“Build in Public”系列里记录了自己如何补上两块关键拼图:基于物料的报价生成,和计划性维护订单管理。他最初的想法是沿用已有的报价逻辑,直接把物料信息叠加上去。但很快发现,物料、报价单、生产工序之间的关系比预想中复杂,继续打补丁会把代码拖进死胡同。

于是他停下来,做了一件在敏捷叙事里不太性感的事——回到 Prisma schema 层面重新设计模型。新增的 QuoteItem 模型里,unitPrice 和 total 用 Decimal 类型存到小数点后两位,还通过 processId 外键关联到 ProductionProcess。另一个新模型 MaintenanceOrder 则用 cuid 生成主键,带着描述和 scheduledAt 时间字段。这一步做完,后端的数据结构才算真正能为“从物料到报价”以及“创建维护工单”两个动作服务。

在 API 层,他新建了 src/app/api/quotes/route.ts,用一个 POST 处理器接收 materialId 和 quantity,查物料单价,算总价,再通过 Prisma 写入 quoteItem 表。前端部分,NewQuoteForm 组件通过 listMaterials() 拉物料列表,让用户可以直接在界面上选择物料并生成报价项。同时,维护订单也有了独立页面:列表页、新建页、详情页,路径塞在 operations/maintenance 下。

整个实现过程里,他自己提炼的核心体会听起来有点枯燥,却刚好是多数独立开发者容易跳过的部分:给现有应用加新功能时,先花时间规划 schema 变更和 API 路由,比急于在 UI 上出效果要划算得多。试错阶段的“先扩展报价功能”方向被放弃,正是因为缺少这一层的预判。

下一步计划也已经在路上了——给报价请求和维护工单加上 WhatsApp 通知。这意味着需要接通 WhatsApp API,并调整现有的通知系统。对于一个还在公开迭代的工业 ERP 来说,用消息应用推送业务提醒,或许比先做一套复杂的内置通知更有落地感。