WRA1 修正企微运行验收门禁
这个提交包含在:
@@ -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: "" }),
|
||||
|
||||
在新工单中引用
屏蔽一个用户