修复(08-28-reimbursement-review-routing-copy): 规范财务兜底文案

这个提交包含在:
2026-08-28 20:30:04 +08:00
父节点 1bb066ddb7
当前提交 be057e665d
共修改 12 个文件,包含 291 行新增和 8 行删除
@@ -443,6 +443,59 @@ describe("GET /api/reimbursements/:id detail enhancements", () => {
await app.close();
});
it("projects legacy owner-self fallback task names as finance review", async () => {
const { app } = await buildApp({
latestWorkflowInstance: {
id: PENDING_INSTANCE_ID,
current_step_id: "approval_1_finance_owner_self_fallback",
current_status: "pending",
created_at: new Date("2026-08-28T11:08:00.000Z"),
started_at: new Date("2026-08-28T11:08:00.000Z"),
context_data: {
workflow_steps_snapshot: [{
id: "approval_1_finance_owner_self_fallback",
name: "负责人本人申请兜底:finance",
type: "approval",
assignee_rule: { type: "role", value: "finance" },
}],
},
workflow_definition: { definition_json: { steps: [] } },
workflow_tasks: [{
id: "owner-fallback-task",
step_id: "approval_1_finance_owner_self_fallback",
step_name: "负责人本人申请兜底:finance",
assignee_role: "finance",
status: "pending",
outcome: null,
comment: null,
created_at: new Date("2026-08-28T11:08:00.000Z"),
completed_at: null,
assignee_employee: { name: "财务人员" },
completer_employee: null,
}],
},
});
const response = await app.inject({
method: "GET",
url: `/api/reimbursements/${REIMBURSEMENT_ID}`,
headers: { authorization: "Bearer test" },
});
expect(response.statusCode).toBe(200);
expect(response.json().data.processingProgress.stages[1]).toEqual(
expect.objectContaining({
key: "approval_owner-fallback-task",
label: "财务复核",
state: "current",
actorName: "财务人员",
detail: "待财务复核处理",
}),
);
await app.close();
});
it("appends future snapshot approvals that do not have workflow tasks yet", async () => {
const { app } = await buildApp({
latestWorkflowInstance: {
@@ -122,7 +122,7 @@ describe("workflow travel helpers", () => {
{
id: "task-2",
status: "pending",
step_name: "财务审批",
step_name: "负责人本人申请兜底:finance",
assignee_role: "finance",
created_at: new Date("2026-05-12T07:00:00.000Z"),
due_date: new Date("2026-05-12T07:30:00.000Z"),
@@ -148,5 +148,10 @@ describe("workflow travel helpers", () => {
{ key: "purchase_request", pendingTotal: 1, overdueTotal: 1 },
]),
);
expect(summary.byStep).toEqual(
expect.arrayContaining([
{ key: "财务复核", pendingTotal: 1, overdueTotal: 1 },
]),
);
});
});
+18
查看文件
@@ -114,6 +114,22 @@ describe("workflow assignee resolution", () => {
);
});
describe("resolveWorkflowStepDisplayName", () => {
it("hides the internal role code in legacy owner fallback tasks", () => {
expect(workflowUtils.resolveWorkflowStepDisplayName({
step_name: "负责人本人申请兜底:finance",
assignee_role: "finance",
})).toBe("财务复核");
});
it("keeps normal readable workflow names unchanged", () => {
expect(workflowUtils.resolveWorkflowStepDisplayName({
step_name: "高额财务终审",
assignee_role: "finance",
})).toBe("高额财务终审");
});
});
describe("buildApprovalWorkflowSnapshot", () => {
it("keeps ordinary employee approval snapshots unchanged", async () => {
const tx = buildTx({ ownerRoles: ["employee"], managerId: MANAGER_ID });
@@ -153,6 +169,7 @@ describe("workflow assignee resolution", () => {
{ type: "role", value: "finance" },
]);
expect(steps[0].id).toContain("owner_self_fallback");
expect(steps[0].name).toBe("财务复核");
const resolved = await resolveActionableStep({
tx,
@@ -184,6 +201,7 @@ describe("workflow assignee resolution", () => {
{ type: "role", value: "finance" },
]);
expect(steps[0].id).toContain("owner_self_fallback");
expect(steps[0].name).toBe("财务复核");
});
it("removes CEO self node and duplicate fallback role for large CEO owner applications", async () => {