# hyb-oa 实施计划(历史 Phase 1 引导 + 当前执行口径) **日期**:2026-05-04 **范围**:保留 2026-02 的引导性实施计划,同时补充当前试运行收口与外部环境闭环口径。 ## 当前阶段(2026-05-04) - 当前系统已不处于 `Phase 1 / P0` 开发阶段;本地核心 happy path、真实 PDF OCR 和报销付款尾链已具备回归证据。 - 当前优先级不是继续堆新功能,而是: 1. 治理事实源刷新 2. 外部环境闭环(HTTPS / 企微 / live smoke / 并发) 3. 发布门禁与部署 runbook 收口 - 当前执行事实源优先级: - 最新执行合同:`issues/*.csv` - 业务覆盖:`artifacts/r75/coverage-matrix.csv` - 试运行结论:`artifacts/r70/manual-trialrun-report.md` - 全局状态矩阵:`docs/feature-matrix.md` ## 历史说明 下文保留的是 2026-02 的 Phase 1 引导计划,主要用于追溯设计出发点、资产复用和里程碑拆解;它**不是**当前最优先的执行合同。 ## 0. 前置结论(不可再分叉) - 技术栈:Fastify + Prisma + PostgreSQL(见 `docs/tech_stack_report.md`) - 规格书:以 `docs/requirements-specification.md` 为单一事实源 ## 1. 历史:复用资产清单(从 shenzhou-business-suite 迁移到 hyb-oa) | 资产 | 来源 | 复用方式 | 需要改造 | | :--- | :--- | :--- | :--- | | 工作流 4 表结构 | `shenzhou-business-suite/supabase/schema/70_workflow/01_workflow_02_tables.sql` | 转 Prisma schema | Supabase/RPC → Fastify service 事务 | | `approval_rules` | 同上 | 转 Prisma schema + seed 3 条 | 管理 UI 放 P1(P0 先 DB/接口维护) | | `approval_transfers` | 同上 | 转 Prisma schema | 与 `workflow_tasks` 联动,reason≥10 约束 | | `document_sequences` | 同上 | 转 Prisma schema + seed 默认报销单号 | 生成逻辑改为服务端原子更新 | | 权限码体系 | `shenzhou-business-suite/src/types/permissions.ts` | 复用命名与粒度 | 增加 `expense.proxy_submit/proxy_manage` | | 工作流类型 | `shenzhou-business-suite/src/types/workflow.ts` | 参考 JSON 结构 | P0 只用线性审批链(后续扩展保留) | | 报销表结构参考 | `shenzhou-business-suite/supabase/schema/20_finance/06_reimbursement_01_tables.sql` | 参考 forms/items/attachments 字段 | 补 `file_sha256`、签名 URL、判重例外审计 | | 默认费用类型 seed | `shenzhou-business-suite/supabase/seed.sql` | 迁移 35 启用 + 3 legacy 禁用 | hyb-oa 额外启用 `utilities/rent` 形成 37 启用 | | 存储安全基线思路 | `shenzhou-business-suite/supabase/migrations/20260131175000_storage_security_baseline.sql` | 迁移约束到 API 层 | P0 本地存储 + 签名 URL;P2 MinIO/OSS | | UI 组件 | `shenzhou-business-suite/src/components/ui/*` | 实现阶段复制到 `client/src/` | 替换路由/样式变量;移除 Supabase 依赖 | | 测试基建 | `playwright` + `vitest` 配置 | 实现阶段迁移 | P0 覆盖鉴权/工作流/判重核心路径 | ## 2. 历史:Phase 1(P0)里程碑拆解(按可开工顺序) ### Milestone 1:Prisma schema 草稿 + 评审 **目标**:把关键表结构确定下来(后续开发不再反复改 schema)。 **范围(至少)**: - 组织/人员:`departments`、`employees`、`employee_roles` - 权限:权限码为代码常量;角色集合落 `employee_roles` - 报销:`reimbursement_forms`、`reimbursement_items`、`invoice_pool`(票据/附件池 + 绑定关系) - OCR:`ocr_results`(OCR 去重与结果持久化) - 费用类型:`expense_types`(含 37 默认启用 seed) - 单号:`document_sequences` - 工作流:`workflow_definitions`、`workflow_instances`、`workflow_tasks`、`workflow_history` - 审批规则/转审:`approval_rules`、`approval_transfers` - 认证与审计:`auth_sessions`、`audit_logs` - 代提交授权:`delegation_grants` **验收**: - schema 与 `docs/requirements-specification.md` 一致 - 关键约束可实现(单号唯一、转审原因≥10、费用类型 code 唯一、软禁用等) **评审截止(Schema Freeze)**: - 截止:Milestone 1 合并后的 **2 个工作日** - 截止后变更规则: - 仅允许 `ADD COLUMN / ADD TABLE / ADD INDEX` 这类向前兼容变更 - `DROP/RENAME/CHANGE TYPE/CHANGE NULLABLE` 等破坏性变更必须走“变更申请”,并同步更新规格书与迁移计划 ### Milestone 2:认证与会话(JWT + refresh cookie) **范围**: - `POST /api/auth/login|refresh|logout|forgot-password|reset-password` - `auth_sessions`:refresh hash + deviceFingerprint/ip/UA + session 限额(5) - `tokenVersion` 踢下线 **验收**: - refresh rotation 生效;退出/重置能撤销会话;access 不落 localStorage ### Milestone 3A:发票池上传(本地存储)+ SHA256 + 签名 URL **范围**: - `POST /api/invoice-pool/upload`(multipart;入参 `file` + 可选 `owner_employee_id` + 可选 `ocr_type`;返回 `invoice_pool_id`) - `POST /api/invoice-pool/:id/signed-url`(TTL=10m) - 上传约束:类型白名单 + ≤10MB - 哈希:计算并落库 `file_sha256`(作为 OCR 去重 key) **验收**: - 未授权用户无法获取签名 URL;过期不可访问;同文件哈希可用于 OCR 去重复用 ### Milestone 3B:腾讯云 OCR + `ocr_results` 去重 + retry 策略 **范围**: - OCR:调用腾讯云 OCR,保存“标准化结果”(rawResponse 仅日志不落库) - 去重:`ocr_results` 以 `file_sha256 + ocr_provider + ocr_type` 唯一,命中时复用(不重复计费) - 状态机:`invoice_pool` 从 `pending_ocr` → `available/ocr_failed` - 重试:`POST /api/invoice-pool/:id/retry-ocr`(attempt<=3;间隔>=60s;错误码 `VALID_006/VALID_007`) - 审计:`OCR_REQUESTED/OCR_SUCCEEDED/OCR_FAILED/OCR_RETRIED` - 自动归档:`available/ocr_failed` 未绑定条目 90 天后自动归档为 `archived_reason=unused_timeout` **验收**: - 同一文件二次上传不重复计费;OCR 失败可重试且次数/频控生效;90 天游离自动归档生效且不参与全局判重;状态与审计一致 ### Milestone 4:费用类型系统(动态 `expense_types`) **范围**: - `GET /api/expense-types?enabled=true` - seed:默认启用 37 项 + legacy 3 项禁用 - 软禁用语义:禁用后不出现在下拉,但历史可展示 **验收**: - 下拉加载启用类型;禁用类型不显示但历史单据不丢 ### Milestone 5:单号生成(`document_sequences`) **范围**: - 报销单号:`BX-YYYYMMDD-0001`(daily reset) - 生成逻辑:数据库原子递增(同事务写入 `reimbursement_forms.form_number`) **验收**: - 并发下无重复编号;失败回滚不产生脏占用 ### Milestone 6:报销单 CRUD + 提交发起工作流 **范围**: - 报销单:创建/更新/删除草稿/查看 - 发票池绑定/解绑:`POST /api/invoice-pool/:id/bind|unbind`(并发行锁;冲突 409/`VALID_005`;绑定时触发全局判重 409/`VALID_003`) - 删除草稿:自动解绑其绑定的发票池条目并回到 `available` - 提交:校验 items、票据/发票要求(发票池绑定)、判重;生成单号;启动工作流实例并创建首个任务 - 代提交:校验 `delegation_grants`(scope & 生效时间) - 代提交授权(Delegation Grants)CRUD API(用于自助/代维护): - `GET /api/delegation-grants`(默认返回与本人相关;`system.users` 可查询任意) - `POST /api/delegation-grants`(本人创建:principal=自己;`system.users` 可代创建) - `POST /api/delegation-grants/:id/revoke`(本人撤销;`system.users` 可代撤销) **验收**: - draft → submitted/reviewing;workflow_instance/task/history 创建完整 - delegation_grants 可被创建/查询/撤销;所有变更写入 `audit_logs` ### Milestone 7:审批动作(approve/reject/return/withdraw/transfer) **范围**: - `approval_rules` 匹配审批链(3 条默认规则) - `POST /api/workflow/tasks/:taskId/approve|reject|return` - `POST /api/workflow/tasks/:taskId/transfer`(reason≥10;链路≤3) - 审计:动作写入 `workflow_history`;关键例外写 `audit_logs` **验收**: - 审批推进正确;转审三处证据齐全;状态与任务一致(status=reviewing 但节点来自 task) ### Milestone 8:付款标记 + 发票判重例外 + 发票池归档 **范围**: - `POST /api/reimbursements/:id/pay`(需 `expense.finance.pay`) - 付款完成联动:将该报销单绑定的发票池条目归档(`status=archived, archived_reason=used_complete`) - 发票双策略判重 + 例外(仅 `finance_mgr`,需原单号+原因,原单 `approved/paid` 禁止) **验收**: - approved → paid;发票池条目自动归档为 `used_complete`;例外受限且审计完整 ### Milestone 9:最小 CI 门槛(护栏) **范围**: - typecheck + lint(不改写源码) - 最小集成测试:登录/发票池上传+OCR+绑定/提交/审批/转审/判重/付款标记/归档 - 安全回归:敏感字段脱敏测试(银行卡/身份证等字段在所有对外响应均为脱敏格式;审计日志禁止明文) **验收**: - CI 通过:typecheck + lint + 最小集成测试 + 脱敏测试全绿 ## 3. Phase 2(扩展) > 状态口径说明(2026-02-09): > - 已落地:OCR 增强、报表导出、对象存储(MinIO/OSS)、工作流扩展到其他实体(最小骨架)。 > - 待推进:企微/钉钉通知(渠道扩展)。 > - 详细状态与证据以 `docs/feature-matrix.md` 与 `issues/2026-02-09_13-39-02-p5-blueprint-v3.csv` 为准。 - [x] OCR 能力增强(队列化与重试策略) - [ ] 企微/钉钉通知 - [x] 报表导出 - [x] 对象存储(MinIO/OSS) - [x] 工作流扩展到其他实体(请假/采购) ## 4. 风险与阻塞项(P0) - 财务对“费用类型/科目默认值”仍可能需要微调:通过 `expense_types` 配置解决,避免改代码 - 转审/例外权限属于高风险动作:必须上线前完成审计与权限回归测试