恢复付款入口与常开基线(08-01-reimbursement-notification-progress-clarity)
这个提交包含在:
@@ -19,7 +19,7 @@ type FeatureFlagItem = {
|
||||
|
||||
type FeatureFlagSnapshot = Pick<
|
||||
FeatureFlagItem,
|
||||
"flagKey" | "overrideMode" | "rolloutType" | "departmentIds" | "version" | "effectiveEnabled" | "effectiveReason"
|
||||
"flagKey" | "overrideMode" | "rolloutType" | "departmentIds" | "note" | "version" | "effectiveEnabled" | "effectiveReason"
|
||||
>;
|
||||
|
||||
type ReimbursementDetail = {
|
||||
@@ -99,7 +99,7 @@ const baseUrl = process.env.LIVE_SMOKE_BASE_URL?.trim() || "https://oa.hyinda.co
|
||||
const reportDir = process.env.P2_FIN_LIVE_REPORT_DIR?.trim() ||
|
||||
path.resolve(process.cwd(), "..", "artifacts/qa-flow/p2-fin-live-local");
|
||||
const summaryPath = path.join(reportDir, "live-result.json");
|
||||
const finalFlagState = process.env.P2_FIN_LIVE_FINAL_STATE?.trim() === "force_on" ? "force_on" : "force_off";
|
||||
const finalFlagState = process.env.P2_FIN_LIVE_FINAL_STATE?.trim() === "force_on" ? "force_on" : "restore";
|
||||
const alreadyOnMode =
|
||||
process.env.P2_FIN_LIVE_ALREADY_ON === "1" ||
|
||||
process.env.LAUNCH_AUTO_PAYMENT_BATCH_ALREADY_ON === "1";
|
||||
@@ -130,6 +130,7 @@ function snapshotFlag(item: FeatureFlagItem): FeatureFlagSnapshot {
|
||||
overrideMode: item.overrideMode,
|
||||
rolloutType: item.rolloutType,
|
||||
departmentIds: item.departmentIds,
|
||||
note: item.note,
|
||||
version: item.version,
|
||||
effectiveEnabled: item.effectiveEnabled,
|
||||
effectiveReason: item.effectiveReason,
|
||||
@@ -183,13 +184,15 @@ async function updateFlag(
|
||||
flagKey: string,
|
||||
overrideMode: FeatureFlagItem["overrideMode"],
|
||||
note: string,
|
||||
rolloutType: FeatureFlagItem["rolloutType"] = "global",
|
||||
departmentIds: string[] = [],
|
||||
) {
|
||||
const current = await loadFlag(api, flagKey);
|
||||
const response = await api.put(`/api/system/feature-flags/${flagKey}`, {
|
||||
data: {
|
||||
overrideMode,
|
||||
rolloutType: "global",
|
||||
departmentIds: [],
|
||||
rolloutType,
|
||||
departmentIds,
|
||||
note,
|
||||
expectedVersion: current.version,
|
||||
},
|
||||
@@ -198,12 +201,24 @@ async function updateFlag(
|
||||
return data.item;
|
||||
}
|
||||
|
||||
async function forcePaymentBatchOff(api: APIRequestContext, note: string) {
|
||||
async function restoreFlagSnapshot(api: APIRequestContext, snapshot: FeatureFlagSnapshot) {
|
||||
const current = await loadFlag(api, "payment_batch_v1");
|
||||
if (current.overrideMode === "force_off" && !current.effectiveEnabled) {
|
||||
const configurationMatches =
|
||||
current.overrideMode === snapshot.overrideMode &&
|
||||
current.rolloutType === snapshot.rolloutType &&
|
||||
JSON.stringify(current.departmentIds) === JSON.stringify(snapshot.departmentIds) &&
|
||||
current.note === snapshot.note;
|
||||
if (configurationMatches) {
|
||||
return current;
|
||||
}
|
||||
return updateFlag(api, "payment_batch_v1", "force_off", note);
|
||||
return updateFlag(
|
||||
api,
|
||||
"payment_batch_v1",
|
||||
snapshot.overrideMode,
|
||||
snapshot.note,
|
||||
snapshot.rolloutType,
|
||||
snapshot.departmentIds,
|
||||
);
|
||||
}
|
||||
|
||||
function resolveLivePdfBuffer(marker: string) {
|
||||
@@ -397,6 +412,7 @@ test.describe("公网付款批次受控验收", () => {
|
||||
|
||||
const clients: AuthenticatedApiClient[] = [];
|
||||
let admin: AuthenticatedApiClient | null = null;
|
||||
let paymentFlagBefore: FeatureFlagItem | null = null;
|
||||
let caughtError: unknown = null;
|
||||
let rollbackError: unknown = null;
|
||||
|
||||
@@ -408,7 +424,7 @@ test.describe("公网付款批次受控验收", () => {
|
||||
const financeMgr = await createLiveClientWithRetry("financeMgr");
|
||||
clients.push(admin, employee, manager, finance, financeMgr);
|
||||
|
||||
const paymentFlagBefore = await loadFlag(admin.api, "payment_batch_v1");
|
||||
paymentFlagBefore = await loadFlag(admin.api, "payment_batch_v1");
|
||||
const erpFlagBefore = await loadFlag(admin.api, "erp_sync");
|
||||
summary.stages.preflight = {
|
||||
paymentFlagBefore: snapshotFlag(paymentFlagBefore),
|
||||
@@ -587,19 +603,7 @@ test.describe("公网付款批次受控验收", () => {
|
||||
} finally {
|
||||
if (admin) {
|
||||
try {
|
||||
if (alreadyOnMode) {
|
||||
const finalPaymentFlag = await loadFlag(admin.api, "payment_batch_v1");
|
||||
const finalErpFlag = await loadFlag(admin.api, "erp_sync");
|
||||
summary.stages.finalState = {
|
||||
paymentFlag: snapshotFlag(finalPaymentFlag),
|
||||
erpSyncEffectiveEnabled: finalErpFlag.effectiveEnabled,
|
||||
alreadyOnMode,
|
||||
};
|
||||
expect(finalPaymentFlag.effectiveEnabled).toBe(true);
|
||||
expect(finalPaymentFlag.overrideMode).toBe("force_on");
|
||||
expect(finalFlagState).toBe("force_on");
|
||||
expect(finalErpFlag.effectiveEnabled).toBe(false);
|
||||
} else if (finalFlagState === "force_on" && !caughtError) {
|
||||
if (finalFlagState === "force_on" && !caughtError) {
|
||||
const paymentFlag = await loadFlag(admin.api, "payment_batch_v1");
|
||||
const finalPaymentFlag =
|
||||
paymentFlag.overrideMode === "force_on" && paymentFlag.effectiveEnabled
|
||||
@@ -609,14 +613,18 @@ test.describe("公网付款批次受控验收", () => {
|
||||
summary.stages.finalState = {
|
||||
paymentFlag: snapshotFlag(finalPaymentFlag),
|
||||
erpSyncEffectiveEnabled: finalErpFlag.effectiveEnabled,
|
||||
alreadyOnMode,
|
||||
};
|
||||
expect(finalPaymentFlag.effectiveEnabled).toBe(true);
|
||||
expect(finalPaymentFlag.overrideMode).toBe("force_on");
|
||||
expect(finalErpFlag.effectiveEnabled).toBe(false);
|
||||
} else {
|
||||
const rolledBack = await forcePaymentBatchOff(admin.api, `${issueId} rollback ${marker}`);
|
||||
summary.stages.rollback = { paymentFlagAfterRollback: snapshotFlag(rolledBack) };
|
||||
expect(rolledBack.effectiveEnabled).toBe(false);
|
||||
} else if (paymentFlagBefore) {
|
||||
const restored = await restoreFlagSnapshot(admin.api, snapshotFlag(paymentFlagBefore));
|
||||
summary.stages.rollback = { paymentFlagAfterRestore: snapshotFlag(restored) };
|
||||
expect(restored.overrideMode).toBe(paymentFlagBefore.overrideMode);
|
||||
expect(restored.rolloutType).toBe(paymentFlagBefore.rolloutType);
|
||||
expect(restored.departmentIds).toEqual(paymentFlagBefore.departmentIds);
|
||||
expect(restored.note).toBe(paymentFlagBefore.note);
|
||||
}
|
||||
} catch (error) {
|
||||
rollbackError = error;
|
||||
|
||||
在新工单中引用
屏蔽一个用户