💰 现金流管家系统(hsd-system)— 环境笔记
GLM5.2(智谱网页版 Agent PRO)生成、Hermes 负责落地的「现金流管家 + 报价/发票一体化」Master APP。状态:✅ 线上运行中(2026-08-04 18:01 上线;8/8 07:28 BQ + Briefing + Agreement 全上线):https://hsd-cashflow.ida-czia.workers.dev(真域名,pages.dev 是配置假值)
分工模型(用户明确)
- 用户:只做微调(fine-tuning),主要工作在 AI
- AI(Hermes):系统内所有项目/功能都有编辑权限;负责部署、导入数据、日常维护
- 数据要求云端在线同步:部署后导入现有 19 项目 + 14 客户 + 报价,永不再重复填
- 用户无技术背景:结论直接可执行、术语大白话
关键位置
| 项目 | 位置 |
|---|
| 源码(8/8 起部署主目录) | D:\hermes\hsdesign_work\glm5.2_cashflow\glm_return\ |
| 一键部署脚本 | build_deploy.sh(8/8 落地:部署+自动验证+失败回滚;修 --outdir 吞退出码 + verify 假域名两 bug) |
| 原始 zip(v1) | D:\hermes\hsdesign_work\glm5.2_cashflow\GLM5.2_cashflow_src.zip |
| GLM v2 zip | OpenClaw 下载目录 a66f4d77-2e23-4fbc-80bc-605e26e21e89-hsd-system-v2.zip |
| GLM 任务 prompt | D:\hermes\hsdesign_work\cashflow_glm_prompt.md |
| 二轮适配 prompt | D:\hermes\hsdesign_work\glm5.2_cashflow\PROMPT_to_GLM5.2_draft.txt |
| 二轮适配 zip | D:\hermes\hsdesign_work\glm5.2_cashflow\GLM5.2_adapt_source_0804.zip(1.9MB,149 文件) |
| 部署指南 | v2 内 CLOUDFLARE_DEPLOY_V2.md;部署脚本 scripts/fix_prisma_worker.mjs |
| GLM 下载 zip 默认落点 | C:\Users\Sozo\AppData\Local\Temp\playwright-artifacts-yOejdj\(⚠️ 不是 Downloads) |
| 桌面快捷方式 | HS Design · 现金流管家.lnk = dev 版 PWA(线上版已可装,等用户装正式 PWA) |
技术栈与版本(2026-08-04 定版;8/7 发现漂移,已回锁;8/8 终验正确组合)
- Next.js 15.5.22(原 16.1.1 降级,opennext 要求
>=15.5.21 <16)+ React 19 + Prisma 6.19.3 + Tailwind 4 + shadcn/ui
- 适配器:@opennextjs/cloudflare 1.17.3(弃 next-on-pages);esbuild 0.21.5(修 Invalid alias name);wrangler 4.118.0
- ⚠️ 8/7 教训:npm install 会漂移到 next 15.5.23 / opennext 1.20.2 → 部署必炸(Prisma stub + chunk 缺失)——用
package.json 精确锁定版本(next 15.5.22 + opennext 1.17.3 + esbuild 0.21.5)
- ✅ 8/8 终验正确组合(8/6 原配置):Prisma
driverAdapters + engineType="client"(WASM 无引擎,自带裸 wasm query_compiler_bg.wasm)+ @prisma/adapter-d1 静态 import;本地 @prisma/adapter-libsql(弃 better-sqlite3,原生编译坑);@libsql/client 必须显式进 dependencies(否则 opennext 不拷贝)
- ⚠️ Prisma schema 改动后必须先
prisma validate(validation error 会静默生成 65 行 stub client → 部署 500;8/7 真因 = Schedule 缺 3 个反向 relation)
- ⚠️ db.ts 的
getCloudflareContext 必须静态 import(@opennextjs/cloudflare/cloudflare/init.js);await import() 动态引入 → opennext 不打进产物 → 线上 e2 is not a function
- ⚠️ workerd 禁止运行时动态编译 wasm(prisma/prisma #28657)→ 静态 import .wasm + wrangler CompiledWasm 预编译(8/8 突破点)
- ⚠️ Prisma 命名陷阱:模型
BQ → 客户端属性 db.bQ(大写 Q);[projectId] 目录 ≠ 解构参数名
- db.ts:异步
await getDb()(Cloudflare getCloudflareContext 主入口——opennext 1.17.3 无 overrides.js;本地 lazy libsql)
- 数据库:本地 SQLite(
db/custom.db);云端 D1
- next-auth 未接入 → 无登录保护(裸奔,用户+AI 双权限的权衡)
- PWA:manifest + service worker + icons(stale-while-revalidate)
Cloudflare 资源(新系统,2026-08-04 建)
| 资源 | 值 |
|---|
| 线上 Worker | https://hsd-cashflow.ida-czia.workers.dev(部署为 Worker 非 Pages;真域名,pages.dev 为配置假值) |
| D1 数据库 | hsd-cashflow-db |
| D1 ID | cd009bf4-3d28-4956-84e3-f60c4e7e2a5d |
| binding | hsd_cashflow_db |
| 表 | 22 张(Customer/Project/Quotation/QuotationItem/Invoice/InvoiceItem/Payment/Bill/BillItem/BillPayment/Supplier/ItemLibrary/BankTransaction/Setting/PurchaseItem + BQ/BQItem + Briefing(8/8 上线)) |
| 数据 | 已导入真实数据(18:15):27 客户 + 18 项目 + 20 item 均价(166 行);8/8 新增 HSD00011 Anne Lew 项目 + Briefing |
| 静态资源 | 46 个(wrangler.json assets 配置,缺了会空白页) |
| 凭据 | Cloudflare token/ACCOUNT_ID 在 D:\hermes\hsdesign_work\site_full\deploy.cmd(ACCOUNT_ID=f6b7326e471bbe3d1b0a0e2ba770f47d) |
| 部署状态 | ✅ 线上稳定运行(8/8 07:28 BQ 部署成功,全 API 200;Briefing + Agreement 同日上线;build_deploy.sh 一键部署) |
本地运行
cd /d/hermes/hsdesign_work/glm5.2_cashflow/glm_return
npm install # ⚠️ 需批准 prisma/sharp/unrs-resolver postinstall
npm run db:push # SQLite 建表
npm run seed # 47 items + 13 工种 + 品牌
npm run dev # localhost:3000
- db.ts
getDb() 双模式:Cloudflare 用 getRequestContext() 拿 D1;本地自动回退 SQLite
- 构建:
next build(20/20 静态页通过);⚠️ eslint 需关 react-hooks/set-state-in-effect
- 环境坑:bun 下载被网络拦截(勿用 bun,npm 即可;bun.lock 已删);Windows 下 wrangler 不认 MSYS
/tmp 路径
功能与待办(8/8 上午更新态)
- ✅ 线上运行:首页 200 + Items API(47 item)+ Dashboard 现金流计算 + 真实数据(27 客户 + 18 项目,18:15 导入验证)
- ✅ 已验证:客户/项目(两行地址)/报价(20% markup 1000→1200)/发票分阶段(15% 定金)/仪表盘(余额/应收/应付/净现金流/3月预测/逾期发票)/Item 库/品牌(Maybank 551539158314)
- ✅ Bills 应付账款(Bill/BillItem/BillPayment:开 bill 给 subcon/supplier 记欠款;
netCashFlow = bankBalance + AR − AP + upcomingOutflows + overdueBills)+ 供应商管理 ✅
- ✅ 独立发票(POST 支持 billTo/billToPhone/billToAddress/subject/items[] 手动开,amount 自动算)+ PDF preview 排版修复(‘To: Mr Vincent Test…’ 居中问题,GLM v2 已修)
- ✅ BQ 工程量清单(8/8 07:28 上线):/api/bqs CRUD + BQPanel + /api/pdf/bq PDF;Mr Chen QUOAUS0001 实测通过。⏳ 成本版 v2(双模式)待实施
- ✅ Briefing Form(8/8 07:44 上线):/briefings/[projectId] 页面 + /api/briefings upsert + /api/pdf/briefing 双语 PDF(微软雅黑);Anne Lew HSD00011 已建档
- ✅ Agreement 施工合同 PDF(8/8 上午):/api/pdf/agreement/[projectId] 英文版(Mr Chen 不签 Agreement,改走 quotation+deposit)
- ✅ Receipt 正式收据(8/8 中午上线):/api/pdf/receipt/[paymentId]——OFFICIAL RECEIPT(金额大字/尚欠余额/签名盖章栏);实测 Mr Chen RM2,400 + Pulai Flora 现金 RM8,003(⛔ 12:27 更正:实收 8,003 全款,非 6,800)。8/8 下午升级:金额大写(LHDN 惯例)+ 公司印章(public/ 透明 PNG 自动盖章)+ Received From 自动带客户名 + 地址读 D1 完整地址 + remark 不含内部信息(FINAL4)
- ✅ Progress Claim 屋主版(8/8 中午上线):/api/pdf/progress-claim/[invoiceId](基于 Invoice stageLabel/percent/amount/balance)
- ✅ VO 变更单(8/8 中午上线):/api/pdf/vo/[projectId]?add=500&desc=… 或 ?subtract=300(增/减项自动算合同总额;纯 PDF 功能无新页面)
- ✅ Progress Claim 总包版(8/8 中午上线):分包→总包(WO 工单号 + 保留金 10% + 证据附件 + 总包签收栏)
- ✅ Site Checklist 现场量尺寸清单(8/8 中午上线):6 大项(空间/门窗/水电/墙况/BQ 核对/照片)
- 🎨 PDF 全系列统一(8/8 中午):基准 = quotation teal doc-title(非金色);客户 PDF 纯英文;无 URL 页脚;8 个 PDF 全统一
- ✅ 8+ 视图:dashboard/customers/projects/quotations/invoices/bills/suppliers/items/bank/settings(中英双语)+ PWA「立即安装」
- ⏳ Work Schedule 并入 master APP(已并入:排期 6 视图 + Purchase List 7 视图)
- ❌ 缺 ColdCall 跟进表(跟进提醒/下次跟进/谁该追)→ 二轮优化
- ❌ 缺跟进日期/待收提醒 → 二轮优化
- ⚠️ Gmail 邮件解析模块无用(马来西亚 Maybank 无 email 交易通知,判死)
部署踩坑速查(全链路已打通,8/8 补 6-9)
- esbuild 太旧 →
npm i -D [email protected](修 “Invalid alias name”)
- Prisma Workers:schema
driverAdapters + engineType="client";本地用 libsql 适配器;serverExternalPackages: ["@prisma/client", ".prisma/client"]
getCloudflareContext({async:true}) 必须 await(未 await → API 500 e2 is not a function)
- wrangler.json 必须配
assets(.open-next/assets),否则静态资源 404 → 空白页
- D1 远程不支持 BEGIN/COMMIT(导入脚本去掉事务包装);D1 无 Prisma 自动填充 → createdAt/updatedAt 显式赋值
- Prisma validate 先行:schema 改动后先
prisma validate 再 generate(validation error → 65 行 stub client 静默 fallback)
- 静态 import:
@opennextjs/cloudflare(cloudflare/init.js)+ @prisma/adapter-d1 必须静态 import(动态 → chunk 缺失 → e2 is not a function);serverExternalPackages 不含 adapter 包
- workerd 禁动态 wasm 编译(#28657)→ 静态 import .wasm + CompiledWasm 预编译;engineType=client 自带裸 wasm;compilerWasm 内置 fs.readFileSync 需 patch 改 globalThis 读取
- 8/6 原配置即正确组合:Prisma 6.19.3 + engineType=client + driverAdapters(Schedule relation 修复后 563 行完整实现);不 patch minified Prisma(一次性方案)——锁版本 + build_deploy.sh 一键部署
- 模型命名:BQ →
db.bQ;路由 [projectId] 参数名要匹配目录名(8/8 中午 Receipt/PC/VO/Checklist 又集体踩坑,批量修复)
- PUT 全量替换前先查 API 期望字段(8/8 中午事故:误传
price→0 → 数据破坏;备份全不通 → 靠 BQ + fixed 模式重建,成本列丢失)
- 写中文数据用 Python(强制 UTF-8)不用 curl(8/8 中午:Windows curl 编码损坏 → 库中乱码 → PDF 问号;不是字体问题)
相关