完成五人团队正式内用最小收口(07-18-small-team-internal-readiness)

这个提交包含在:
2026-07-18 15:46:14 +08:00
父节点 58c8decef9
当前提交 5d0a5f9a38
共修改 134 个文件,包含 10790 行新增和 1413 行删除
+42 -3
查看文件
@@ -9,6 +9,16 @@ const BLOCKING_ASSIGNEE_SKIP_REASONS = new Set([
"cycle_detected",
"max_depth_exceeded",
]);
const BUSINESS_APPROVAL_ROLE_CODES = Object.freeze([
"employee",
"manager",
"ceo",
"finance",
"finance_mgr",
"hr",
"administration",
]);
const BUSINESS_APPROVAL_ROLE_CODE_SET = new Set(BUSINESS_APPROVAL_ROLE_CODES);
const SUPPORTED_OWNER_SELF_FALLBACK_ROLES = new Set(["finance_mgr"]);
const OWNER_SELF_FALLBACK_REASONS = new Set([
"no_manager_found",
@@ -32,6 +42,23 @@ function parseWorkflowSteps(definitionJson) {
return steps;
}
function isBusinessApprovalRoleCode(roleCode) {
return typeof roleCode === "string" && BUSINESS_APPROVAL_ROLE_CODE_SET.has(roleCode);
}
function assertBusinessApprovalRoleCode(roleCode) {
if (isBusinessApprovalRoleCode(roleCode)) {
return roleCode;
}
throw new AppError({
code: "VALID_001",
message: "参数校验失败",
statusCode: 400,
details: { workflow: "unsupported_business_approval_role" },
});
}
function buildWorkflowStepsFromApprovalRule(approvalRule) {
if (!approvalRule || typeof approvalRule !== "object") {
throw new AppError({
@@ -57,6 +84,8 @@ function buildWorkflowStepsFromApprovalRule(approvalRule) {
});
}
roleCodes.forEach(assertBusinessApprovalRoleCode);
return roleCodes.map((roleCode, index) => ({
id: `approval_${index + 1}_${roleCode}`,
name: `审批节点${index + 1}`,
@@ -364,6 +393,7 @@ async function resolveAssigneeFromRule(rule, options = {}) {
details: { workflow: "invalid_role_assignee" },
});
}
assertBusinessApprovalRoleCode(rule.value);
return {
assigneeId: null,
@@ -504,11 +534,18 @@ async function resolveActionableStep({
function getWorkflowStepsSnapshot(workflowInstance) {
const snapshot = workflowInstance?.context_data?.workflow_steps_snapshot;
if (Array.isArray(snapshot) && snapshot.length > 0) {
return parseWorkflowSteps({ steps: snapshot });
const steps = Array.isArray(snapshot) && snapshot.length > 0
? parseWorkflowSteps({ steps: snapshot })
: parseWorkflowSteps(workflowInstance?.workflow_definition?.definition_json);
for (const step of steps) {
const roleCode = getRoleCodeFromStep(step);
if (roleCode) {
assertBusinessApprovalRoleCode(roleCode);
}
}
return parseWorkflowSteps(workflowInstance?.workflow_definition?.definition_json);
return steps;
}
function toMoneyString(value) {
@@ -517,9 +554,11 @@ function toMoneyString(value) {
}
module.exports = {
BUSINESS_APPROVAL_ROLE_CODES,
buildApprovalWorkflowSnapshot,
buildWorkflowStepsFromApprovalRule,
getWorkflowStepsSnapshot,
isBusinessApprovalRoleCode,
parseWorkflowSteps,
resolveActionableStep,
resolveAssigneeFromRule,