P2FINV1 收口付款批次启用前硬化
这个提交包含在:
@@ -90,11 +90,16 @@ test("E2E 报销支付批次主链路:提交 -> 审批 -> 创建批次 -> 复
|
|||||||
await page.goto(`/reimbursements/${reimbursementId}`);
|
await page.goto(`/reimbursements/${reimbursementId}`);
|
||||||
await reimbursementDetail.assertLoaded();
|
await reimbursementDetail.assertLoaded();
|
||||||
await reimbursementDetail.submitReimbursement();
|
await reimbursementDetail.submitReimbursement();
|
||||||
await expect(page.getByText(/状态:(reviewing|审批中)/)).toBeVisible();
|
const reimbursementAfterSubmit = await apiGetData<{
|
||||||
const reimbursementAfterSubmit = await apiGetData<{ formNumber: string | null; totalAmount: string | null }>(
|
formNumber: string | null;
|
||||||
|
status: string;
|
||||||
|
totalAmount: string | null;
|
||||||
|
}>(
|
||||||
employeeApi.api,
|
employeeApi.api,
|
||||||
`/api/reimbursements/${reimbursementId}`,
|
`/api/reimbursements/${reimbursementId}`,
|
||||||
);
|
);
|
||||||
|
expect(reimbursementAfterSubmit.status).toBe("reviewing");
|
||||||
|
await expect(page.getByText("审批中", { exact: true }).first()).toBeVisible();
|
||||||
const reimbursementDisplayCode = reimbursementAfterSubmit.formNumber ?? reimbursementId;
|
const reimbursementDisplayCode = reimbursementAfterSubmit.formNumber ?? reimbursementId;
|
||||||
const secondApprovalUser = Number(reimbursementAfterSubmit.totalAmount ?? 0) > 500 ? FINANCE_MGR : FINANCE;
|
const secondApprovalUser = Number(reimbursementAfterSubmit.totalAmount ?? 0) > 500 ? FINANCE_MGR : FINANCE;
|
||||||
|
|
||||||
@@ -108,7 +113,8 @@ test("E2E 报销支付批次主链路:提交 -> 审批 -> 创建批次 -> 复
|
|||||||
await managerTaskRow.getByTestId(TEST_IDS.workflow.detailLink).click();
|
await managerTaskRow.getByTestId(TEST_IDS.workflow.detailLink).click();
|
||||||
await workflowDetail.assertLoaded();
|
await workflowDetail.assertLoaded();
|
||||||
await workflowDetail.approve();
|
await workflowDetail.approve();
|
||||||
await expect(workflowDetail.summary).toContainText(/状态:(已处理|completed|已完成)/);
|
await expect(page.getByText("已完成", { exact: true }).first()).toBeVisible();
|
||||||
|
await expect(page.getByText(`通过 · ${MANAGER.name}`, { exact: true })).toBeVisible();
|
||||||
|
|
||||||
await logout(page, MANAGER.name);
|
await logout(page, MANAGER.name);
|
||||||
|
|
||||||
@@ -120,7 +126,8 @@ test("E2E 报销支付批次主链路:提交 -> 审批 -> 创建批次 -> 复
|
|||||||
await financeTaskRow.getByTestId(TEST_IDS.workflow.detailLink).click();
|
await financeTaskRow.getByTestId(TEST_IDS.workflow.detailLink).click();
|
||||||
await workflowDetail.assertLoaded();
|
await workflowDetail.assertLoaded();
|
||||||
await workflowDetail.approve();
|
await workflowDetail.approve();
|
||||||
await expect(workflowDetail.summary).toContainText(/状态:(已处理|completed|已完成)/);
|
await expect(page.getByText("已完成", { exact: true }).first()).toBeVisible();
|
||||||
|
await expect(page.getByText(`通过 · ${secondApprovalUser.name}`, { exact: true })).toBeVisible();
|
||||||
|
|
||||||
await logout(page, secondApprovalUser.name);
|
await logout(page, secondApprovalUser.name);
|
||||||
await login(page, FINANCE);
|
await login(page, FINANCE);
|
||||||
@@ -174,12 +181,26 @@ test("E2E 报销支付批次主链路:提交 -> 审批 -> 创建批次 -> 复
|
|||||||
const executedBatchDetailCard = page.locator(".card-std").filter({ hasText: batchName }).filter({ hasText: "复核进度:" }).last();
|
const executedBatchDetailCard = page.locator(".card-std").filter({ hasText: batchName }).filter({ hasText: "复核进度:" }).last();
|
||||||
await expect(executedBatchDetailCard).toBeVisible();
|
await expect(executedBatchDetailCard).toBeVisible();
|
||||||
await expect(executedBatchDetailCard).toContainText("复核进度:1/1");
|
await expect(executedBatchDetailCard).toContainText("复核进度:1/1");
|
||||||
|
const executeBatchResponsePromise = page.waitForResponse((response) => {
|
||||||
|
const url = new URL(response.url());
|
||||||
|
return response.request().method() === "POST" &&
|
||||||
|
url.pathname === `/api/payment-batches/${batchId}/execute` &&
|
||||||
|
response.ok();
|
||||||
|
});
|
||||||
await executedBatchDetailCard.getByRole("button", { name: "执行" }).click();
|
await executedBatchDetailCard.getByRole("button", { name: "执行" }).click();
|
||||||
|
await expect(page.getByTestId("action-confirm-dialog")).toContainText("确认后将执行付款批次");
|
||||||
|
await page.getByTestId("action-confirm-submit").click();
|
||||||
|
await executeBatchResponsePromise;
|
||||||
await expect(executedBatchDetailCard).toContainText("状态:已执行", { timeout: 30_000 });
|
await expect(executedBatchDetailCard).toContainText("状态:已执行", { timeout: 30_000 });
|
||||||
|
|
||||||
await page.goto(`/reimbursements/${reimbursementId}`);
|
await page.goto(`/reimbursements/${reimbursementId}`);
|
||||||
await reimbursementDetail.assertLoaded();
|
await reimbursementDetail.assertLoaded();
|
||||||
await expect(page.getByText(/状态:(paid|已支付)/)).toBeVisible({ timeout: 30_000 });
|
const reimbursementAfterPayment = await apiGetData<{ status: string }>(
|
||||||
|
employeeApi.api,
|
||||||
|
`/api/reimbursements/${reimbursementId}`,
|
||||||
|
);
|
||||||
|
expect(reimbursementAfterPayment.status).toBe("paid");
|
||||||
|
await expect(page.getByText("已支付", { exact: true }).first()).toBeVisible({ timeout: 30_000 });
|
||||||
await expect(page.getByTestId("reimbursement-payment-status")).toContainText("已付款");
|
await expect(page.getByTestId("reimbursement-payment-status")).toContainText("已付款");
|
||||||
|
|
||||||
const paymentAudit = await apiGetData<{
|
const paymentAudit = await apiGetData<{
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ DCL7 已删除本文件中 R70-R91 的长流水历史,避免旧环境、旧开
|
|||||||
- 2026-05-16 QAOPS9 已完成隔离核心业务流稳定化、恢复演练 dry-run checklist、公网 live smoke、真实 OCR 和公网移动矩阵复核;`pending OCR` 因本地未注入 `DATABASE_URL` 继续按规则记非阻断 `SKIP`。P2D 已完成分流:`P2-ORG` 只读巡检可进入独立合同,其余 P2 候选先保持前置条件等待。
|
- 2026-05-16 QAOPS9 已完成隔离核心业务流稳定化、恢复演练 dry-run checklist、公网 live smoke、真实 OCR 和公网移动矩阵复核;`pending OCR` 因本地未注入 `DATABASE_URL` 继续按规则记非阻断 `SKIP`。P2D 已完成分流:`P2-ORG` 只读巡检可进入独立合同,其余 P2 候选先保持前置条件等待。
|
||||||
- 2026-05-16 P2D 旧口径已修正:live smoke 凭据、员工 OCR 凭据和授权 PDF 样票已具备,不再作为 P2-FIN/P2-OCR 的 HOLD 原因。P2-ORG 已完成只读巡检:当前连接数据源 high=0、medium=0、low=9,建议 `NO_WRITE_FIX_NEEDED`;低风险项为 CEO/root 无直属主管观察 1 和 active 员工无企业微信绑定 8。
|
- 2026-05-16 P2D 旧口径已修正:live smoke 凭据、员工 OCR 凭据和授权 PDF 样票已具备,不再作为 P2-FIN/P2-OCR 的 HOLD 原因。P2-ORG 已完成只读巡检:当前连接数据源 high=0、medium=0、low=9,建议 `NO_WRITE_FIX_NEEDED`;低风险项为 CEO/root 无直属主管观察 1 和 active 员工无企业微信绑定 8。
|
||||||
- 2026-05-16 P2-FIN-DECISION 已完成付款批次启用决策准备:只读核对代码/flag/空态、角色账号、导出字段、审计事件、公网 readiness 和 flag off 回滚口径,结论为 `GO_TO_IMPLEMENT`,后续可另建 `P2-FIN-V1`;当前仍不启用 `payment_batch_v1`、不写付款批次业务数据、不部署。
|
- 2026-05-16 P2-FIN-DECISION 已完成付款批次启用决策准备:只读核对代码/flag/空态、角色账号、导出字段、审计事件、公网 readiness 和 flag off 回滚口径,结论为 `GO_TO_IMPLEMENT`,后续可另建 `P2-FIN-V1`;当前仍不启用 `payment_batch_v1`、不写付款批次业务数据、不部署。
|
||||||
|
- 2026-05-16 P2-FIN-V1 已完成付款批次启用前本地/隔离硬化:后端 focused 回归、前端 typecheck/build、隔离付款批次闭环、权限直连审计、公网 readiness 和只读 review 均通过;本轮只修补 E2E 对当前状态胶囊和二次确认 UI 的断言,不改业务 API/schema/UI,不部署,公网 `payment_batch_v1` 继续关闭。
|
||||||
|
|
||||||
## 关键证据索引
|
## 关键证据索引
|
||||||
|
|
||||||
@@ -45,6 +46,7 @@ DCL7 已删除本文件中 R70-R91 的长流水历史,避免旧环境、旧开
|
|||||||
| P2D | 已完成决策分流:`P2-ORG` 只读巡检可进入独立合同;付款批次、图片 OCR、UX8、审批通知和轻业务增强均需前置条件;冻结项继续冻结 | `issues/2026-05-16_00-19-21-p2-decision-followup.csv` |
|
| P2D | 已完成决策分流:`P2-ORG` 只读巡检可进入独立合同;付款批次、图片 OCR、UX8、审批通知和轻业务增强均需前置条件;冻结项继续冻结 | `issues/2026-05-16_00-19-21-p2-decision-followup.csv` |
|
||||||
| P2-ORG | 已收口:组织账号主数据只读巡检完成,高/中风险为 0,低风险观察 9,不需要写修复合同 | `issues/2026-05-16_02-04-27-p2-org-readonly-master-data-audit.csv`、`artifacts/qa-flow/p2-org-readonly-audit-20260516-020427/report.json` |
|
| P2-ORG | 已收口:组织账号主数据只读巡检完成,高/中风险为 0,低风险观察 9,不需要写修复合同 | `issues/2026-05-16_02-04-27-p2-org-readonly-master-data-audit.csv`、`artifacts/qa-flow/p2-org-readonly-audit-20260516-020427/report.json` |
|
||||||
| P2-FIN-DECISION | 已收口:付款批次决策准备完成,结论 `GO_TO_IMPLEMENT`;后续进入单独 `P2-FIN-V1` 合同前仍需方案批准 | `issues/2026-05-16_09-02-42-p2-fin-payment-batch-decision.csv` |
|
| P2-FIN-DECISION | 已收口:付款批次决策准备完成,结论 `GO_TO_IMPLEMENT`;后续进入单独 `P2-FIN-V1` 合同前仍需方案批准 | `issues/2026-05-16_09-02-42-p2-fin-payment-batch-decision.csv` |
|
||||||
|
| P2-FIN-V1 | 已收口:付款批次启用前本地/隔离硬化完成;隔离付款批次闭环 1 passed、权限直连审计 8 passed、公网 readiness ready | `issues/2026-05-16_09-42-43-p2-fin-payment-batch-v1.csv`、`artifacts/qa-flow/business-flow-20260516-095719/summary.txt`、`artifacts/qa-flow/business-flow-20260516-095900/summary.txt` |
|
||||||
|
|
||||||
## 当前门禁
|
## 当前门禁
|
||||||
|
|
||||||
@@ -61,6 +63,7 @@ DCL7 已删除本文件中 R70-R91 的长流水历史,避免旧环境、旧开
|
|||||||
| QAOPS9 公网移动矩阵 | 通过 | `E2E_BASE_URL=https://oa.hyinda.com npx playwright test tests/e2e/dg7-mobile-information-dedupe.spec.ts tests/e2e/r124-mobile-entry-matrix.spec.ts --workers=1 --reporter=list`,6 passed |
|
| QAOPS9 公网移动矩阵 | 通过 | `E2E_BASE_URL=https://oa.hyinda.com npx playwright test tests/e2e/dg7-mobile-information-dedupe.spec.ts tests/e2e/r124-mobile-entry-matrix.spec.ts --workers=1 --reporter=list`,6 passed |
|
||||||
| P2-ORG 只读巡检 | 通过,含低风险观察项 | `server/src/scripts/audit-org-master-data.js` 在 READ ONLY 事务中执行;当前连接数据源 high=0、medium=0、low=9,未输出手机号、邮箱、token 或企业微信真实标识,报告 `artifacts/qa-flow/p2-org-readonly-audit-20260516-020427/` |
|
| P2-ORG 只读巡检 | 通过,含低风险观察项 | `server/src/scripts/audit-org-master-data.js` 在 READ ONLY 事务中执行;当前连接数据源 high=0、medium=0、low=9,未输出手机号、邮箱、token 或企业微信真实标识,报告 `artifacts/qa-flow/p2-org-readonly-audit-20260516-020427/` |
|
||||||
| P2-FIN 决策准备 | 通过 | `LIVE_SMOKE_BASE_URL=https://oa.hyinda.com node scripts/qa/check-live-smoke-env.mjs` 显示 publicReady/liveSmokeReady/liveOcrReady 均为 true;只读核对付款批次 flag、权限、导出、审计和回滚口径;未执行付款批次业务写入 |
|
| P2-FIN 决策准备 | 通过 | `LIVE_SMOKE_BASE_URL=https://oa.hyinda.com node scripts/qa/check-live-smoke-env.mjs` 显示 publicReady/liveSmokeReady/liveOcrReady 均为 true;只读核对付款批次 flag、权限、导出、审计和回滚口径;未执行付款批次业务写入 |
|
||||||
|
| P2-FIN-V1 启用前硬化 | 通过,未部署 | 后端 focused 回归 8 tests passed;`client` typecheck/build 通过;隔离临时库 `reimbursement-payment-batch-flow` 1 passed,覆盖创建批次、复核、二次确认执行、报销 paid、票据 archived、AP 台账和 ERP outbox;权限直连审计 8 passed;公网只做 readiness,不启用 `payment_batch_v1` |
|
||||||
|
|
||||||
## R7EP / OPS8 / QAF8 / UX8 / P2T 预检推进
|
## R7EP / OPS8 / QAF8 / UX8 / P2T 预检推进
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -40,6 +40,7 @@
|
|||||||
| `P2D` | `issues/2026-05-16_00-19-21-p2-decision-followup.csv` | `EVIDENCE` | P2 功能决策分流已完成:`P2-ORG` 只读巡检可进独立合同,其余 P2 候选保持 `HOLD_FOR_PREREQ`,冻结项继续冻结 |
|
| `P2D` | `issues/2026-05-16_00-19-21-p2-decision-followup.csv` | `EVIDENCE` | P2 功能决策分流已完成:`P2-ORG` 只读巡检可进独立合同,其余 P2 候选保持 `HOLD_FOR_PREREQ`,冻结项继续冻结 |
|
||||||
| `P2-ORG` | `issues/2026-05-16_02-04-27-p2-org-readonly-master-data-audit.csv` | `EVIDENCE` | 组织账号主数据只读巡检已完成;当前连接数据源高/中风险为 0,仅有低风险观察项,不需要写修复合同 |
|
| `P2-ORG` | `issues/2026-05-16_02-04-27-p2-org-readonly-master-data-audit.csv` | `EVIDENCE` | 组织账号主数据只读巡检已完成;当前连接数据源高/中风险为 0,仅有低风险观察项,不需要写修复合同 |
|
||||||
| `P2-FIN-DECISION` | `issues/2026-05-16_09-02-42-p2-fin-payment-batch-decision.csv` | `EVIDENCE` | 付款批次启用决策准备已完成,结论 `GO_TO_IMPLEMENT`;后续必须另建 `P2-FIN-V1` 实现合同,当前不启用 `payment_batch_v1` |
|
| `P2-FIN-DECISION` | `issues/2026-05-16_09-02-42-p2-fin-payment-batch-decision.csv` | `EVIDENCE` | 付款批次启用决策准备已完成,结论 `GO_TO_IMPLEMENT`;后续必须另建 `P2-FIN-V1` 实现合同,当前不启用 `payment_batch_v1` |
|
||||||
|
| `P2-FIN-V1` | `issues/2026-05-16_09-42-43-p2-fin-payment-batch-v1.csv` | `EVIDENCE` | 付款批次启用前本地/隔离硬化已完成;后端 focused 回归、前端构建、隔离闭环、权限审计和公网 readiness 通过,公网仍不启用 `payment_batch_v1` |
|
||||||
|
|
||||||
旧 Issue CSV 保留为历史审计证据:不删除、不批量回写、不移动到 `docs/archive/` 或其他归档目录。新连续合同如替代旧合同,只在新合同 `Notes` 或文档索引中说明 supersedes。
|
旧 Issue CSV 保留为历史审计证据:不删除、不批量回写、不移动到 `docs/archive/` 或其他归档目录。新连续合同如替代旧合同,只在新合同 `Notes` 或文档索引中说明 supersedes。
|
||||||
|
|
||||||
@@ -47,8 +48,8 @@
|
|||||||
|
|
||||||
| Doc_ID | Path | Category | Authority | Status | Owner | Related_Issues | Evidence | Supersedes | Last_Audited | Audit_Method | Risk | Notes |
|
| Doc_ID | Path | Category | Authority | Status | Owner | Related_Issues | Evidence | Supersedes | Last_Audited | Audit_Method | Risk | Notes |
|
||||||
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
| `IDX` | `docs/文档索引.md` | 入口索引 | 最高文档入口 | `CURRENT` | product/dev | `GOV8,QAOPS9,P2D,P2-ORG,P2-FIN-DECISION` | `rg` | none | 2026-05-16 | `node scripts/qa/audit-docs.mjs --check-registry` | medium | 判断当前该读什么 |
|
| `IDX` | `docs/文档索引.md` | 入口索引 | 最高文档入口 | `CURRENT` | product/dev | `GOV8,QAOPS9,P2D,P2-ORG,P2-FIN-DECISION,P2-FIN-V1` | `rg` | none | 2026-05-16 | `node scripts/qa/audit-docs.mjs --check-registry` | medium | 判断当前该读什么 |
|
||||||
| `REG` | `docs/文档事实源状态矩阵.md` | 文档台账 | 文档分类和状态事实源 | `CURRENT` | product/dev | `GOV8,QAOPS9,P2D,P2-ORG,P2-FIN-DECISION` | `audit-docs` | none | 2026-05-16 | `audit-docs --check-registry` | medium | 判断文档权威性 |
|
| `REG` | `docs/文档事实源状态矩阵.md` | 文档台账 | 文档分类和状态事实源 | `CURRENT` | product/dev | `GOV8,QAOPS9,P2D,P2-ORG,P2-FIN-DECISION,P2-FIN-V1` | `audit-docs` | none | 2026-05-16 | `audit-docs --check-registry` | medium | 判断文档权威性 |
|
||||||
| `PRD-MVP` | `docs/海音达OA-MVP需求规格说明书.md` | 需求事实源 | PRD 主事实源 | `CURRENT` | product | `REQ8,P2T,GOV8` | Issue CSV | `docs/requirements-specification.md` | 2026-05-13 | `rg` | high | 定义做什么、不做什么和验收口径 |
|
| `PRD-MVP` | `docs/海音达OA-MVP需求规格说明书.md` | 需求事实源 | PRD 主事实源 | `CURRENT` | product | `REQ8,P2T,GOV8` | Issue CSV | `docs/requirements-specification.md` | 2026-05-13 | `rg` | high | 定义做什么、不做什么和验收口径 |
|
||||||
| `PRODUCT-SCOPE` | `docs/产品口径.md` | 需求事实源 | 产品边界事实源 | `CURRENT` | product | `REQ8,P2T` | `rg` | none | 2026-05-13 | `rg` | high | 记录已拍板产品边界 |
|
| `PRODUCT-SCOPE` | `docs/产品口径.md` | 需求事实源 | 产品边界事实源 | `CURRENT` | product | `REQ8,P2T` | `rg` | none | 2026-05-13 | `rg` | high | 记录已拍板产品边界 |
|
||||||
| `DESIGN-UI` | `docs/产品设计规则.md` | 设计事实源 | PC/移动/企业微信设计事实源 | `CURRENT` | design/frontend | `MIA7,MIF7,GOV8,DG8,DG9` | Playwright/视觉审查/DG8/DG9 | none | 2026-05-13 | `rg` | high | 页面改动必须读取;DG8 后飞书为主 UI/布局参考;DG9 后按页面分层和样板选型 |
|
| `DESIGN-UI` | `docs/产品设计规则.md` | 设计事实源 | PC/移动/企业微信设计事实源 | `CURRENT` | design/frontend | `MIA7,MIF7,GOV8,DG8,DG9` | Playwright/视觉审查/DG8/DG9 | none | 2026-05-13 | `rg` | high | 页面改动必须读取;DG8 后飞书为主 UI/布局参考;DG9 后按页面分层和样板选型 |
|
||||||
|
|||||||
+3
-1
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
## 最近事实源链
|
## 最近事实源链
|
||||||
|
|
||||||
R6 -> PC6 -> PA6 -> FL6 -> AP6 -> RI6 -> LP6 -> ME6/QG6 -> DG7/MRF7 -> MIA7 -> MIF7/MIF7T(公网部署与带凭据公网复检已收口) -> DG8 -> DG9 -> R7E -> FBA -> QAOPS9/P2D -> P2-ORG -> P2-FIN-DECISION。
|
R6 -> PC6 -> PA6 -> FL6 -> AP6 -> RI6 -> LP6 -> ME6/QG6 -> DG7/MRF7 -> MIA7 -> MIF7/MIF7T(公网部署与带凭据公网复检已收口) -> DG8 -> DG9 -> R7E -> FBA -> QAOPS9/P2D -> P2-ORG -> P2-FIN-DECISION -> P2-FIN-V1。
|
||||||
|
|
||||||
- R6、PC6、PA6、FL6、AP6、RI6、LP6 已完成并部署。
|
- R6、PC6、PA6、FL6、AP6、RI6、LP6 已完成并部署。
|
||||||
- ME6 自动化、公网视觉矩阵和 `ME6-3` 代表性企业微信真机门禁已完成。
|
- ME6 自动化、公网视觉矩阵和 `ME6-3` 代表性企业微信真机门禁已完成。
|
||||||
@@ -34,6 +34,7 @@ R6 -> PC6 -> PA6 -> FL6 -> AP6 -> RI6 -> LP6 -> ME6/QG6 -> DG7/MRF7 -> MIA7 -> M
|
|||||||
- P2D 是 P2 功能决策合同,只决定组织主数据、付款批次、图片 OCR、UX8、审批通知和轻业务增强是否进入独立开发合同;统一使用 `GO_TO_CONTRACT`、`HOLD_FOR_PREREQ`、`FREEZE` 三类结论,不新增 API/schema、feature flag 或前端功能。
|
- P2D 是 P2 功能决策合同,只决定组织主数据、付款批次、图片 OCR、UX8、审批通知和轻业务增强是否进入独立开发合同;统一使用 `GO_TO_CONTRACT`、`HOLD_FOR_PREREQ`、`FREEZE` 三类结论,不新增 API/schema、feature flag 或前端功能。
|
||||||
- P2-ORG 是 P2D 后第一个执行合同,已完成组织账号主数据只读巡检;当前连接数据源下高/中风险为 0,低风险观察项为 CEO/root 无直属主管 1 和 active 员工无企业微信绑定 8;本轮不需要写修复合同。
|
- P2-ORG 是 P2D 后第一个执行合同,已完成组织账号主数据只读巡检;当前连接数据源下高/中风险为 0,低风险观察项为 CEO/root 无直属主管 1 和 active 员工无企业微信绑定 8;本轮不需要写修复合同。
|
||||||
- P2-FIN-DECISION 已完成付款批次启用决策准备,结论为 `GO_TO_IMPLEMENT`:可进入单独 `P2-FIN-V1` 实现合同;当前仍不启用 `payment_batch_v1`、不写付款批次业务数据、不部署。
|
- P2-FIN-DECISION 已完成付款批次启用决策准备,结论为 `GO_TO_IMPLEMENT`:可进入单独 `P2-FIN-V1` 实现合同;当前仍不启用 `payment_batch_v1`、不写付款批次业务数据、不部署。
|
||||||
|
- P2-FIN-V1 已完成付款批次启用前本地/隔离硬化:后端 focused 回归、前端 typecheck/build、隔离付款批次闭环、权限直连审计和公网 readiness 均通过;本轮只硬化 E2E 断言,不新增 API/schema/feature flag/UI,不部署,公网 `payment_batch_v1` 继续关闭。
|
||||||
|
|
||||||
## 当前活跃治理流
|
## 当前活跃治理流
|
||||||
|
|
||||||
@@ -54,6 +55,7 @@ R6 -> PC6 -> PA6 -> FL6 -> AP6 -> RI6 -> LP6 -> ME6/QG6 -> DG7/MRF7 -> MIA7 -> M
|
|||||||
| `P2D` | `issues/2026-05-16_00-19-21-p2-decision-followup.csv` | 已收口:P2 决策分流完成 | `P2-ORG` 只读巡检进入独立合同;付款批次、图片 OCR、UX8、审批通知、轻业务增强均 `HOLD_FOR_PREREQ`;冻结 ERP/AI/完整差旅/复杂 BPM/审批设计器/重预算/企业微信原生审批 | 不新增 API/schema/feature flag/UI;不启用付款批次或图片 OCR |
|
| `P2D` | `issues/2026-05-16_00-19-21-p2-decision-followup.csv` | 已收口:P2 决策分流完成 | `P2-ORG` 只读巡检进入独立合同;付款批次、图片 OCR、UX8、审批通知、轻业务增强均 `HOLD_FOR_PREREQ`;冻结 ERP/AI/完整差旅/复杂 BPM/审批设计器/重预算/企业微信原生审批 | 不新增 API/schema/feature flag/UI;不启用付款批次或图片 OCR |
|
||||||
| `P2-ORG` | `issues/2026-05-16_02-04-27-p2-org-readonly-master-data-audit.csv` | 已收口:组织主数据只读巡检完成 | 主管链、停用审批人、角色持有人、admin-only、财务/admin 混授、企业微信绑定漂移的脱敏只读审计 | 不写生产账号数据、不执行 P2-ORG-FIX、不改 API/schema/UI、不部署 |
|
| `P2-ORG` | `issues/2026-05-16_02-04-27-p2-org-readonly-master-data-audit.csv` | 已收口:组织主数据只读巡检完成 | 主管链、停用审批人、角色持有人、admin-only、财务/admin 混授、企业微信绑定漂移的脱敏只读审计 | 不写生产账号数据、不执行 P2-ORG-FIX、不改 API/schema/UI、不部署 |
|
||||||
| `P2-FIN-DECISION` | `issues/2026-05-16_09-02-42-p2-fin-payment-batch-decision.csv` | 已收口:付款批次决策准备完成,结论 `GO_TO_IMPLEMENT` | 付款批次代码/flag/空态、角色账号矩阵、导出字段、审计事件、公网验收窗口和 flag off 回滚口径 | 不启用 `payment_batch_v1`、不写付款批次、不接真实支付、不写 ERP 实时凭证、不部署 |
|
| `P2-FIN-DECISION` | `issues/2026-05-16_09-02-42-p2-fin-payment-batch-decision.csv` | 已收口:付款批次决策准备完成,结论 `GO_TO_IMPLEMENT` | 付款批次代码/flag/空态、角色账号矩阵、导出字段、审计事件、公网验收窗口和 flag off 回滚口径 | 不启用 `payment_batch_v1`、不写付款批次、不接真实支付、不写 ERP 实时凭证、不部署 |
|
||||||
|
| `P2-FIN-V1` | `issues/2026-05-16_09-42-43-p2-fin-payment-batch-v1.csv` | 已收口:付款批次启用前本地/隔离硬化完成 | 后端付款批次/AP/导出 focused 回归、前端构建、隔离闭环、权限审计、公网 readiness、flag off 回滚口径 | 不公网启用 `payment_batch_v1`、不部署、不接真实支付、不写 ERP 实时凭证 |
|
||||||
|
|
||||||
旧 Issue CSV 不删除、不批量回写、不移动到归档目录。若新治理流替代旧合同,只在新 CSV 的 `Notes` 或本索引说明 supersedes,旧文件保留历史审计语义。
|
旧 Issue CSV 不删除、不批量回写、不移动到归档目录。若新治理流替代旧合同,只在新 CSV 的 `Notes` 或本索引说明 supersedes,旧文件保留历史审计语义。
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
ID,Title,Description,Acceptance,Test_Method,Tools,Dev_Status,Review1_Status,Regression_Status,Files,Dependencies,Notes
|
||||||
|
"P2FINV1-0","P2-FIN-V1 合同建档","建立付款批次最小闭环启用前硬化合同,范围限定本地或隔离环境验证;公网 payment_batch_v1 继续关闭,不部署,不接真实支付,不写 ERP 实时凭证。","1) CSV 校验通过;2) 本轮复用现有 /api/payment-batches、/api/ap-operations、/api/exports/ap-operations 和 payment_batch_v1;3) 不新增业务 API、schema、migration、路由或 feature flag;4) 公网不启用付款批次;5) 后续 P2-OCR/UX8/P2-WF/P2-BIZ 只排队不实现。","流程级验证:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-16_09-42-43-p2-fin-payment-batch-v1.csv;人工核对本 CSV 范围不包含公网启用、部署、生产恢复、数据库重置或远端 env 打印。","python3|manual","DONE","DONE","DONE","issues/2026-05-16_09-42-43-p2-fin-payment-batch-v1.csv","[]","ScopeLocked=DONE; CSV validated; no public enable/deploy/prod restore/db reset/secret/env print; later public enable requires P2-FIN-LIVE."
|
||||||
|
"P2FINV1-1","现有回归预检","先执行付款批次现有后端、前端和本地隔离 E2E 回归,判断是否需要代码修复;若全过,本轮作为启用前验收与硬化收口,不强行制造代码改动。","1) 后端语法、Prisma、单测和 regression-payment-batches 通过;2) 前端 typecheck/build 通过;3) 本地或隔离 E2E 支付批次闭环通过或有明确非代码阻断;4) 预检结论写入 Notes。","受影响流程:员工提交报销 -> 主管/财务审批 -> 财务创建付款批次 -> 财务主管复核 -> 财务执行 -> 报销 paid、发票 archived、AP 台账更新;验证命令:cd server && npm run prisma:validate && node --check src/routes/paymentBatches.js src/routes/apOperations.js src/routes/exports.js src/routes/reimbursements.js && npm test -- tests/unit/routes/paymentBatches.reimbursement.test.js tests/unit/routes/exports.apOperations.test.js tests/unit/services/financeLedger.test.js && ./scripts/regression-payment-batches.sh;cd client && npm run typecheck && npm run build;cd client && E2E_BASE_URL=<local-or-isolated-url> npx playwright test tests/e2e/reimbursement-payment-batch-flow.spec.ts --workers=1 --reporter=list。","npm|node|bash|playwright","DONE","DONE","DONE","server/src/routes/paymentBatches.js|server/src/routes/apOperations.js|server/src/routes/exports.js|server/src/routes/reimbursements.js|server/tests/unit|server/scripts/regression-payment-batches.sh|client/tests/e2e/reimbursement-payment-batch-flow.spec.ts","[""P2FINV1-0""]","Precheck=PASS; server prisma/node-check/unit 8 tests/regression-payment-batches pass; client typecheck/build pass; isolated E2E final pass at artifacts/qa-flow/business-flow-20260516-095719/summary.txt after E2E status/confirm assertions hardened."
|
||||||
|
"P2FINV1-2","后端硬化预留","仅当 P2FINV1-1 发现后端缺口时,最小修补现有付款批次、AP 台账、AP 导出或报销付款 follow-up;不新增接口契约、schema 或 migration。","1) 若无后端缺口则记录 N/A;2) 若修补,保持现有 API 兼容;3) 权限、maker-checker、状态转换和审计不回归;4) 不接真实支付或 ERP 实时凭证。","受影响流程:付款批次创建、复核、执行、失败项、AP 导出和报销付款归档;验证步骤:复跑 P2FINV1-1 后端命令,必要时增加最小单测。","node|npm|manual","DONE","DONE","DONE","server/src/routes/paymentBatches.js|server/src/routes/apOperations.js|server/src/routes/exports.js|server/src/routes/reimbursements.js|server/tests/unit","[""P2FINV1-1""]","BackendHardening=N/A; existing backend passed focused regression; no server/src, API, schema or migration changes."
|
||||||
|
"P2FINV1-3","前端硬化预留","仅当 P2FINV1-1 发现前端缺口时,最小修补 PaymentBatchesPage、ApOperationsPage 或移动财务空态;不新增移动付款能力或新路由。","1) 若无前端缺口则记录 N/A;2) 付款批次和 AP 页面操作与现有权限一致;3) flag off 时仍展示关闭态或 409 解释;4) 不新增移动执行付款。","受影响流程:财务 PC 付款批次页、AP 运营页、移动财务摘要关闭态;验证步骤:cd client && npm run typecheck && npm run build;必要时补 focused Playwright。","npm|playwright|manual","DONE","DONE","DONE","client/src/pages/PaymentBatchesPage.tsx|client/src/pages/ApOperationsPage.tsx|client/src/pages/MobilePortalPage.tsx|client/tests/e2e","[""P2FINV1-1""]","FrontendHardening=E2E_ONLY; no product UI or route change; updated reimbursement-payment-batch-flow spec for current status badges and payment action confirmation; typecheck/build pass."
|
||||||
|
"P2FINV1-4","本地隔离闭环验收","在本地或隔离环境临时打开 payment_batch_v1,跑付款批次最小闭环,确认创建、复核、执行、报销 paid、发票 archived、AP 台账和 ERP outbox 兼容证据。","1) E2E 闭环通过;2) 不使用公网环境写付款批次;3) 测试产生的数据仅存在本地或隔离环境;4) 若环境不可用,记录阻断原因,不伪造通过。","流程级验证:启动本地/隔离 server 和 client 后执行 cd client && E2E_BASE_URL=<local-or-isolated-url> npx playwright test tests/e2e/reimbursement-payment-batch-flow.spec.ts --workers=1 --reporter=list;人工核对测试中 ensureFeatureFlagOn 只作用于本地/隔离环境。","playwright|manual","DONE","DONE","DONE","client/tests/e2e/reimbursement-payment-batch-flow.spec.ts|server/src/scripts/seed-trialrun.js|server/src/routes/featureFlags.js","[""P2FINV1-1""]","LocalClosure=PASS; isolated temp DB run business-flow-20260516-095719, 1 passed; ensureFeatureFlagOn only local/isolated; public payment_batch_v1 remains off."
|
||||||
|
"P2FINV1-5","权限审计回滚验收","验证付款批次权限、审计事件和 flag off 回滚口径:财务成功,员工/审批人/admin-only 拒绝或受门禁 409,审计可追溯,flag off 回到关闭态。","1) payment.batch.manage 和 risk.review.manage 权限边界清楚;2) 员工、审批人、admin-only 不越权;3) PAYMENT_BATCH_* 与 EXPORT_AP_OPERATIONS 审计覆盖;4) flag off 后 payment-batches/AP/export 回到 409 或移动关闭空态。","流程级验证:cd client && E2E_BASE_URL=<local-or-isolated-url> npx playwright test tests/e2e/permission-direct-access.spec.ts --workers=1 --reporter=list;rg -n 'PAYMENT_BATCH_CREATED|PAYMENT_BATCH_REVIEWED|PAYMENT_BATCH_SECOND_REVIEWED|PAYMENT_BATCH_EXECUTED|EXPORT_AP_OPERATIONS|payment_batch_v1_disabled|flag_force_off' server/src client/tests docs issues;公网只运行 LIVE_SMOKE_BASE_URL=https://oa.hyinda.com node scripts/qa/check-live-smoke-env.mjs,不执行付款批次写入。","playwright|rg|node|manual","DONE","DONE","DONE","client/tests/e2e/permission-direct-access.spec.ts|server/src/routes/paymentBatches.js|server/src/routes/exports.js|server/src/services/featureFlags/index.js|scripts/qa/check-live-smoke-env.mjs","[""P2FINV1-4""]","RollbackEvidence=PASS; permission-direct-access in isolated temp DB business-flow-20260516-095900, 8 passed; rg confirmed PAYMENT_BATCH_* and EXPORT_AP_OPERATIONS audit plus flag_force_off/payment_batch_v1_disabled; live readiness true without public writes."
|
||||||
|
"P2FINV1-6","独立 reviewer 复核","对 P2-FIN-V1 做独立只读复核,重点检查权限模型、财务状态流、maker-checker、审计事件、flag off 回滚和未接真实支付边界。","1) reviewer 结论无阻断;2) 如有阻断,先修复并复跑相关测试;3) 复核明确本轮不新增 schema/API,不公网启用;4) 复核意见写入 Notes。","人工 reviewer:对照 diff、P2FINV1-1..5 证据、server/src/routes/paymentBatches.js、server/src/routes/exports.js、client/tests/e2e/reimbursement-payment-batch-flow.spec.ts 和 permission-direct-access.spec.ts;不修改代码。","manual","DONE","DONE","DONE","issues/2026-05-16_09-42-43-p2-fin-payment-batch-v1.csv|server/src/routes/paymentBatches.js|server/src/routes/exports.js|client/tests/e2e","[""P2FINV1-5""]","Reviewer=PASS; read-only review found no business code diff; routes still enforce payment_batch_v1 gate, payment.batch.manage/risk.review.manage split, maker-checker, audit events and no real payment/ERP credential path; no blocker."
|
||||||
|
"P2FINV1-7","收口回填与中文提交","回填 P2-FIN-V1 CSV、文档索引、事实源矩阵和人工试运行报告,运行最终校验并提交中文 commit。","1) CSV 状态真实回填;2) docs/文档索引.md、docs/文档事实源状态矩阵.md、docs/trialrun/人工试运行报告.md 必要状态已更新;3) validate、audit-docs、rg 和 git diff --check 通过;4) 中文 commit 引用 P2FINV1;5) 明确未部署。","流程级验证:python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/2026-05-16_09-42-43-p2-fin-payment-batch-v1.csv;node scripts/qa/audit-docs.mjs --check-registry;rg -n 'P2FINV1|P2-FIN-V1|payment_batch_v1|付款批次|flag_force_off|EXPORT_AP_OPERATIONS|PAYMENT_BATCH' docs issues;git diff --check;git status --short。","python3|node|rg|git|manual","DONE","DONE","DONE","issues/2026-05-16_09-42-43-p2-fin-payment-batch-v1.csv|docs/文档索引.md|docs/文档事实源状态矩阵.md|docs/trialrun/人工试运行报告.md","[""P2FINV1-6""]","Closeout=PASS; docs index/matrix/trial report updated; final validate/audit-docs/rg/git diff check run before commit; not deployed; next queued P2-OCR-SAMPLE."
|
||||||
|
在新工单中引用
屏蔽一个用户