文件
hyb-oa/.trellis/tasks/07-27-yang-jun-reimbursement-readiness/implement.md
T
wangsli 8a9279efce
ci-e2e / e2e (push) Canceled after 0s
ci-minimal / check-minimal (push) Canceled after 0s
实现报销材料连续预览(07-27-yang-jun-reimbursement-readiness)
2026-08-01 00:17:54 +08:00

36 KiB
原始文件 Blame 文件历史

杨俊报销就绪:执行计划

1. 生产写入前门禁

  • 只读复核活动 server 构建标识、Compose 项目、4 个 systemd service 当前 BUILD_SHA、timer enabled/active、最近源端备份与 ARM 新鲜度;输出仅限状态和计数。
  • 使用活动部署的显式合同参数重装 automatic backup 的 daily/watchdog/drill-reminder units。
  • 使用活动部署的显式合同参数重装 WARCH3 unit。
  • 验证以下 4 个 service 的 BUILD_SHA 全部等于活动 server,相关 timers 为 enabled/active:
    • hyb-oa-automatic-backup-daily.service
    • hyb-oa-automatic-backup-watchdog.service
    • hyb-oa-automatic-backup-drill-reminder.service
    • hyb-oa-warch3-ops.service
  • 手工启动一次 automatic backup daily service;确认源端 Result=success、ExecMainStatus=0。
  • 在 ARM 只读验证新批次完成、manifest/文件完整性与新鲜度检查通过;任何失败均停止人员写入。

2. 杨俊单人导入

  • 从管理员导出的通讯录以管道/内存方式筛选杨俊一人,不生成持久化子集文件,不输出个人字段。
  • 在生产容器运行 dry-run,验收计数:输入 1、active 1、incomplete 0、planned create 1、conflict 0、skip 0、failure 0。
  • dry-run 符合预期,无需进入偏差处理分支。
  • 经本任务最终实施批准后,使用 docker-compose exec -T -e WECOM_DIRECTORY_EXPORT_APPLY ... --input=- --apply 写入唯一目标。
  • 只读验证杨俊 OA 员工为 active、企微绑定唯一、初始角色严格为 employee,且其余通讯录成员未进入本轮输入或写入。
  • 确认生产企微通讯录写回门禁关闭;本轮同步结果为 skipped,未调用企微成员写接口。

3. 设置真实直属主管

  • 写入前记录杨俊原 direct_manager_id 的脱敏状态,并确认马建勇为 active、不同员工且具有 expense.approve。
  • 通过现有 POST /api/users/batch/set-manager 仅将杨俊的主管设置为马建勇;不直写数据库、不调整任何人的角色。
  • 写后验证主管解析成功,并核对 SYSTEM_USERS_BATCH_SET_MANAGER 审计增量;该接口合同不递增目标员工 token version 或撤销会话。
  • 主管写入成功,未进入失败或误配回退分支。

4. 聚焦验证

  • 运行通讯录导入相关测试,覆盖手机号为空、单目标和 apply 双门禁。
  • 运行 users set-manager 路由测试,覆盖 active、自指、审计和权限边界。
  • 运行 workflow/reimbursement 聚焦测试,覆盖主管解析、expense.approve、无差旅申请和绑定票据提交门禁。
  • 运行 cd server && npm run prisma:validate;代码未变化时仍将结果作为当前合同基线记录。
  • 运行 Trellis task/governance、流程/文档、敏感扫描和 git diff --check。
  • 按项目规则对权限、workflow 和生产写入证据做一次只读 review;Codex inline 主代理复核通过,未发现角色扩权、企微反向写入、审批自审或生产测试业务数据。

5. 两个既有企微测试成员的受控验收

  • 从管理员通讯录以内存方式仅筛选“测试员工”和“测试主管”,验证二者唯一、active、资料满足导入合同;不输出或持久化原始字段。
  • 生产 dry-run 验收输入 2、计划创建 2、冲突/跳过/失败 0;偏差即停止。
  • 单独取得生产测试账号/业务写入批准后 apply,并确认两人 active、企微绑定各自唯一、没有导入其他成员。
  • 通过现有角色接口将角色收敛为:测试员工=employee,测试主管=employee + manager;核对 token version、会话撤销及角色审计。
  • 通过现有主管接口设置“测试员工 → 测试主管”,确认测试主管 active 且具有 expense.approve。
  • 两个测试成员均完成账号密码登录与首次改密,申请人可见报销入口、主管可见审批入口;企微 SSO 因不能冒充企微身份仍待人工确认。
  • 测试员工创建唯一一条描述含“系统测试、非真实业务、禁止付款”、总额 0.01 元的测试报销,并上传不含真实资料的安全 PDF。
  • 合成 PDF 经生产 mock OCR 自动生成测试字段并标记可用,绑定后成功提交;该结果同时暴露真实使用前必须移除 mock OCR 的门禁。
  • 测试主管确认待办可见并执行“退回”,未执行“通过”;报销回到 draft 且 workflow instance 终止,无需追加“撤回”。
  • 测试员工删除 draft 报销;票据解绑回到 available 后已手工归档。
  • 管理员停用两个测试 OA 账号并确认会话撤销、企微写回为 skipped;企微侧两个测试成员保持不变。
  • 只读收口确认:测试报销 0、pending 待办 0、测试票据唯一且为 manual archived、两个测试 OA 账号为 archived、活动会话 0、企微绑定保留 2;未产生测试付款。

