文件
hyb-oa/server/src/services/cutover.js
T
wangsli e39e41287e 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

80 行
1.8 KiB
JavaScript

const { AppError } = require("../utils/AppError");
const { FEATURE_FLAG_KEYS, evaluateFeatureFlag } = require("./featureFlags");
async function ensureCutoverAllowed({
prisma,
config,
request,
domain,
departmentId = null,
legalEntityId = null,
}) {
const gate = await evaluateFeatureFlag({
prisma,
config,
flagKey: FEATURE_FLAG_KEYS.cutoverConsole,
departmentId: departmentId ?? request.employee.department_id ?? null,
strictDepartment: false,
});
if (!gate.enabled) {
return {
checked: false,
allowed: true,
reason: gate.reason,
matchedScope: null,
};
}
const now = new Date();
const scopes = await prisma.cutoverScope.findMany({
where: {
enabled: true,
OR: [{ starts_at: null }, { starts_at: { lte: now } }],
},
orderBy: [{ scope_type: "asc" }, { scope_key: "asc" }],
});
const matchedScope = scopes.find((scope) => {
if (scope.scope_type === "domain") {
return scope.scope_key === domain;
}
if (scope.scope_type === "department") {
return departmentId && scope.scope_key === departmentId;
}
if (scope.scope_type === "legal_entity") {
return legalEntityId && scope.scope_key === legalEntityId;
}
return false;
}) ?? null;
if (!matchedScope) {
throw new AppError({
code: "VALID_001",
message: "参数校验失败",
statusCode: 409,
details: {
cutover: "not_enabled",
domain,
departmentId,
legalEntityId,
},
});
}
return {
checked: true,
allowed: true,
reason: gate.reason,
matchedScope: {
id: matchedScope.id,
scopeType: matchedScope.scope_type,
scopeKey: matchedScope.scope_key,
},
};
}
module.exports = {
ensureCutoverAllowed,
};