归档五人团队正式内用最小收口(07-18-small-team-internal-readiness)

这个提交包含在:
2026-07-18 15:49:18 +08:00
父节点 5d0a5f9a38
当前提交 b3dadfa1bf
共修改 6 个文件,包含 3 行新增和 3 行删除
@@ -0,0 +1,8 @@
{"file":".trellis/spec/hyb-oa/project-governance.md","reason":"验证任务合同、复审、提交和归档边界"}
{"file":".trellis/spec/hyb-oa/backend-fastify-prisma.md","reason":"验证权限、事务、迁移与服务端回归"}
{"file":".trellis/spec/hyb-oa/frontend-react-vite-design.md","reason":"验证页面一致性、响应式和浏览器证据"}
{"file":".trellis/spec/hyb-oa/approval-workflow.md","reason":"验证审批角色、自审和 workflow 约束"}
{"file":".trellis/spec/hyb-oa/docs-and-evidence.md","reason":"验证证据、finding 生命周期和文档事实源"}
{"file":".trellis/spec/hyb-oa/security-privacy.md","reason":"验证敏感字段、日志、附件与安全摘要"}
{"file":".trellis/spec/hyb-oa/deployment-trialrun.md","reason":"验证本地候选结论没有越界为已部署"}
{"file":".trellis/tasks/archive/2026-07/07-16-system-multidimensional-audit/research/findings.md","reason":"逐项核对已承接 finding 的状态和证据"}
@@ -0,0 +1,99 @@
# 五人团队正式内用最小收口设计
## 实施顺序
1. **角色与敏感资料**:先完成 enum/权限常量、账号与角色边界、员工 DTO、工资/银行/证件/合同授权及矩阵测试。
2. **付款一致性**:在新角色合同稳定后完成候选查询、行锁状态机、取消原因、回单作废、前端选择器及 PostgreSQL 并发验证。
3. **页面与门禁**:完成共享表格、dirty guard、移动路由、权限显隐、路由 manifest 和 `local-candidate` runner,最后回填旧标题任务。
每阶段先跑聚焦测试再扩展到全量。权限、状态机、workflow 和迁移在实现后由只读 reviewer 复核,不让 reviewer 修改代码。
## 角色与权限设计
### 角色模型
- `employee` 是所有日常账号基础角色。
- `manager`、`ceo`、`finance`、`system_admin` 是可兼任职责。
- `finance_mgr`、`hr`、`administration` 保留兼容,不自动迁移。
- `admin` 仍映射 `*`,仅现有超级管理员/初始化流程可用;普通创建和普通角色编辑不提供该选项。
### system_admin 授权
允许:账号创建/启停/凭据重置、为其他用户分配普通业务角色、系统设置、集成、通知渠道、脱敏审计查看。
拒绝:修改自身角色、授予或撤销 `admin/system_admin`、人员完整档案、工资、银行/证件、员工合同、业务审批、付款制单/执行/复核。
普通角色修改继续使用既有 endpoint,但服务端按操作者角色和目标用户实施额外约束;UI 限制只做体验,不作为安全边界。角色变更审计只记录操作者、目标用户 ID、前后角色代码和结果,不记录凭据或员工敏感字段。
### 敏感资料数据流
```text
角色/对象判断 -> 选择最小 Prisma select -> DTO 字段省略 -> 前端按权限渲染
-> 脱敏审计(成功访问/写入)
```
- 业务员工目录固定字段:`id / employeeNo / name / title / department / avatar / status`。
- 完整 profile:本人或人员资料管理权限。
- 银行资料:finance 只读;admin/明确管理权限可写。
- 证件、员工合同:仅明确管理权限;内部路径、原始正文和不必要文件名不进入 DTO/审计。
## 付款设计
### 状态机
```text
draft -> reviewed -> executed
-> failed -> executed(仅失败项)
-> cancelled(仅未执行项)
-> cancelled
```
- `executed`、`cancelled` 终态;已执行 item 永不回滚。
- review 需要 `payment.batch.review` 且角色代码包含 `manager` 或 `ceo`;创建者自审返回 409。
- 50000 元阈值只影响警示/确认文案,不增加状态或第三复核人。
### 锁与并发
- review/execute/cancel/付款元数据更新/回单作废:同一事务内先 `SELECT ... FOR UPDATE` 锁批次。
- create:稳定排序并锁定源报销,复查 `approved`、未付款且未进入非 cancelled 批次。
- execute:稳定排序锁定开放 item 对应源单,再复查状态、金额和回单门槛。
- 竞争失败统一返回 409 业务码;失败重试按所有 item 最终状态重算汇总。
- `payment_batch_v1` 启用时旧直接付款端点返回兼容性 409;关闭 flag 可回滚旧代码路径。
### API / 数据
- Prisma 加法迁移:`RoleCode.system_admin`;`payment_batches.cancelled_reason TEXT NULL`。
- `GET /api/payment-batches/candidates?q=&page=&pageSize=` 返回业务展示字段,entity ID 仅用于后续提交。
- 取消 body:`{ reason }`;DTO 增 `cancelledReason`。
- 回单作废:`{ reason }`;复用现有治理/归档字段,不物理删除。
- 旧 DELETE/直接付款仅作为 feature flag 回滚路径;新版开启时不得产生第二写路径。
### 迁移与回滚
- 只提交加法 migration,不运行 migrate deploy,不修改真实数据。
- 代码回滚时关闭 `payment_batch_v1` 并回退应用提交;enum 和 nullable 列保留,避免破坏已写数据。
- 一旦部署后曾授予 `system_admin`,回退到不识别该枚举值的旧应用前,必须先在兼容版本中撤销或转换该角色,或保留可识别该值的兼容解析;不得让旧 Prisma client 直接读取未知枚举值。
- 不修改迁移历史,不执行 migrate reset。
## 页面与门禁设计
- 表格修复优先调整共享容器:表格自身保留最小宽度,容器 `overflow-x:auto`,document 不横溢;五个代表页做命中和尺寸断言。
- dirty guard 使用共享 hook/provider,统一拦截站内导航、浏览器返回/刷新和记录切换;保存成功或显式放弃后清除 dirty。
- `/mobile/attendance` 复用现有响应式考勤页;移动 resolver、首页和通知目标统一使用该路径,避免 `/attendance -> /mobile` 自循环。
- 移动归档只处理长字段换行/局部 overflow 和底栏安全区,不扩展移动信息架构。
- 路由 manifest 每条注册路由必须显式分类;`core` 必须有可实际执行的行为 spec,标记 `visualRequired` 的路由还必须有视觉 spec;manual/live 文件不计本地候选证据。
- `local-candidate` 组合基础门禁、路由/流程可信扫描和核心本地浏览器测试,不读取公网或生产环境变量。
## 验证矩阵
- **权限**:employee / manager / ceo / finance / system_admin / admin 正负矩阵;字段省略;拒绝时零 DB/file side effect;角色自提升负例。
- **付款**:候选筛选、POST 权威拒绝、maker-checker、高额单次复核、取消原因、回单作废、审计、失败重试和权限负例。
- **PostgreSQL 并发**:双 execute、execute vs cancel、双 create 同一报销、direct pay vs batch execute;使用隔离合成数据库并清理。
- **浏览器**:375×812 移动考勤/归档;768×1024 与 1024×768 五类表格;四类 dirty form;危险动作 0/0/1 mutation;三处权限按钮 count=0。
- **门禁反例**:unclassified、manual-only、core behavior missing、visualRequired missing 均非零退出。
## 证据与状态
- 截图和临时浏览器产物放 `output/playwright/07-18-small-team-internal-readiness/`,只保留合成/脱敏内容。
- 原 finding 台账只更新当前修复状态和证据引用,不改发现时严重度;未部署项继续保持部署/外部验证待定。
- 本地完成结论固定为 `LOCAL_CANDIDATE_PASS`。
@@ -0,0 +1,93 @@
# 五人团队正式内用最小收口证据
## 证据身份与边界
- 发现基线:`bbb5c89`;规划基线:`58c8dec`。
- 复核对象:本文件所在工作提交;提交前所有结果仅归属于当前受控工作树,提交后以本文件所在提交为 `reviewedCommit`。
- 允许环境:回环 HTTP、回环 PostgreSQL、合成角色/业务数据、无网络外部适配器。
- 未执行:部署、push、公网、生产配置、共享或真实数据库、真实账号、企业微信真机、真实 OCR、真实付款、银行流水和 ERP。
- 状态上限:`LOCAL_CANDIDATE_PASS`;不得据此告知用户线上可测试。
## 最终门禁摘要
| 证据 | 结果 | 关键结论 |
| --- | --- | --- |
| 权限与敏感资料只读复审 | PASS,聚焦 107/107;统计权限 4/4 | `system_admin` 与经理/CEO/财务/超级管理员分离;工资/绩效汇总使用独立敏感权限,拒绝路径先于敏感查询或文件读取。 |
| 付款状态机只读复审 | PASS,聚焦 36/36;重试回归 27/27 | maker-checker、锁顺序、直付关闭、失败项重试、取消/回单审计均无 P1。 |
| 候选 workflow 只读复审 | `PASS_WITH_FOLLOWUPS`,follow-up 已修复 | witness 来源、结果 parser、loopback、模式标签与无历史 Issue CSV 依赖均有反例。 |
| migration 只读复审 | PASS,无 P1/P2 未结项 | 两项加法 migration;`system_admin` 位于 `admin` 前;可空取消原因;回滚前置已记录。 |
| 服务端全量 | PASS,161/161 文件、985/985 测试 | 包含用户导入 8/8、付款批次 27/27、员工统计权限 4/4。 |
| 前端静态门禁 | PASS | typecheck 与 Vite production build 通过;仅既有 Browserslist 提示。 |
| 默认完整基础门禁 | PASS,exit 0 | `bash scripts/check-minimal.sh` 的历史流程基线、984 项服务端测试、前端 build 与功能矩阵全部通过;本机 stub 使用回环权限。 |
| 路由与候选反例 | PASS,52/52 | 71 条路由全部分类;10/10 核心流程束、10/10 witness、7/7 acceptance、0 blocking gap。 |
| 隔离 PostgreSQL | PASS,exit 0 | 当前 61 项 migration 从空库应用;五组付款竞态 PASS;审计/通知唯一;临时库残留 0。 |
| Playwright focused | `FOCUSED_BROWSER_PASS`,44/44 | 0 failed、0 skipped、0 unexpected;10 个 witness 均来自指定 spec。 |
| Playwright/full 候选 | `LOCAL_CANDIDATE_PASS`,exit 0 | 2026-07-18 13:27 CST 完成;44/44,0 failed、0 skipped、0 unexpected;基础层与结果门禁同时通过。 |
默认门禁第一次在禁止回环监听的沙箱内运行时,两个本机 stub 测试未能产生完整结果;允许本机-only stub 后聚焦 12/12 通过,随后原命令完整 exit 0。该诊断未访问公网,也未作为 PASS 替代原命令。
## PostgreSQL 竞态与迁移证据
命令:`bash scripts/qa/run-web-gates.sh payment-concurrency-local`。
- 双执行:一个成功、一个确定性 409;付款/执行审计和内部通知各唯一。
- 执行与取消:本轮执行成功、取消 409;无重复状态或副作用。
- 双创建:一个 201、一个 409;仅一个有效批次/项及一条创建审计。
- 直接付款与批次付款:范围外均拒绝且零副作用;范围内直付 409、批次执行成功。
- 缺失制单人:复核 409,批次保持 draft,零复核审计。
- 空库 migration 后只读确认枚举相邻顺序为 `system_admin` 后接 `admin`。
- runner 与独立检查结束后,`hyb_oa_payment_%` 临时数据库计数为 0。
## 十个核心流程 witness
每项均断言最终路径、唯一 H1、合成角色、允许/禁止动作,以及 `unhandled API / page error / 非白名单 console error = 0`。
| 流程束 | 最终路径 | H1 | 角色 fixture | 允许动作 | 禁止动作 |
| --- | --- | --- | --- | --- | --- |
| 登录退出 | `/login` | 海音达 OA | employee | 登录 | 应急超级管理员 |
| 报销 | `/reimbursements` | 我的报销 | employee | 新建报销 | 导出 |
| 审批 | `/workflow/tasks` | 待我处理 | manager | 处理 | 通过 |
| 票据 | `/invoice-pool` | 票据 | employee | 上传票据 | 作废 |
| 采购 | `/purchase-requests` | 采购 | employee | 新建采购 | 通过 |
| 项目/合同 | `/contracts-registry` | 合同 | manager | 新增合同 | 执行付款 |
| 付款/AP | `/payment-batches` | 付款 | finance | 新建批次 | 复核批次 |
| 人员/审计 | `/system/users` | 系统用户管理 | system_admin | 新建用户 | 应急超级管理员 |
| 考勤/归档 | `/mobile/attendance` | 考勤 | employee | 修正申请 | 提交应急修正 |
| 移动工作台 | `/mobile` | 今天待办 | employee | 新建报销 | 财务 |
## 浏览器视口与截图
- 移动:375×812,覆盖移动考勤、归档空态、长字段详情、换行、底栏遮挡与页面横溢。
- PC:768×1024、1024×768,覆盖项目、资产、合同、付款、报销五类表格;局部横滚可用、右侧操作可命中、document 横溢不超过 2px。
- 截图均使用合成身份和合成业务记录,已人工复核未见真实资料、内部 Secret、完整账号、银行资料或原始 payload。
- 产物目录为 `output/playwright/07-18-small-team-internal-readiness/`;最终 full 复跑后的 SHA-256 如下。
| 截图 | SHA-256 |
| --- | --- |
| `assets-1024x768.png` | `d3d0ff0d9dd413521a068ca1c87ad6978d12d08e836d6fe3c1048559f013014b` |
| `assets-768x1024.png` | `1a5c9b07617479cfa14fa9a4525bbdf32fac6eb74635d8dbd7641e319871abbc` |
| `contracts-registry-1024x768.png` | `f318e1637f3eb65eb853f3d0436c1825efca4fcc9336b80a6cccb6ab7236b3b9` |
| `contracts-registry-768x1024.png` | `5ce2b667aef2fd24cdc918729fe998327991246417477d6301f8314406bde7dd` |
| `desktop-archive-1024x768.png` | `9d099e825e897f37383ee7d40622322946356a9dd89b8893d9531120da6750f6` |
| `mobile-archive-detail-375x812.png` | `6a1359c4bae284cd68872faa148755e2b6fc53b7be41b1739ae2aff0090a9436` |
| `mobile-archive-empty-375x812.png` | `9b6fb325287e4436de7a71f80cf5b75c3a4e5d4f183b8919af5ffa59cf1070ca` |
| `mobile-attendance-375x812.png` | `01f75c88be01b4e4ab0696bb1de39f211eaaee402377757bf7384a278c197a7d` |
| `payment-batches-1024x768.png` | `0d8f69b360a7fbfcf5a0774aa031a0c6845dac6f468a28486c72a575db0a8db1` |
| `payment-batches-768x1024.png` | `72554a7d3a6778547a69732a5a2c1cf49bfdb2e1394acb3f465782becd559ef1` |
| `projects-1024x768.png` | `cf925dede4124e1780c8a9e67e82bf596e96278131fd03c1a115e6d45dd22eba` |
| `projects-768x1024.png` | `da5dd4b0842b407d715b91e5025f8b4e6c68cb7d7b5a87c0e460630a95f40308` |
| `reimbursements-1024x768.png` | `30726bbdba0d8dc0e80d8aa269c57996d72ce0564c84c333b7cb8a97e832e096` |
| `reimbursements-768x1024.png` | `46a146af17f1f69069492b1232071de4ae55f81f73a36ed95d5672f56e887621` |
## Finding 生命周期边界
- 原 finding 台账已按本证据更新本地修复状态,未改写发现时严重度、置信度或发现状态。
- `05-31-unified-page-header-actions` 的权限显隐、资产旧 E2E、七页面标题动作及项目/资产视觉验收已闭合,并归档至 `archive/2026-07/`。
- 本地验证通过的条目只更新 `当前修复状态=LOCAL_FIX_VERIFIED`。
- 未部署的运行时条目继续 `DEPLOYMENT_PENDING`;企业微信/角色/公网行为继续 `EXTERNAL_BEHAVIOR_PENDING`。
- 纯测试/门禁条目使用 `NOT_APPLICABLE` 部署状态;不需要外部行为的条目使用 `NOT_REQUIRED`。
- 移动通知定位只闭合考勤入口增量;其他对象定位不在本任务范围,`MOB-TARGET-001` 整体保持开放。
## 后续授权边界
真实账号职责分配、超级管理员托管、内部地址部署、migration 执行、备份恢复、部署来源、公网角色、企业微信真机和新 Day 1 连续试运行均由后续获批 Trellis task 承担。
@@ -0,0 +1,8 @@
{"file":".trellis/spec/hyb-oa/project-governance.md","reason":"任务、审批、迁移、复审和提交边界"}
{"file":".trellis/spec/hyb-oa/backend-fastify-prisma.md","reason":"Fastify、Prisma、事务、迁移和服务端测试规则"}
{"file":".trellis/spec/hyb-oa/frontend-react-vite-design.md","reason":"React/Vite 页面、权限显隐、响应式和视觉验证规则"}
{"file":".trellis/spec/hyb-oa/approval-workflow.md","reason":"经理、公司负责人、自审和审批链合同"}
{"file":".trellis/spec/hyb-oa/reimbursement-invoice-ocr.md","reason":"报销、付款、附件和回单业务边界"}
{"file":".trellis/spec/hyb-oa/security-privacy.md","reason":"员工敏感数据、审计脱敏和附件安全边界"}
{"file":".trellis/spec/hyb-oa/deployment-trialrun.md","reason":"LOCAL_CANDIDATE 与部署/公网结论分离"}
{"file":".trellis/tasks/archive/2026-07/07-16-system-multidimensional-audit/research/findings.md","reason":"本任务承接 finding 生命周期与控制目标"}
@@ -0,0 +1,105 @@
# 五人团队正式内用最小收口
## Goal
在不部署、不连接真实数据、不进行公网或企业微信真机验证的前提下,把当前代码收敛为适合约 5 人公司内部使用的本地候选版本。角色上明确分离业务管理、财务和 OA 系统运维;业务上保证付款状态、敏感资料和高影响操作可控;工程上建立可信的本地候选门禁。
本任务承接用户在 2026-07-17 批准的 `07-17-small-team-internal-readiness` 方案。由于任务实际创建日期为 2026-07-18,Trellis 目录按规则使用 `07-18-small-team-internal-readiness`。
## Scope
- Backend:Fastify 权限、员工/账号/工资/合同和付款批次路由,Prisma 加法迁移,聚焦与并发测试。
- Frontend:角色管理、敏感资料与付款页面、共享表格/dirty guard、移动考勤与归档、聚焦 E2E/视觉断言。
- QA / governance:路由分类、流程覆盖扫描、`local-candidate` runner、当前 task、必要 Trellis spec/现有手册及 finding 生命周期。
- 只使用本地合成数据和隔离测试资源;不改变生产配置或真实数据。
## Requirements
### 角色、权限与敏感资料
- 所有账号保留员工基础能力;日常职责可显式兼任 `manager`、`ceo`、`finance` 和新增 `system_admin`。
- `manager` 与员工 `direct_manager_id` 分开维护;经理身份不自动建立汇报关系。
- 新增 `RoleCode.system_admin`。现有 `admin` 继续作为通配超级管理员,但只用于初始化和应急,不作为普通预设。
- 普通用户管理界面显示员工、直属经理、公司负责人、财务、OA 系统管理员;`finance_mgr/hr/administration` 保留为高级兼容职责;普通界面不可授予 `admin`。
- `system_admin` 可管理其他普通账号、业务角色、系统配置、集成和审计;不得修改自己的角色,不得授予或撤销 `admin/system_admin`,所有变更写脱敏审计。
- `system_admin` 不获得工资、银行、证件、员工合同、付款执行或业务审批权限。
- 付款复核要求显式具有 `manager` 或 `ceo`,不能仅凭 `admin` 或 `system_admin` 进入正常审批路径。
- 新增细分权限:`system.accounts.manage`、`system.roles.manage`、`payroll.manage`、`employee.bank.read`、`employee.bank.manage`、`employee.identity.manage`、`employee.contract.manage`、`payment.batch.review`。
- `/employees` 对业务选择调用者只返回窄 DTO;完整员工档案仅本人或人员资料管理员可读,权限拒绝发生在敏感查询或文件读取前。
- 财务只读银行字段,不读取证件或修改敏感资料;未授权字段从响应中省略。
- 员工合同列表、元数据、附件下载和写操作使用独立权限;DTO 不返回内部路径,成功访问和变更写脱敏审计。
- 前端按权限隐藏动作;后端仍为最终授权边界。
### 付款一致性与最小审计
- 固定“财务制单/执行 + 经理或公司负责人复核”;创建者不得复核自己的批次。
- 所有金额只需一次独立复核;总金额达到 50000 元时增加警示和强确认,不增加第三人审批。
- 批次状态为 `draft -> reviewed -> executed|failed|cancelled`;`failed` 只重试失败项或取消剩余项;`executed/cancelled` 为终态。
- 创建、复核、执行、取消、付款元数据更新和回单作废在事务内锁定批次;执行再按稳定顺序锁定源单并复查状态和金额。
- 并发竞争返回确定性 409,不重复更新付款状态、审计或通知。
- 正式范围只接受已审批、未付款且未进入其他有效批次的报销;`payment_batch_v1` 启用时直接报销付款端点不得形成第二付款路径。
- 新增付款候选查询,页面按业务编号、人员、金额和日期选择,不要求粘贴内部 UUID;创建接口继续权威复查。
- 取消必须填写 2–500 字原因;取消失败批次只终止未付款项,不表示退款或冲正。
- 回单采用有理由的留痕作废,不物理删除;已复核后的付款元数据变更写 before/after 审计。
### 核心页面与本地候选门禁
- 项目、资产、合同、付款、报销表格在 768×1024 和 1024×768 下操作可达;容器可控横滚,页面整体不横向溢出。
- 报销、采购、合同、资产长表单共享未保存保护,覆盖站内跳转、记录切换、浏览器返回和刷新。
- 高敏附件删除和付款回单作废显示对象、后果和理由确认;普通可恢复动作不升级为强确认。
- 新增 `/mobile/attendance` 并消除移动考勤自循环;修复 375×812 下移动归档长字段裁切和底栏遮挡。
- 完成付款、合同、票据的权限显隐;修正资产旧 E2E,补齐项目/资产标题动作视觉覆盖;通过后回填并归档 `05-31-unified-page-header-actions`。
- 所有注册路由分类为 `core`、`supported-noncore`、`deferred` 或 `frozen`。未分类、核心行为测试缺失、仅由 `manual/live` 测试覆盖时门禁非零退出。
- 本地核心矩阵覆盖:登录退出、报销、审批、票据、采购、项目/合同、付款/AP、人员/审计、考勤/归档、移动工作台。
- 建立仓库内可移植的 `local-candidate` 门禁,不依赖公网、生产配置、历史 Issue CSV 或个人绝对路径。
## Acceptance Criteria
- [x] Prisma enum 包含 `system_admin`,加法迁移可验证且有回滚说明;既有角色与历史账号不自动迁移。
- [x] 角色矩阵证明业务管理、财务、系统管理员和超级管理员职责分离,系统管理员不能自我提权。
- [x] 员工目录、完整档案、银行、证件、工资和员工合同权限满足字段级与对象级边界;拒绝路径无敏感 DB/file 副作用。
- [x] 付款批次创建、复核、执行、失败重试、取消和回单作废满足状态机、maker-checker、原因与审计合同。
- [x] 合成本地 PostgreSQL 并发验证覆盖双执行、执行与取消、双创建、直接付款与批次付款竞争,结果唯一且不重复审计/通知。
- [x] 付款页面使用业务候选选择器,不要求普通用户输入 UUID;高额仅增加警示和确认。
- [x] 五类表格、四类未保存表单、不可逆动作、移动考勤和移动归档通过聚焦浏览器验证。
- [x] 付款、合同、票据权限显隐与后端拒绝一致;`05-31-unified-page-header-actions` 剩余测试和视觉证据闭合后才归档。
- [x] 路由清单无未分类项,门禁反例对 unmapped、manual-only、核心缺失行为/视觉均能失败。
- [x] 十个核心流程束在本地合成环境实际运行,记录最终 URL、H1、角色、主操作和页面错误断言。
- [x] 完整本地质量门禁通过;权限、状态机、workflow 和迁移变更完成独立只读复审。
- [x] 收口结论只写 `LOCAL_CANDIDATE_PASS`,不写已部署、可公网测试或企业微信真机通过。
## Definition of Done
- 代码、迁移、测试、现有规范/手册和 finding 生命周期同步更新,未新建重复审查报告。
- `bash scripts/check-minimal.sh`、Prisma 校验、服务端聚焦及全量测试、前端 typecheck/build、聚焦 Playwright、task validate、Trellis governance、敏感扫描、文档 registry 和 `git diff --check` 通过。
- 三个实施阶段分别复核,最后以中文 commit 引用本任务;不部署、不 push。
- `05-31-unified-page-header-actions` 仅在其剩余验收确实闭合后归档;当前任务完成后按 Trellis finish-work 归档并记录 journal。
## Test Plan
- 静态与单元:Prisma validate、触及服务端文件 `node --check`、权限/DTO/审计/付款路由 Vitest、前端 typecheck/build。
- 集成:隔离合成 PostgreSQL 应用已提交 migration,运行付款四类并发竞争,结束后清理数据库;不连接共享开发库或生产库。
- 浏览器:本地 Vite dev 与合成 fixture 实际运行十个核心流程;PC 768×1024/1024×768 和 WeCom UA 375×812 记录 URL、H1、角色、错误及溢出指标。
- 门禁可信度:为 unclassified、manual-only、core behavior missing、visualRequired missing 提供反例测试并断言非零退出;Playwright `--list` 只证明资产可解析。
- 全量收口:`bash scripts/check-minimal.sh`、task validate、Trellis governance、敏感扫描、文档 registry、`git diff --check`;权限/状态机/workflow/迁移另做只读 reviewer 复核。
## Decision (ADR-lite)
**Context**:公司约 5 人,需要低配置成本,但系统维护者不一定是领导,付款与高敏资料仍需要最小职责分离。
**Decision**:保留现有多角色引擎和业务职责,新增受限 `system_admin`,保留隐藏的应急 `admin`;付款使用数据库行锁和 maker-checker,不建设通用权限平台、事件平台或多级审批系统;发布只增加本地候选模式。
**Consequences**:日常界面简单且允许一人兼任多个职责;数据库仅做加法迁移;至少两个不同账号才能闭环付款;真实账号分配和内部环境验证必须在后续授权任务完成。
## Out of Scope
- 部署、公网检查、生产配置、真实账号分配、真实数据库写入、迁移 deploy、数据库重置、备份恢复演练。
- 企业微信真机、真实 OCR、真实付款、银行直连/流水、退款冲正、ERP/总账、差旅付款恢复。
- 通用 RBAC 平台、权限表达式设计器、全局幂等平台、事件总线、分布式锁、可配置多级金额审批。
- 全量可访问性、搜索直达、复杂离线数据生命周期、所有通知精准定位、非核心路由视觉重做。
## Technical Notes
- 规划基线:`58c8dec`;实现开始前若 HEAD 变化,更新 task notes 并重跑全部门禁。
- 发现来源:归档任务 `07-16-system-multidimensional-audit` 中 `DATA-EMP-001`、`DATA-HR-ATT-001`、`PAY-STATE-001`、`PAY-AUDIT-001`、`PAY-UX-001`、`UX-SAFE-001`、`UX-FORM-001`、`MOB-ATTEND-001`、`RESP-TABLE-001`、`REL-GATE-001`、`UI-PERM-001`、`MOB-ARCHIVE-001`。
- 页面可靠性沿用现有设计语言,不做新视觉风格裁决;当前会话没有可用的 `frontend-design` skill。
@@ -0,0 +1,26 @@
{
"id": "small-team-internal-readiness",
"name": "small-team-internal-readiness",
"title": "五人团队正式内用最小收口",
"description": "面向约 5 人公司,分离业务管理与 OA 系统运维,收敛敏感资料、付款一致性、核心页面和本地候选门禁。",
"status": "completed",
"dev_type": null,
"scope": "fullstack",
"package": null,
"priority": "P1",
"creator": "shunli",
"assignee": "shunli",
"createdAt": "2026-07-18",
"completedAt": "2026-07-18",
"branch": null,
"base_branch": "main",
"worktree_path": null,
"commit": null,
"pr_url": null,
"subtasks": [],
"children": [],
"parent": null,
"relatedFiles": [],
"notes": "承接用户批准的 07-17 方案;实际创建日期为 2026-07-18,规划基线 58c8dec。2026-07-18 当前工作提交通过 full 本地候选门禁(44/44 浏览器、10/10 witness、0 skipped/failed/unexpected)、服务端 985/985、隔离 PostgreSQL 61 migrations 与五组竞态、权限/付款/workflow/migration 只读复审;复审发现的员工统计敏感汇总权限漏口已修复并以 system_admin 零敏感查询回归验证,结论为 LOCAL_CANDIDATE_PASS。本轮未部署、未 push、未访问公网/生产/真实数据、未做企微真机或真实付款;后续内部部署另行授权。",
"meta": {}
}