5.1 真实发票路径门禁

  • 只读确认生产当前为 OCR_PROVIDER=mock,腾讯 OCR 凭证未配置。
  • 用户选定“关闭 mock 并采用财务查看 PDF 原件人工核对”;本轮不改代码、不部署新构建。
  • 生产 .env 已切换为 OCR_PROVIDER=off;现场无独立 worker 且 JOBS_ENABLED=true,因此仅强制重建 server。公网 /ready 正常,构建仍为 4886f9b081dd。
  • 重新启用两个测试 OA 账号并完成受控 API 闭环:新 PDF 直接 available,八个发票业务字段为空、OCR 尝试为 0,绑定、提交、主管退回均成功。
  • 复验后删除测试报销、归档测试票据、停用测试 OA 账号;最终活动会话 0、测试报销 0、pending 待办 0、未归档测试票据 0,企微同步均为 skipped。
  • 记录非阻断 schema finding:off 路径未显式写 provider,但 ocr_provider 因非空默认值仍存 tencent;请求/完成时间和 OCR 结果为空,当前 UI 不展示该字段。

6. 用户真实验收

  • 在杨俊提交前通过现有审批规则管理接口把三档规则收敛为唯一 [0,+∞) 规则,审批链固定为 department_manager → finance;不扩角色、不保留 CEO 重复节点。
  • 规则写入前后只读核对 499.99 / 500 / 5000 三个金额,确认解析结果完全相同且 active finance 有唯一实际处理人。
  • 请杨俊本人从企业微信进入 OA,确认身份解析成功并能看到报销入口。
  • 杨俊使用真实业务数据创建报销,至少添加一条费用明细并上传/绑定状态有效的真实票据后提交。
  • 确认马建勇能看到该真实审批待办并按业务事实处理。
  • 审批通过后确认单据进入王芝玲负责的财务处理链路;后续付款批次继续遵守既有 maker-checker。
  • 用户验收期间不在聊天、截图或任务证据中粘贴票据、金额、银行资料或完整账号。

6.1 审批详情可达性修复

  • 保留移动待办列表卡片现有 handleTaskSelection 行为,不修改任务列表到审批任务详情的路由。
  • 在 MobileApprovalsPage 的审批任务详情报销摘要区增加“查看完整报销单”,复用 /mobile/reimbursements/:id 和现有 state.from 来源回跳约定。
  • 在 WorkflowTaskDetailPage 的报销摘要区增加“查看报销单”,复用 PC 报销详情路由。
  • 不修改后端、审批状态机、权限矩阵或生产数据;请假、采购、差旅同类入口缺口仅记录,不在本轮扩展。
  • 增加聚焦前端回归,验证移动进入/返回及 PC 入口;运行前端 typecheck、build、Trellis task/governance 和 git diff --check。

6.2 审批详情入口生产发布

  • 将工作提交 d2841b1 推送后,以 SYNC_ENV=0 按标准发布脚本部署;未覆盖生产 .env,未修改审批状态、真实业务数据或付款数据。
  • 第一次发布尝试在同步前因附件挂载目标解析不匹配停止,生产未变化;按活动容器的实际挂载目标修正输入后重新执行。
  • 发布来源校验、环境合同、远端 Compose 校验、Prisma migration status、/ready、external deps smoke、runtime smoke 与公网资源扫描均通过,活动构建为 d2841b166dc0。
  • 使用既有 unit 中的受控合同参数重装 automatic backup 三项 service/timer 与 WARCH3 service/timer;第一次读取活动容器时因未向 Compose 显式传入构建变量而在 unit 写入前失败,补齐目标构建参数后成功。
  • 4 个 service 的 BUILD_SHA 均与活动构建一致;4 个 timer 均为 enabled/active。
  • 手工触发 automatic backup daily,源端 Result=success、ExecMainStatus=0;随后源端 watchdog 同为 success/0。daily 只有在 ARM receiver 完成三文件、manifest 与 SHA-256 校验并原子 finalize 后才会成功。
  • ARM dead-man timer 保持 enabled/active,最近一次自动运行是 success/0;本次尝试立即手工复跑被已收口的最小权限策略拒绝,未恢复临时 sudo、未改 ARM。不得把该证据写成“独立 dead-man 已对新批次即时复跑”。
  • 公网 /ready 构建标识匹配,已发布的移动端和 PC 资源分别包含“查看完整报销单”和“查看报销单”;未读取、截图或输出真实报销内容。

