feat: 完成P13治理收尾并创建P14执行合同(Issue: P13-1,P13-2,P13-3,P13-4,P13-5,P13-6,P13-7,P13-8,P14-0)
这个提交包含在:
@@ -0,0 +1,123 @@
|
||||
const {
|
||||
FEATURE_FLAG_KEYS,
|
||||
} = require("../../src/services/featureFlags");
|
||||
const {
|
||||
evaluateVerificationAccess,
|
||||
verifyInvoiceByProvider,
|
||||
} = require("../../src/services/verification");
|
||||
|
||||
function buildFlagRecord({
|
||||
overrideMode = "force_on",
|
||||
rolloutType = "global",
|
||||
departmentIds = [],
|
||||
}) {
|
||||
const now = new Date("2026-02-12T00:00:00.000Z");
|
||||
return {
|
||||
id: "verification-flag",
|
||||
flag_key: FEATURE_FLAG_KEYS.invoiceVerification,
|
||||
override_mode: overrideMode,
|
||||
rollout_type: rolloutType,
|
||||
department_ids: departmentIds,
|
||||
note: "unit-test",
|
||||
version: 1,
|
||||
created_at: now,
|
||||
created_by: null,
|
||||
updated_at: now,
|
||||
updated_by: null,
|
||||
};
|
||||
}
|
||||
|
||||
function buildPrisma(record) {
|
||||
return {
|
||||
featureFlag: {
|
||||
findUnique: async () => record,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
describe("evaluateVerificationAccess", () => {
|
||||
it("returns env_hard_off when env gate is closed", async () => {
|
||||
const result = await evaluateVerificationAccess({
|
||||
prisma: buildPrisma(buildFlagRecord({})),
|
||||
config: {
|
||||
erpSyncEnabled: true,
|
||||
invoiceVerificationEnabled: false,
|
||||
},
|
||||
departmentId: "dept-a",
|
||||
strictDepartment: true,
|
||||
});
|
||||
|
||||
expect(result.enabled).toBe(false);
|
||||
expect(result.reason).toBe("env_hard_off");
|
||||
});
|
||||
|
||||
it("returns allowlist decision for department rollout", async () => {
|
||||
const prisma = buildPrisma(
|
||||
buildFlagRecord({ rolloutType: "department_allowlist", departmentIds: ["dept-a"] }),
|
||||
);
|
||||
|
||||
const blocked = await evaluateVerificationAccess({
|
||||
prisma,
|
||||
config: {
|
||||
erpSyncEnabled: true,
|
||||
invoiceVerificationEnabled: true,
|
||||
},
|
||||
departmentId: "dept-b",
|
||||
strictDepartment: true,
|
||||
});
|
||||
|
||||
const allowed = await evaluateVerificationAccess({
|
||||
prisma,
|
||||
config: {
|
||||
erpSyncEnabled: true,
|
||||
invoiceVerificationEnabled: true,
|
||||
},
|
||||
departmentId: "dept-a",
|
||||
strictDepartment: true,
|
||||
});
|
||||
|
||||
expect(blocked.enabled).toBe(false);
|
||||
expect(blocked.reason).toBe("department_not_allowed");
|
||||
expect(allowed.enabled).toBe(true);
|
||||
expect(allowed.reason).toBe("flag_force_on_department_allowed");
|
||||
});
|
||||
});
|
||||
|
||||
describe("verifyInvoiceByProvider", () => {
|
||||
const invoice = {
|
||||
invoice_code: "INV-001",
|
||||
invoice_number: "NO-001",
|
||||
total_amount: "100.00",
|
||||
remarks: "ok",
|
||||
};
|
||||
|
||||
it("uses mock provider and returns passed", async () => {
|
||||
const result = await verifyInvoiceByProvider({
|
||||
config: { verificationProvider: "mock" },
|
||||
invoice,
|
||||
});
|
||||
|
||||
expect(result.status).toBe("passed");
|
||||
expect(result.resultCode).toBe("verified");
|
||||
});
|
||||
|
||||
it("uses tax provider and returns provider-not-configured", async () => {
|
||||
const result = await verifyInvoiceByProvider({
|
||||
config: { verificationProvider: "tax" },
|
||||
invoice,
|
||||
});
|
||||
|
||||
expect(result.status).toBe("error");
|
||||
expect(result.resultCode).toBe("tax_provider_not_configured");
|
||||
});
|
||||
|
||||
it("returns unsupported provider error", async () => {
|
||||
const result = await verifyInvoiceByProvider({
|
||||
config: { verificationProvider: "unknown" },
|
||||
invoice,
|
||||
});
|
||||
|
||||
expect(result.status).toBe("error");
|
||||
expect(result.resultCode).toBe("provider_unsupported");
|
||||
});
|
||||
});
|
||||
在新工单中引用
屏蔽一个用户