💰 现金流管家系统(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 zipOpenClaw 下载目录 a66f4d77-2e23-4fbc-80bc-605e26e21e89-hsd-system-v2.zip
GLM 任务 promptD:\hermes\hsdesign_work\cashflow_glm_prompt.md
二轮适配 promptD:\hermes\hsdesign_work\glm5.2_cashflow\PROMPT_to_GLM5.2_draft.txt
二轮适配 zipD:\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)
  • 数据库:本地 SQLitedb/custom.db);云端 D1
  • next-auth 未接入 → 无登录保护(裸奔,用户+AI 双权限的权衡)
  • PWA:manifest + service worker + icons(stale-while-revalidate)

Cloudflare 资源(新系统,2026-08-04 建)

资源
线上 Workerhttps://hsd-cashflow.ida-czia.workers.dev(部署为 Worker 非 Pages;真域名,pages.dev 为配置假值
D1 数据库hsd-cashflow-db
D1 IDcd009bf4-3d28-4956-84e3-f60c4e7e2a5d
bindinghsd_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)

  1. esbuild 太旧 → npm i -D esbuild@0.21.5(修 “Invalid alias name”)
  2. Prisma Workers:schema driverAdapters + engineType="client";本地用 libsql 适配器;serverExternalPackages: ["@prisma/client", ".prisma/client"]
  3. getCloudflareContext({async:true}) 必须 await(未 await → API 500 e2 is not a function
  4. wrangler.json 必须配 assets(.open-next/assets),否则静态资源 404 → 空白页
  5. D1 远程不支持 BEGIN/COMMIT(导入脚本去掉事务包装);D1 无 Prisma 自动填充 → createdAt/updatedAt 显式赋值
  6. Prisma validate 先行:schema 改动后先 prisma validate 再 generate(validation error → 65 行 stub client 静默 fallback)
  7. 静态 import@opennextjs/cloudflarecloudflare/init.js)+ @prisma/adapter-d1 必须静态 import(动态 → chunk 缺失 → e2 is not a function);serverExternalPackages 不含 adapter 包
  8. workerd 禁动态 wasm 编译(#28657)→ 静态 import .wasm + CompiledWasm 预编译;engineType=client 自带裸 wasm;compilerWasm 内置 fs.readFileSync 需 patch 改 globalThis 读取
  9. 8/6 原配置即正确组合:Prisma 6.19.3 + engineType=client + driverAdapters(Schedule relation 修复后 563 行完整实现);不 patch minified Prisma(一次性方案)——锁版本 + build_deploy.sh 一键部署
  10. 模型命名:BQ → db.bQ;路由 [projectId] 参数名要匹配目录名(8/8 中午 Receipt/PC/VO/Checklist 又集体踩坑,批量修复)
  11. PUT 全量替换前先查 API 期望字段(8/8 中午事故:误传 price→0 → 数据破坏;备份全不通 → 靠 BQ + fixed 模式重建,成本列丢失)
  12. 写中文数据用 Python(强制 UTF-8)不用 curl(8/8 中午:Windows curl 编码损坏 → 库中乱码 → PDF 问号;不是字体问题)

相关