6.3 报销详情时区与 KISS 收敛

  • 让共享日期时间格式化显式使用 Asia/Shanghai,PC/移动报销详情与 PC 审批任务详情移除本地字符串截取函数并复用共享实现。
  • PC 合并重复概况,收敛明细、发票、附件标题和解释;无关联或无预算/风险内容时隐藏对应辅助区块。
  • 移动概况删除重复状态、计数教学和冗余下一步文案;只读无动作时不渲染空操作卡,编辑能力保持不变。
  • 用合成数据补附件 UTC→上海时间和 KISS 信息层级聚焦回归;运行前端 typecheck、build 与相关 Playwright。
  • 运行 Trellis task/governance、流程合同、文档审计、敏感扫描和 git diff --check;生产部署另行批准。

6.4 企微 WebView 旧包刷新护栏

  • 在页面从后台恢复为可见时请求 /ready,比较规范化后的前端与 server 构建标识;一致、未知或请求失败时静默。
  • 构建不一致时复用现有 PWA 更新事件,在已登录 PC/移动壳显示“发现新版本,点击刷新”;不自动重载页面。
  • 点击刷新后清理旧 PWA runtime/precache 并重载;同一页面生命周期只提示一次。
  • 用合成 /ready 响应覆盖 mismatch、match 和 failure,运行 typecheck、build、聚焦 Playwright 与 Trellis 门禁。
  • 只提交并推送;生产部署和经理二次刷新另行执行,不在本步骤自动部署。

6.5 企业微信原生发票与附件预览

  • 增加企微 JSAPI ticket 获取/缓存和本站 URL 签名接口;覆盖缺配置、上游失败、跨 origin、fragment/凭据 URL 拒绝与脱敏返回。
  • 发票短时 URL 响应补准确文件元数据;移动企微用 previewFile,PC 用浏览器预览。
  • 为报销附件增加严格对象授权、理由门禁和实际取件审计的短时预览 URL;不扩大角色或通用下载权限。
  • 抽取 PC/移动共用材料预览调用,企微路径不使用异步 window.open(blob:);只读审批人看得到查看动作但看不到编辑、解绑、删除动作。
  • 用合成文件与 mock JS bridge 运行后端聚焦测试、前端 typecheck/build 和 PC/移动 Playwright 一致性回归。
  • 运行 Trellis 治理、流程/文档、敏感扫描、git diff --check,并对新增短时授权边界做只读 review;不在本步骤部署生产。

6.6 原生预览生产发布与运维对齐

  • 将提交 410d8cd 推送后以 SYNC_ENV=0 发布;未覆盖生产 .env,62 个 migration 无待执行项,公网 /ready 的 12 位构建标识匹配。
  • 如实记录两次发布尝试:第一次使用 runbook 示例发布目录和普通运维入口,来源/环境合同通过,但 rsync 因目录权限在同步前失败,生产未变化;随后从活动 Compose 标签解析实际发布根目录,复用既有受控 root 运维入口成功发布,未新增 sudo 或修改目录权限。
  • external deps、runtime smoke 与公网 bundle 扫描通过;公网包包含 previewFile、同源 JS-SDK 签名接口和附件短时预览入口,未登录请求签名接口返回 401。
  • 发布后从既有 unit 内部复用受控合同参数和运行时间,仅把 automatic backup 三项与 WARCH3 的构建标识刷新为 410d8cd;4 个 service 均匹配活动构建,4 个 timer 均为 enabled/active。
  • 手工触发 automatic backup daily 和源端 watchdog,二者均为 success/0;daily 成功以异机接收端完成文件、manifest、哈希校验和原子 finalize 为既有合同。
  • 记录非阻断依赖 finding:本次镜像构建审计报告 client 18 个风险(10 high),server 32 个风险(20 high、2 critical);未在发布窗口执行自动升级,留待独立依赖升级和回归任务。
  • 记录证据最小化 finding:既有 external/runtime smoke 输出仍包含不必要的配置标识和测试管理员联系方式;本任务不复述这些值,后续应独立收敛为状态与计数输出。
  • 请用户在企微自建应用刷新后先用无业务数据 PDF 验证原生预览,再由马建勇查看当前真实报销的发票与附件;材料真实可见前不得完成主管审批。

