feat(P25-1/P25-5/P26-1/P26-3/P24-1/P29-4): 落地内部OA够用版后端与试运行能力

关联 Issue: P25-1, P25-2, P25-3, P25-4, P25-5, P26-1, P26-3, P24-1, P24-2, P29-1, P29-2, P29-3, P29-4
这个提交包含在:
2026-03-21 18:03:20 +08:00
父节点 9b7cd818f7
当前提交 e39e41287e
共修改 45 个文件,包含 4571 行新增和 328 行删除
@@ -212,13 +212,8 @@ describe("listFeatureFlags", () => {
invoiceVerificationEnabled: true,
});
expect(items).toHaveLength(4);
expect(items.map((item) => item.flagKey).sort()).toEqual([
FEATURE_FLAG_KEYS.aiAssist,
FEATURE_FLAG_KEYS.erpSync,
FEATURE_FLAG_KEYS.invoiceVerification,
FEATURE_FLAG_KEYS.leaveHolidayCalendar,
]);
expect(items).toHaveLength(Object.keys(FEATURE_FLAG_KEYS).length);
expect(items.map((item) => item.flagKey).sort()).toEqual(Object.values(FEATURE_FLAG_KEYS).sort());
const missingItem = items.find((item) => item.flagKey === FEATURE_FLAG_KEYS.aiAssist);
expect(missingItem.id).toBeNull();
@@ -69,6 +69,9 @@ function buildPrisma({ items = [], detail = null } = {}) {
count: vi.fn().mockResolvedValue(items.length),
findUnique: vi.fn().mockResolvedValue(detail),
},
entityRiskFlag: {
findMany: vi.fn().mockResolvedValue([]),
},
};
}
+6 -4
查看文件
@@ -7,8 +7,8 @@ const {
describe("IM enqueue", () => {
it("builds detail url from APP_ORIGIN", () => {
expect(buildDetailUrl({ appOrigin: "https://app.example.com" }, "/workflow/tasks/1")).toBe(
"https://app.example.com/workflow/tasks/1",
expect(buildDetailUrl({ appOrigin: "https://app.example.com", jwtSecret: "test-secret" }, "/workflow/tasks/1")).toContain(
"https://app.example.com/api/auth/deeplink?token=",
);
expect(buildDetailUrl({ appOrigin: "" }, "/workflow/tasks/1")).toBeNull();
});
@@ -93,6 +93,7 @@ describe("IM enqueue", () => {
imNotifierEnabled: true,
integrationOutboxMaxAttempts: 5,
appOrigin: "https://app.example.com",
jwtSecret: "test-secret",
},
logger: { warn: vi.fn() },
recipientEmployeeIds: ["employee-1"],
@@ -111,8 +112,8 @@ describe("IM enqueue", () => {
expect(result.duplicated).toBe(1);
expect(result.matchedChannels).toEqual(["channel-1", "channel-2"]);
expect(tx.integrationOutbox.create).toHaveBeenCalledTimes(1);
expect(tx.integrationOutbox.create.mock.calls[0][0].data.payload.detailUrl).toBe(
"https://app.example.com/workflow/tasks/task-1",
expect(tx.integrationOutbox.create.mock.calls[0][0].data.payload.detailUrl).toEqual(
expect.stringContaining("https://app.example.com/api/auth/deeplink?token="),
);
});
@@ -150,6 +151,7 @@ describe("IM enqueue", () => {
imNotifierEnabled: true,
integrationOutboxMaxAttempts: 5,
appOrigin: "https://app.example.com",
jwtSecret: "test-secret",
},
logger: { warn: vi.fn() },
recipientEmployeeIds: ["employee-1"],