WRA1 修正企微运行验收门禁

这个提交包含在:
2026-05-19 02:16:20 +08:00
父节点 82b211e1a5
当前提交 9d1927a4f9
共修改 14 个文件,包含 122 行新增和 34 行删除
@@ -233,6 +233,7 @@ function buildEntryOauthCheck(config) {
}
function buildSecretMatrix(config) {
const checkinSyncEnabled = Boolean(config.wecomCheckinSyncEnabled);
return {
contact: {
source: "WECOM_CONTACT_SECRET",
@@ -251,6 +252,8 @@ function buildSecretMatrix(config) {
endpoint: "POST /cgi-bin/checkin/getcheckindata",
override: configured(config.wecomCheckinSecret),
overrideEnv: configured(config.wecomCheckinSecret) ? "WECOM_CHECKIN_SECRET" : null,
syncEnabled: checkinSyncEnabled,
runtimeReadyMode: checkinSyncEnabled ? "sync_enabled" : "qa_read_only_sync_disabled",
},
messageAndOauth: {
source: "WECOM_AGENT_SECRET",
@@ -588,14 +591,6 @@ async function runCheckinReadCheck({
};
}
if (!config.wecomCheckinSyncEnabled) {
return {
...contract,
status: "BLOCKED",
reason: "wecom_checkin_sync_disabled",
missing: ["WECOM_CHECKIN_SYNC_ENABLED=true"],
};
}
if (!resolveCheckinSecret(config)) {
return {
...contract,
@@ -614,12 +609,18 @@ async function runCheckinReadCheck({
startDate: window.startDate,
endDate: window.endDate,
externalUserIds,
requireSyncEnabled: false,
});
return {
...contract,
status: result.ok ? "OK" : "BLOCKED",
reason: result.code || null,
syncEnabled: Boolean(config.wecomCheckinSyncEnabled),
runtimeReadyMode: config.wecomCheckinSyncEnabled ? "sync_enabled" : "qa_read_only_sync_disabled",
readiness: result.ok
? (config.wecomCheckinSyncEnabled ? "readable_and_sync_enabled" : "readable_sync_disabled")
: "blocked",
window,
userCount: externalUserIds.length,
recordCount: Array.isArray(result.records) ? result.records.length : 0,
@@ -75,10 +75,11 @@ async function fetchWecomCheckinData({
startDate,
endDate,
externalUserIds,
requireSyncEnabled = true,
fetchImpl = fetch,
}) {
const userIds = Array.from(new Set((externalUserIds ?? []).map((id) => toSafeString(id, 128)).filter(Boolean)));
if (!config?.wecomCheckinSyncEnabled) {
if (requireSyncEnabled && !config?.wecomCheckinSyncEnabled) {
return {
ok: false,
skipped: true,
@@ -173,6 +173,78 @@ describe("check-wecom-runtime-ready", () => {
]);
});
it("uses QA-only checkin read mode when sync switch is disabled", async () => {
const fetchCheckinImpl = vi.fn(async ({ requireSyncEnabled }) => {
expect(requireSyncEnabled).toBe(false);
return {
ok: true,
code: "wecom_checkin_fetched",
records: [],
response: { checkindataCount: 0 },
};
});
const report = await executeRuntimeReady(baseOptions(), {
config: baseConfig({ wecomCheckinSyncEnabled: false }),
env: {},
oaRows: [boundEmployee()],
fetchProfilesImpl: vi.fn(async () => ({
tokenSource: { contact: "WECOM_CONTACT_SECRET", hr: "WECOM_AGENT_SECRET" },
profiles: [wecomProfile()],
})),
fetchCheckinImpl,
generatedAt: "2026-05-19T01:00:00.000Z",
});
expect(report.status).toBe("PASS_WITH_CONFIG_GAPS");
expect(report.checks.secretMatrix.matrix.checkin).toMatchObject({
syncEnabled: false,
runtimeReadyMode: "qa_read_only_sync_disabled",
});
expect(report.checks.checkinRead).toMatchObject({
status: "OK",
syncEnabled: false,
runtimeReadyMode: "qa_read_only_sync_disabled",
readiness: "readable_sync_disabled",
});
});
it("keeps real WeCom checkin API failures blocking in QA-only mode", async () => {
const report = await executeRuntimeReady(baseOptions(), {
config: baseConfig({ wecomCheckinSyncEnabled: false }),
env: {},
oaRows: [boundEmployee()],
fetchProfilesImpl: vi.fn(async () => ({
tokenSource: { contact: "WECOM_CONTACT_SECRET", hr: "WECOM_AGENT_SECRET" },
profiles: [wecomProfile()],
})),
fetchCheckinImpl: vi.fn(async ({ requireSyncEnabled }) => {
expect(requireSyncEnabled).toBe(false);
return {
ok: false,
code: "wecom_checkin_api_error",
records: [],
response: { errcode: 301062, errmsg: "permission denied" },
message: "WeCom checkin errcode 301062",
};
}),
generatedAt: "2026-05-19T01:00:00.000Z",
});
expect(report.status).toBe("SKIP");
expect(report.conclusion).toBe("BLOCKED_BY_EXTERNAL_CONFIG");
expect(report.mainBlockers).toEqual(expect.arrayContaining([
expect.objectContaining({
id: "checkin_short_window_read",
reason: "wecom_checkin_api_error",
}),
]));
expect(report.checks.checkinRead).toMatchObject({
status: "BLOCKED",
readiness: "blocked",
});
});
it("blocks instead of falling back when contact Secret is missing", async () => {
const report = await executeRuntimeReady(baseOptions(), {
config: baseConfig({ wecomContactSecret: "" }),