6.7 移动报销查看范围对齐

  • 在 MobileReimbursementsPage 读取 expense.view_all,仅对有权用户显示“我的 / 全部”范围切换;复用现有 Tabs/按钮样式,触控高度为 48px。
  • 范围默认和无权限回退均为 own;切换 all 时写入 URL 查询参数并纳入 React Query key,调用现有 fetchReimbursements({ scope }),不改后端或扩大权限。
  • 列表到详情的 state.from 保留当前 status 和 scope;普通员工不渲染“全部”入口,“全部”范围不显示仅限本人草稿的删除动作。
  • 增加聚焦 Playwright:管理员默认本人、切换全部后看到他人单据并进入详情;普通员工即使手工带 scope=all 也不显示范围切换且请求保持 scope=own。
  • 运行前端 typecheck/build、聚焦 Playwright、task/governance、流程/文档、敏感扫描和 git diff --check;部署另行批准。

6.8 移动范围生产发布

  • 将 20b20b1 和 8b376f4 推送后,以 SYNC_ENV=0 部署 8b376f4;未覆盖生产 .env,无待执行 migration,/ready、external/runtime smoke 与公网扫描通过。
  • 如实记录三次本地发布入口尝试:第一次因临时日志清理命令被本地安全护栏在进程启动前拒绝;第二次在来源校验阶段因未跟踪 portfolio review 导致 dirty worktree 停止;两次均未同步或改变生产。仅临时 stash 该目录后第三次发布成功,随后按 stash 标识原样恢复且未纳入提交。
  • 公网 /ready 为 8b376f413585,活动 server 中唯一移动报销 chunk 包含 mobile-reimbursements-scope-all 标识。
  • 复用既有 unit 合同参数与运行时间刷新 automatic backup 三项和 WARCH3;4 个 service 均匹配 8b376f4,4 个 timer 均 enabled/active。
  • 手工触发 automatic backup daily 与源端 watchdog,二者均为 success/0;未执行真实审批、财务审核、付款批次或付款写入。
  • 用户已用自己的企微管理员账号进入“报销 → 审批中 → 全部”,打开当前真实报销并确认能够查看材料;本项只记录查看验收,不代表主管审批或财务链路已完成。

6.9 报销明细与材料 KISS 对齐

  • PC 与移动端按 linkedItemId 在每条费用明细内展示关联发票摘要,并复用当前安全预览动作;未关联发票不归入明细。
  • 将原发票区和附件区收敛为单一“报销材料”区,显示分类计数,全部材料信息行可点击预览且不再重复显示“查看原件”按钮。
  • 保留草稿编辑态的添加/移除发票与上传/删除附件,不改后端合同、对象授权、审计、签名 URL、企微 JS-SDK 或审批状态机。
  • 更新聚焦 Playwright,覆盖关联/未关联发票、统一计数、PC/企微预览、编辑态动作、44px 触控目标和移动横屏无溢出;前端 typecheck/build 与 Trellis 质量门禁通过。
  • 用户明确批准后推送并部署生产;真人业务验收仍由用户在企微刷新后执行。

6.10 明细/材料 KISS 生产发布

  • 推送 665dcab 与 0e44aa7,从干净的已发布提交快照以 SYNC_ENV=0 部署 0e44aa7;不触碰未跟踪 portfolio review,不同步生产 .env。
  • 发布脚本的来源、环境合同、init、migration、/ready、external/runtime smoke 和公网资源扫描通过;公网构建标识为 0e44aa72f3f5,活动资源包含 PC/移动统一材料区标识。
  • 复用现有 unit 参数和运行时间刷新 automatic backup 三项与 WARCH3;4 个 service 构建身份一致,4 个 timer 均 enabled/active。
  • 手工触发 automatic backup daily 和源端 watchdog,二者均为 success/0;未执行真实审批、财务审核、付款批次或付款写入。
  • 用户验收后修正方向:不需要在费用明细内查看关联发票;现有逐份材料行仍然繁琐,需要一次进入连续查看全部材料。该反馈覆盖 6.9 的内联发票展示合同,已部署事实保留但不再作为目标体验。

