文件
hyb-oa/docs/tech_stack_report.md
T
wangsli f527633716 feat(server): 完成 P0+P1 后端能力(工作流、RBAC、付款归档)
P0 MVP:

- 认证:login/refresh/logout/forgot/reset + tokenVersion

- RBAC:角色到权限映射 + requirePermission

- 发票池:upload/bind/signed-url + 判重(VALID_003/VALID_005)

- 报销:create/view/submit + 单号生成

- 工作流:approve + department_manager 解析

P1 扩展:

- 动作:reject/return/withdraw(含 comment)

- transfer:任务转审 + 链路上限 3

- pay:approved -> paid + 发票归档 used_complete

- 动态审批链:approval_rules 驱动

回归脚本:

- smoke-test.sh / regression-dedup.sh / regression-workflow-actions.sh
2026-02-07 16:43:31 +08:00

67 行
4.5 KiB
Markdown
原始文件 Blame 文件历史

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
# hyb-oa 技术栈与复用报告(定案)
**日期**:2026-02-05
**适用范围**:OA 报销系统(Phase 1)
## 1. 定案结论(统一口径)
| 层级 | 选型 |
| :--- | :--- |
| 前端(OA) | React + Vite + Tailwind |
| 后端(OA API) | Fastify |
| ORM | Prisma |
| 数据库 | PostgreSQL |
| 认证 | JWT(access + refresh rotation),refresh 以 httpOnly Cookie 传输 |
| 权限 | RBAC(权限码) |
| 审计 | `workflow_history`(流程)+ `audit_logs`(安全与关键变更) |
| 部署 | Docker + Nginx(反向代理) |
## 2. 关键取舍(为什么这么选)
### 2.1 常驻 Node 服务场景:优先“稳定性/少踩坑”
本项目目标是云服务器常驻 Node 服务 + 长期演进,因此选型优先级为:
1) 工具链成熟度与可维护性
2) 团队上手成本与踩坑风险
3) 可观测性/审计/权限等生产配套
4) 性能(在常驻服务场景下,冷启动优势不显著)
### 2.2 Prisma vs Drizzle(定案:Prisma)
- Prisma:迁移范式统一、资料多、团队协作成本低;适合“新人不踩坑”
- Drizzle:更轻、更 SQL 直观,但更依赖团队 SQL/事务/索引纪律;在本项目“稳定性优先”的定义下不作为默认
### 2.3 Fastify vs Hono(定案:Fastify)
- Fastify 适合常驻服务:生态成熟、插件与生产实践丰富(鉴权、日志、schema 校验等)
- Hono 更偏极简/Edge/Serverless 方向;并非本项目的默认最优解
### 2.4 为什么不使用 Supabase(本项目定案)
本项目部署形态为“自建常驻 API + 自建权限/审计/工作流/文件存储”,Supabase 在此形态下会带来:
- 额外的运维与概念复杂度(RLS、RPC、Storage、Auth 等)
- 架构边界不清(哪些逻辑在 DB,哪些在服务层)
因此 hyb-oa 选择“Fastify + Prisma + PostgreSQL”作为单一事实源。
## 3. 复用资产清单(来自 `shenzhou-business-suite`)
> 原则:复用“成熟结构/约束/枚举/经验”,把改造集中在“Supabase 调用 → REST API 调用”。
| 资产 | 来源路径(参考) | 复用价值 | 备注/改造点 |
| :--- | :--- | :---: | :--- |
| 工作流引擎 4 表 + `approval_rules`/`approval_transfers`/`document_sequences` | `shenzhou-business-suite/supabase/schema/70_workflow/01_workflow_02_tables.sql` | ⭐⭐⭐⭐⭐ | 转 Prisma schema;工作流事务由 Fastify 服务层实现 |
| 工作流配置/类型(assignee_rule 等) | `shenzhou-business-suite/src/types/workflow.ts` | ⭐⭐⭐⭐ | 作为工作流 JSON 配置与契约参考 |
| 权限码体系 | `shenzhou-business-suite/src/types/permissions.ts` | ⭐⭐⭐⭐ | 复用命名与粒度;补 `expense.proxy_*` |
| 报销表结构参考(forms/items/attachments) | `shenzhou-business-suite/supabase/schema/20_finance/06_reimbursement_01_tables.sql` | ⭐⭐⭐⭐ | 字段设计参考;hyb-oa 简化并补 `file_sha256` 等 |
| 默认费用类型 seed(35 启用 + 3 legacy 禁用) | `shenzhou-business-suite/supabase/seed.sql` | ⭐⭐⭐⭐⭐ | hyb-oa 额外启用 `utilities/rent` 形成 37 启用 |
| 存储安全基线(类型/大小/访问控制) | `shenzhou-business-suite/supabase/migrations/20260131175000_storage_security_baseline.sql` | ⭐⭐⭐⭐ | 思路迁移到“本地存储 + 签名 URL” |
| UI 组件(shadcn/ui 风格) | `shenzhou-business-suite/src/components/ui/*` | ⭐⭐⭐⭐ | 实现阶段复制到 `hyb-oa/client/src/`(需统一路径与样式变量) |
| 报销前端页面结构 | `shenzhou-business-suite/src/pages/finance/reimbursement/*` | ⭐⭐⭐ | 需移除 Supabase 调用,替换为 OA API |
| 测试框架 | `shenzhou-business-suite/playwright.config.ts` + `vitest.config.ts` | ⭐⭐⭐ | 实现阶段迁移;补齐鉴权/工作流核心路径 |
## 4. 关键设计原则(写入规格书的那几条)
- 状态 vs 节点分离:报销单 `status` 固定 7 状态;审批节点由 `workflow_tasks` 驱动
- 配置驱动:`approval_rules`/`expense_types`/`document_sequences` 均可配置;P0 预置默认值即可生效
- 审计分层:
- `workflow_history`:流程动作与审批链路(权威)
- `audit_logs`:登录/敏感字段/配置变更/判重例外等安全关键事件
- 文件存储:P0 本地存储 + 签名 URL;P2 切换 MinIO/OSS(接口不变)
## 5. 与本仓库当前现状对齐(信息校验)
- `server/package.json` 已包含:`fastify`、`@fastify/jwt`、`prisma/@prisma/client`、`zod`
- `docker-compose.yml` 已提供 PostgreSQL 15(本地/开发用)