文件
hyb-oa/client
wangsli和Claude Opus 5.5 db28706177 借款对账 S1、S2:导出与银行提交分开登记、确认失败收紧及失败回单识别口径(09-17-company-loan-principal-repayment)
S1(迁移 20261007010000)
- 借款导出逐次记录;存量批次保留已知导出次数为历史汇总,不视为真实导出,存在即拦截
- 银行提交登记(只能撤回一次)与提交清单确认;独立复核,复核后任何登记、撤回、导出即失效
- 确认失败只计未作废附件;作废附件无法证明为明确失败或确属他笔付款即阻断
- S3 前临时拦截:多次导出、多次提交、清单未复核或历史汇总均不能确认失败
- 确认失败改按付款后规则;确认人不得兼任导出、提交登记、清单确认

S2(迁移 20261007020000)
- 存在同金额候选时须有已复核、覆盖提交清单的失败归属;结算与失败归属分槽

失败回单识别口径(用户同意并入)
- 新增原始状态措辞字段(多字段原文不一致即为空);失败事实严格判定:单页完整、
  仅“交易失败/转账失败/付款失败/支付失败”、唯一问题为交易失败、字段齐全;
  已撤销、已冲正、已退汇不接受;顶层识别状态与成功匹配不变
- 测试改走真实识别与归一化链,仅替换云端 OCR 响应

验证:借款 HTTP 41 组、浏览器 7 组、76 迁移;server 4463;共享回单测试 237;
三轮同模型只读复核的阻断项均已修复。

注意:界面未完成,不能单独部署;真实回单待验。未推送、未部署。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 11:47:24 +08:00
..

hyb-oa Client Runbook (P1-5)

1. 前置条件

  • Node.js >=22 <23
  • 后端服务可用(http://127.0.0.1:3000)

2. 安装与启动

cd client
npm install
npm run dev

默认前端地址:http://127.0.0.1:5173

3. 本地联调建议顺序

cd ..

export POSTGRES_PASSWORD="<local-only-db-password>"
export JWT_SECRET="<local-only-jwt-secret>"
docker compose up -d db

cd server
npm run prisma:migrate:deploy
SEED_DEV_ALLOW=1 SEED_DEV_DATABASE_CONFIRM=hyb_oa npm run seed:dev
npm run dev

cd ../client
npm run dev

根级 Compose 要求显式提供本地数据库口令和 JWT 密钥;不要把真实值写入仓库,并让 server/.env 的 DATABASE_URL 使用同一数据库口令。

3.1 试运行/单域托管部署(推荐)

试运行/上线演练建议使用仓库内置部署包(server 托管 client/dist,同域 cookie 更稳定):

  • deploy/trialrun/runbook.md
  • deploy/trialrun/checklist.md

4. 鉴权与会话说明

  • Access Token 仅保存在内存,不写入 localStorage/sessionStorage。
  • Refresh Token 由后端通过 HttpOnly Cookie 维护。
  • 前端在 401 时自动调用 /api/auth/refresh 并重试一次请求。
  • 登录与刷新请求都会附带 x-device-fingerprint。

4.1 开发账号(seed:dev)

seed:dev 仅用于本机开发库,必须显式允许并确认数据库名;账号与口令以本地受控 SEED_* 配置为准,脚本不输出口令。默认不会覆盖已有账号密码;新建账号和主动设置 SEED_DEV_RESET_PASSWORDS=1 后轮换的账号,首次登录都必须改密。

5. 菜单与权限(当前壳层)

  • 仪表盘:登录即可访问。
  • 我的报销:expense.view_own 或 expense.view_all。
  • 待我处理:expense.approve。
  • 票据中心:invoice.upload / invoice.view_own / invoice.manage。
  • 审计工作台:system.audit.view(finance_mgr/admin)。
  • 用户管理:system.users(hr/admin)。
  • 个人设置:登录即可访问。

6. 页面现状(P3)

  • 待我处理:列表 + 详情 + approve/reject/return/transfer 动作。
  • 我的报销:分页列表 + 详情 + submit/withdraw/pay 联调入口。
  • 票据中心:分页列表 + 上传 + OCR 轮询 + 绑定 + 签名预览。
  • 审计工作台:分页筛选已落地。

7. 状态管理与错误语义

  • 引入 @tanstack/react-query 统一查询缓存与失效策略。
  • 错误文案统一映射在 client/src/api/errorMessages.ts。
  • API 层保留后端错误码原文,前端仅做可读化。

6. 风格资源复用策略(锁定)

  • 视觉 Token 来源:<design-source-repo>。
  • 采用“复制到 client + 单向同步”,不做跨仓软链与自动联动。
  • 如需同步风格,请记录来源 commit 并通过评审。

8. 可用脚本

npm run dev
npm run typecheck
npm run build
npm run preview
npm run test:e2e

8.1 Playwright E2E(E15)

前置:本地启动 DB + server(建议 SERVE_CLIENT_DIST=true 单域托管),并启用 mock OCR:

cd ..
docker compose up -d db

cd server
OCR_PROVIDER=mock OCR_POLL_CRON="*/5 * * * * *" npm run prisma:migrate:deploy
SEED_DEV_ALLOW=1 SEED_DEV_DATABASE_CONFIRM=hyb_oa OCR_PROVIDER=mock OCR_POLL_CRON="*/5 * * * * *" npm run seed:dev
OCR_PROVIDER=mock OCR_POLL_CRON="*/5 * * * * *" SERVE_CLIENT_DIST=true npm run dev

执行:

cd ../client
npm install
npx playwright install --with-deps
npm run test:e2e

9. 仓库级最小门禁

cd ..
./scripts/check-minimal.sh

说明:

  • 会执行 client 的 typecheck/build 与 server 的静态检查。
  • 不启动服务,不替代发版前的 server/scripts/regression-all.sh。