6.11 票种摘要与整单材料预览

  • 只读核查生产真实报销:绑定票据 3 张,均为 bound、腾讯 OCR 已实际执行且无存储错误;号码/日期/金额完整。票种为 2 张电子火车票和 1 张数电发票,传统代码均不适用,火车票销售方字段不适用;未输出号码、金额、主体、文件名、UUID 或原始 OCR 结果。
  • 核查企微 SDK 合同:previewFile 仅接受单个 url/name/size;只有图片接口 previewImage 接受 urls[]。当前真实材料为 3 份 PDF 发票和 3 份 PNG 补充附件,总源文件小于 1 MiB,适合逐份 PDF 栅格化后组成有序图片包验证连续预览。
  • 用户批准采用服务端 PDF 栅格化 + 企微 previewImage,其余按统一材料入口、票种摘要和原件降级方案实施;不采用合并 PDF 或 PDF.js。
  • 删除 PC/移动费用明细中的关联发票 UI 和对应旧断言,保留后端 linkedItemId。
  • 报销详情 API 增加安全票种分类映射;共享票据格式化按普通增值税、数电发票和电子火车票显示适用字段,不重跑或改写当前真实 OCR 数据。
  • 在运行镜像加入固定 Poppler 工具,结合既有 sharp 实现有界、短时、对象授权的报销级图片预览 grant;企微一次 previewImage 原生滑动,PC/普通浏览器连续浏览,失败展开逐份原件预览降级。
  • 更新后端路由/授权/审计/超限/缓存失效测试与 PC/企微 Playwright;运行 Prisma validate、server 聚焦测试与全量基线、client typecheck/build、Trellis/governance/process/docs/sensitive/diff 门禁。
  • 稳定合同验收后再反向更新 reimbursement-invoice-ocr.md 与 wecom-boundary.md,覆盖当前“明细内发票、无聚合接口”的旧规范;提交、推送、生产部署和真实材料查看分别遵守既有批准门禁。

7. 完成条件

  • PRD 全部验收项有脱敏证据或明确由用户完成的真实业务验收结果。
  • 本任务未导入杨俊和两个既有测试成员之外的其他成员、未创建法体、未补银行资料;唯一测试业务数据已按受控生命周期清理/归档。
  • 若只完成系统就绪而真实报销尚未提交,任务保持未完成并明确剩余用户操作,不用合成测试替代。
  • 完成后归档本任务,返回 R63–R66 产品主线;不从本任务继续长出新的运维加固范围。

