治理(08-11-internal-oa-finance-backoffice-positioning-and-navigation-reduction): 固化财务后台定位与写入定性

这个提交包含在:
2026-08-13 21:27:53 +08:00
父节点 08c9d42e15
当前提交 71e68c8ddf
共修改 12 个文件,包含 747 行新增和 24 行删除
@@ -0,0 +1,166 @@
export const FEATURE_FLAG_APPLY_DECISION = Object.freeze({
CONTINUE_POST: "CONTINUE_POST",
STOP_NOT_APPLIED: "STOP_NOT_APPLIED",
STOP_UNKNOWN: "STOP_UNKNOWN",
STOP_FOR_MANUAL_DECISION: "STOP_FOR_MANUAL_DECISION",
});
function normalizeTargets(targets) {
if (!Array.isArray(targets) || targets.length === 0) {
throw new TypeError("targets must be a non-empty array");
}
const keys = targets.map((target) => String(target?.flagKey ?? "").trim());
if (keys.some((key) => !key) || new Set(keys).size !== keys.length) {
throw new TypeError("targets must contain unique non-empty flagKey values");
}
return targets.map((target, index) => {
const preVersion = Number(target.preVersion);
if (!Number.isInteger(preVersion) || preVersion < 1) {
throw new TypeError(`invalid preVersion for ${keys[index]}`);
}
const preOverrideMode = String(target.preOverrideMode ?? "").trim();
const postOverrideMode = String(target.postOverrideMode ?? "").trim();
if (!preOverrideMode || !postOverrideMode) {
throw new TypeError(`missing override mode for ${keys[index]}`);
}
return Object.freeze({
flagKey: keys[index],
preVersion,
preOverrideMode,
postVersion: preVersion + 1,
postOverrideMode,
});
});
}
function normalizeReadback(readback) {
if (!Array.isArray(readback)) {
throw new TypeError("readback must be an array");
}
return new Map(
readback.map((item) => [
String(item?.flagKey ?? "").trim(),
{
version: Number(item?.version),
overrideMode: String(item?.overrideMode ?? "").trim(),
},
]),
);
}
function matchesState(actual, version, overrideMode) {
return actual?.version === version && actual?.overrideMode === overrideMode;
}
export function classifyFeatureFlagApplyReadback({ targets, readback }) {
const normalizedTargets = normalizeTargets(targets);
const actualByKey = normalizeReadback(readback);
const observations = normalizedTargets.map((target) => {
const actual = actualByKey.get(target.flagKey);
if (matchesState(actual, target.postVersion, target.postOverrideMode)) {
return { flagKey: target.flagKey, state: "POST" };
}
if (matchesState(actual, target.preVersion, target.preOverrideMode)) {
return { flagKey: target.flagKey, state: "PRE" };
}
return { flagKey: target.flagKey, state: "OTHER" };
});
if (observations.every((item) => item.state === "POST")) {
return Object.freeze({
decision: FEATURE_FLAG_APPLY_DECISION.CONTINUE_POST,
classification: "APPLIED",
observations: Object.freeze(observations),
});
}
if (observations.every((item) => item.state === "PRE")) {
return Object.freeze({
decision: FEATURE_FLAG_APPLY_DECISION.STOP_NOT_APPLIED,
classification: "NOT_APPLIED",
observations: Object.freeze(observations),
});
}
return Object.freeze({
decision: FEATURE_FLAG_APPLY_DECISION.STOP_FOR_MANUAL_DECISION,
classification: "PARTIAL_OR_UNEXPECTED",
observations: Object.freeze(observations),
});
}
export async function resolveFeatureFlagApplyUncertainty({ targets, readCurrent }) {
if (typeof readCurrent !== "function") {
throw new TypeError("readCurrent must be a function");
}
try {
const readback = await readCurrent();
return classifyFeatureFlagApplyReadback({ targets, readback });
} catch (error) {
return Object.freeze({
decision: FEATURE_FLAG_APPLY_DECISION.STOP_UNKNOWN,
classification: "READBACK_FAILED",
errorCode: error instanceof Error && error.message ? error.message : "readback_failed",
observations: Object.freeze([]),
});
}
}
export function createSingleAttemptMutation(sendMutation) {
if (typeof sendMutation !== "function") {
throw new TypeError("sendMutation must be a function");
}
let attemptCount = 0;
return Object.freeze({
get attemptCount() {
return attemptCount;
},
async execute(payload) {
if (attemptCount !== 0) {
throw new Error("mutation_attempt_already_consumed");
}
attemptCount += 1;
return sendMutation(payload);
},
});
}
export async function executeFeatureFlagApplyAttempt({
targets,
payload,
sendMutation,
readCurrent,
observedRequestCount = null,
}) {
const mutation = createSingleAttemptMutation(sendMutation);
let response = null;
let responseError = null;
try {
response = await mutation.execute(payload);
} catch (error) {
responseError = error instanceof Error && error.message ? error.message : "mutation_result_unknown";
}
const resolution = await resolveFeatureFlagApplyUncertainty({ targets, readCurrent });
const normalizedObservedCount = Number.isInteger(observedRequestCount) && observedRequestCount >= 0
? observedRequestCount
: null;
return Object.freeze({
...resolution,
sendAttemptCount: mutation.attemptCount,
responseKnown: responseError === null,
response,
responseErrorCode: responseError,
observedRequestCount: normalizedObservedCount,
observerMismatch: normalizedObservedCount !== null && normalizedObservedCount !== mutation.attemptCount,
});
}