8. 已完成的脱敏证据

  • timer:4 个 service 构建合同一致,4 个 timer 均 enabled/active。
  • 备份:源端真实批次 success/0,ARM 独立 dead-man success/0。
  • 通讯录 dry-run:输入 1、active 1、缺手机号 1、incomplete 0、计划创建 1、冲突/跳过/失败 0。
  • 通讯录 apply:创建 1、成功 1、冲突/跳过/失败 0;角色严格为 employee,企微绑定唯一。
  • 主管接口:状态 200、更新 1、SYSTEM_USERS_BATCH_SET_MANAGER 审计新增 1;企微外部写入 0。
  • 主数据:active 费用类型 37,active 报销工作流定义 1。
  • 本地回归:5 个测试文件、61 项测试通过;Prisma schema 校验通过。
  • 公网检查:/ready 为 ok、构建标识匹配,首页 HTTP 200。
  • 只读 review:本轮只写 OA 员工、身份绑定和 OA 主管关系;未修改角色矩阵、workflow 代码、状态机、数据库 schema 或企微成员资料。
  • 测试账号受控闭环:dry-run/apply 2/2、最小角色和主管关系通过;普通浏览器双账号登录、首次改密、0.01 元测试报销、合成 PDF 上传、提交、主管退回、草稿删除、票据归档均通过;最终 OA 测试账号 archived 2、活动会话 0、企微同步 skipped 2、测试报销与 pending 待办均为 0。
  • finding:生产 OCR 为 mock 且真实腾讯 OCR 未配置,合成 PDF 自动生成 Mock 字段;草稿删除后页面导航前产生已删除详情/precheck 的 404 控制台噪声。前者阻断杨俊真实票据上传,后者不阻断业务。
  • OCR off 复验:配置切换后未改构建;三次有业务写入的复验/诊断均按“退回 → 删除 → 归档 → 停用”收口。累计 4 张合成测试票据(含第一轮)均已归档,未归档 0;测试报销与 pending 待办均为 0。
  • OCR off 结论:空发票业务字段可以绑定并提交,主管退回成功;真实使用暂由财务查看 PDF 原件并人工核对。文件 SHA-256 查重仍有效,发票号查重暂不可用。
  • 真实首跑复核:三名参与人 active 且企微绑定唯一,但企微首登均未发生;费用标准 0、适用预算池 0、active 法体 0,法体不阻断当前报销。历史 mock 票据仅 1 张且为测试账号上传,非测试员工为 0。
  • 审批规则 finding:[0,500) 可由马建勇和唯一 finance 王芝玲处理;[500,5000) 与 [5000,+∞) 均以 finance_mgr 收尾,但 active finance_mgr=0,达到 500 元会形成无人处理待办。未修正规则前不得笼统通知杨俊可提交。
  • 审批规则收口:写入前报销 reviewing/工作流 pending/待办 pending 均为 0;备份 watchdog 与 ARM dead-man 均为 success。正式接口更新 3 次、审计新增 3,生产仅剩 1 条 [0,+∞) active 规则。
  • 金额边界验证:实际工作流构造函数对 499.99、500、5000 均输出 department_manager → finance;直属主管解析到马建勇,active finance 唯一且由王芝玲承担。写后仍无报销、实例或待办新增,公网 ready 正常、构建标识未变化。
  • 真实报销生产只读核验:杨俊最新真实报销为 reviewing,工作流为 pending,当前唯一待办为主管审批且已指派主管;付款批次 0。未输出金额、单号、UUID、附件或原始 payload,未执行生产写入。
  • 真实验收 finding:主管能进入审批任务详情,但该页只有报销摘要,没有费用明细、发票、附件或完整报销单入口;因此尚未按业务事实审批。
  • 审批详情入口本地实现:移动任务详情新增“查看完整报销单”,复用移动报销详情和 state.from;PC 任务详情新增“查看报销单”。未修改后端、权限矩阵、审批状态机或列表卡片点击行为。
  • 首次聚焦 Playwright 运行因本地前端服务未启动,9 个用例均在 /login 前以 ERR_CONNECTION_REFUSED 失败,未执行到功能断言;启动 Vite 后改为只跑本次相关用例。
  • 移动聚焦用例首次进入/返回链路通过,随后因固定在 2026-05 的“已处理”测试数据超过页面最近 30 天窗口而失败;已把完成时间改为运行时近期时间,避免日历漂移。
  • 最终本地验证:npm run typecheck 通过,npm run build 通过;移动审批入口聚焦 Playwright 1/1 通过,PC 审批入口聚焦 Playwright 1/1 通过。
  • 交付门禁:当前 task validate、Trellis governance、process contract、敏感扫描和 git diff --check 均通过;文档注册审计为 0 error、1 条既有未注册文档汇总 warning。
  • 生产发布:d2841b166dc0 已部署,迁移无待执行项,发布脚本的 /ready、外部依赖、运行时和公网资源扫描通过;生产 .env 未同步。
  • 发布后运维身份:automatic backup 三项与 WARCH3 共 4 个 service 均匹配活动构建,4 个 timer 均 enabled/active;新 automatic backup daily 和源端 watchdog 均为 success/0。
  • ARM 证据边界:新批次已由 receiver 校验并 finalize;ARM dead-man timer enabled/active、最近自动结果 success/0,但本次没有扩大 sudo 权限来即时手工复跑独立 dead-man。
  • 公网入口:生产移动资源存在“查看完整报销单”,PC 资源存在“查看报销单”;只验证静态发布资源和构建身份,不读取真实报销数据。
  • 报销详情时区:共享日期时间格式化固定 Asia/Shanghai;聚焦 Playwright 将浏览器强制设为洛杉矶后,合成 UTC 附件与审批时间仍分别显示为上海 17:10、17:05,1/1 通过。
  • KISS 视觉复核:PC 与移动合成截图确认重复概况、状态、教学和空辅助区已收敛;未读取生产真实报销。Wave3 移动整段 1/1 通过;PC 大用例先通过本轮报销/审批断言,随后在未改动的合同页因找不到“筛选”按钮超时,因此不把该大用例记录为全绿。
  • 编辑态回归:R111 移动发票/附件能力 1/1 通过;PC 首轮因旧断言仍要求空“预算与审核提示”显示而失败,按新合同更新断言后,PC 发票与附件流程 1/1 通过。
  • 本地质量门禁:前端 typecheck/build 通过;task validate、Trellis governance、process contract、敏感扫描和 git diff --check 通过;文档审计 0 error、1 条既有未注册文档汇总 warning。
  • 企微旧包诊断:真机截图中的报销日期与已部署按钮属于同一个无额外条件的 JSX 块;公网 /ready 为部署构建且当前移动 chunk 包含入口文案,因此排除权限、报销关联缺失和未进入详情,结论为存活 WebView 旧包。
  • 旧包刷新护栏:页面回到前台时用 /ready 与前端构建标识做一次 no-store 比对;不一致只提示用户刷新,点击后清理 PWA 缓存并重载,同一生命周期不重复提示;一致、unknown/development、异常响应和网络失败静默。
  • 刷新护栏回归:mismatch/match/failure 聚焦 Playwright 3/3 通过,完整 login/portal UX 15/15 通过,typecheck/build 通过;375px 竖屏与 667×375 横屏无水平溢出,刷新按钮高度 44px。手机专项首次因测试在 React 壳监听器挂载前人工触发事件而失败,等待移动工作台渲染后复跑通过;未改生产或真实业务数据。
  • 原生预览调研:官方 previewFile JSAPI 与腾讯维护的 @wecom/jssdk 均确认支持企微 iOS/Android;普通 PDF 链接“只下载”不等于原生 JSAPI 不支持预览。原生调用必须提供可直接取件的短时 URL、带扩展名文件名和准确字节数。
  • 原生预览实现:服务端新增同源 JS-SDK 签名、发票元数据和附件 120 秒以内对象授权;客户端只在企微 WebView 动态加载 SDK。PC 发票使用短时 URL,PC 附件保留认证 Blob;移动发票/附件统一显示“查看原件”。未修改角色矩阵、workflow、数据库 schema 或真实业务数据。
  • 短时授权只读 review:grant 绑定用途、报销、附件、actor 与过期时间;签发前检查当前对象权限和下载理由,实际取件审计失败时不发送文件。review 发现附件 GET 初版会在普通未认证请求前查询对象,已改为无 grant 先认证、有 grant 先验签再查对象,并用回归固定 401/403 前置拒绝。
  • 原生预览回归:最终后端聚焦 3 个文件、46 项通过;服务端全量基线 169 个文件、1101 项通过;Prisma validate、touched server node --check、前端 typecheck/build 通过。聚焦 Playwright PC/企微 2/2 通过,mock bridge 收到准确 URL/name/size,企微路径未调用 window.open。
  • 原生预览治理:task validate、Trellis governance、process contract、敏感扫描与 git diff --check 通过;文档审计 0 error、1 个既有注册汇总 warning。稳定例外已写入 wecom-boundary、security-privacy 与 reimbursement-invoice-ocr spec。本步骤未部署生产,真机和真实材料验收仍待单独批准。
  • 原生预览生产发布:410d8cd71b1f 已部署,SYNC_ENV=0,62 个 migration 无待执行项;/ready、external deps、runtime smoke 与公网 bundle 扫描通过,未登录 JS-SDK 签名请求为 401。第一次尝试在同步前因示例目录权限失败且生产未变化,第二次通过活动 Compose 标签解析实际发布根目录并复用既有受控 root 运维入口成功。
  • 本次发布后运维身份:automatic backup 三项与 WARCH3 共 4 个 service 均匹配 410d8cd,4 个 timer 均 enabled/active;新 automatic backup daily 与源端 watchdog 均为 success/0。
  • 新增 finding:镜像构建审计为 client 18 个风险(10 high)、server 32 个风险(20 high、2 critical),未执行自动修复;既有部署 smoke 还会输出不必要的配置标识和测试管理员联系方式,后续需分别建立依赖升级回归和证据最小化收敛项。
  • 外部验收边界:生产已部署但企微真机中的无业务 PDF 原生预览、马建勇对真实发票与附件的可见性仍待人工验收;在材料真实可见前不得完成主管审批。
  • 移动范围对齐:管理员移动报销页新增“我的 / 全部”,默认 own,选择“全部”后请求现有 scope=all 并把 status/scope 带入详情回跳来源;普通员工即使 URL 带 scope=all 仍请求 own 且看不到切换。首轮 Playwright 因未显式指定本地 Vite 地址而在登录前连接失败;指定 E2E_BASE_URL 后功能执行,首次严格 44px 断言测得浏览器子像素值略低于 44,控件提升为 48px 后最终聚焦 2/2、同文件完整回归 5/5 通过。375px 竖屏和 667×375 横屏无横向溢出,typecheck/build 通过。
  • 移动范围生产发布:20b20b1 与 8b376f4 已推送,8b376f413585 以 SYNC_ENV=0 部署;无待执行 migration,公网 ready、external/runtime smoke、公网扫描和活动移动 chunk 标识通过。第一次本地命令在进程启动前被安全护栏拒绝,第二次因 portfolio review 令来源校验在同步前停止;临时 stash 后第三次成功,目录已原样恢复。4 个 service 构建身份匹配、4 个 timer enabled/active,新 daily 与 watchdog 均为 success/0。企微管理员真机的“全部”列表及发票/附件原生预览仍待用户验收。
  • 真实材料查看验收:用户随后确认已能从自己的企微管理员账号找到当前真实报销并查看材料;该确认只关闭查看阻断,不代表主管审批、财务审核、付款批次或最终复核已经完成。
  • 明细/材料 KISS 实现:PC 与移动端按 linkedItemId 在费用明细内显示可预览发票,未关联发票只留在统一“报销材料”区;材料区显示类型计数并以整行作为预览入口,后台类型、权限、审计、短时 URL 和企微 previewFile 均未改变。
  • 聚焦 Playwright 首轮因本地前端服务未启动,PC/移动 2 项均在 /login 前 ERR_CONNECTION_REFUSED,未进入功能断言。启动 Vite 并指定 E2E_BASE_URL 后,两端首次都因旧测试仍假设销售方文本唯一而触发 strict-mode failure;这是新界面同时在关联明细和材料区展示同一发票摘要后的断言漂移,改为按区域断言。
  • 下一轮 PC 通过,移动在“添加附件”后因测试仍从旧附件子区查找已移到统一材料区的隐藏 file input,等待至用例超时;页面快照确认实现已渲染且未发生业务错误。测试改为从材料区定位上传控件后,移动单项通过。
  • 最终本地验证:生产 build(含 typecheck)通过;R111 PC/企微双端与 Wave3 只读时区/KISS 聚焦回归 3/3 通过,企微 previewFile 参数、PC 打开 URL、关联/未关联发票、材料计数、无逐文件“查看原件”按钮、44px 触控目标和 667×375 横屏无溢出均有合成断言。
  • 最终治理:task validate、Trellis governance、process contract、敏感扫描与 git diff --check 通过;文档审计为 0 error、1 条既有汇总 warning(22 个历史未登记文件)。稳定展示合同已写入 reimbursement-invoice-ocr spec;未部署、未读取或写入真实业务数据。
  • 明细/材料生产发布:665dcab 与 0e44aa7 已推送,0e44aa72f3f5 以 SYNC_ENV=0 部署;无待执行 migration,schema、/ready、external/runtime smoke 与公网资源扫描通过,公网递归扫描 91 个 JS 资源并在 2 个活动资源中命中统一材料区标识。
  • 本次发布第一次本地命令因包含临时目录递归清理,被安全护栏在进程启动前拒绝,未生成快照、未连接或改变生产。第二次移除清理动作后,从干净 clone 发布成功;发布后按提交标识和受限临时目录模式删除本轮唯一快照,未保留构建日志。
  • 发布后运维对齐:只读检查先发现 automatic backup 三项与 WARCH3 均仍为旧构建身份;复用现有 unit 参数和运行时间刷新后,4 个 service 匹配 0e44aa7、4 个 timer enabled/active。新 automatic backup daily 与源端 watchdog 均为 success/0。
  • 本轮未同步生产 .env,未修改权限、审批状态机、企微认证或业务数据,未执行真实审批、财务审核、付款批次、银行回单或付款动作;真人企微 KISS 页面验收仍待用户刷新确认。
  • 整单材料实现:PC/移动费用明细不再渲染关联发票;只读态以一个“查看全部材料”入口生成有序图片包,企微调用一次 previewImage,PC 使用共享材料页连续显示;编辑态和失败降级仍保留逐份原件管理/查看能力。
  • 票种显示回归:合成数电发票与电子火车票分别显示正确票种;数电发票保留销售方,火车票使用购买方且不再出现“无代码 / 未识别销售方”;未重跑或改写生产 OCR 数据。
  • 后端验证:聚焦 5 个测试文件、23 项通过;服务端全量 171 个文件、1109 项通过,Prisma validate 与 touched-file node --check 通过。新增断言覆盖顺序、页/源/输出/缓存上限、token 篡改、缓存缺失、下载理由、访问审计失败和安全票种映射。
  • 前端验证:生产 build(含 typecheck)通过;R111 PC/企微 2/2 通过,覆盖费用明细无发票入口、票种文案、统一计数、材料页与一次有序 previewImage.urls 调用。
  • 目标镜像验证:server_build 成功安装 poppler-utils;Playwright 生成的无业务合成单页 PDF 经容器内生产 reimbursementMaterialPreview 转换为 1 页 PNG,探针结果为 raster-probe-pass。未合并、改写或使用真实票据。
  • 治理复核:task validate、Trellis governance、process contract、敏感扫描和 git diff --check 通过;文档审计 0 error、1 条既有汇总 warning(22 个历史未登记文件)。首次敏感扫描命令误指向不存在的旧路径并立即失败,改用当前 scripts/qa/check-sensitive-content.mjs 后 30 个变更文件、0 finding;该失败未执行生产或业务写入。
  • 本步骤只完成本地实现与验证;未推送、未部署、未修改生产配置或真实业务数据,不能据此通知真人线上测试。