Files
wace_rps/frontend/lib/utils/numberingRuleDeps.ts
T
chpark 945b65b870
Build and Push Images / build-and-push (push) Has been cancelled
시퀀스 관리 메뉴 + 테이블 타입관리 코멘트/검증 + 설계 문서
- 시스템 관리 > 시퀀스 관리 신규 메뉴 + 페이지(채번 룰 빌더)
- ensureSequenceMngMenu 부팅 시드
- 테이블 타입관리 → 채번 룰 드롭다운 + 의존성 자동 검증
- 표시명/코멘트 UX 개선
- 설계 문서 추가

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 11:46:11 +09:00

82 lines
3.2 KiB
TypeScript

/**
* 채번 룰 의존성 분석 유틸
* - 룰이 동작하려면 적용 테이블에 어떤 폼 키 컬럼들이 있어야 하는지 추출
* - 테이블 타입 관리에서 룰 선택 시 검증에 사용
*
* 의존이 생기는 케이스:
* 1) reference 파트 (mode=master) : 폼키(referenceColumnName) 가 적용 테이블의 컬럼이어야 한다
* 2) reference 파트 (mode=form) : 폼키(referenceColumnName) 가 적용 테이블의 컬럼이어야 한다
* 3) category 파트 : categoryKey="table.col" 일 때, table 이 적용 테이블이면 col 이 의존
* (table 이 다른 테이블이면 그 테이블 마스터 조회 — 의존 아님)
*
* 의존이 아닌 케이스:
* - sequence / date / number / text / reference(constant)
*/
export interface NumberingRulePartLite {
partType: string;
autoConfig?: Record<string, any>;
}
export interface NumberingRuleLite {
ruleId?: string;
ruleName?: string;
parts?: NumberingRulePartLite[];
}
/** 룰에서 적용 테이블에 있어야 하는 폼 키(컬럼명) 목록을 추출 */
export function extractRequiredFormKeys(
rule: NumberingRuleLite | null | undefined,
tableName?: string,
): string[] {
if (!rule?.parts) return [];
const keys: string[] = [];
for (const p of rule.parts) {
const c = (p.autoConfig ?? {}) as Record<string, any>;
if (p.partType === "reference") {
const mode = c.mode ?? (c.sourceTableName ? "master" : c.constantValue ? "constant" : "form");
// master/form 모두 폼키(referenceColumnName) 필요
if ((mode === "master" || mode === "form") && c.referenceColumnName) {
keys.push(String(c.referenceColumnName));
}
} else if (p.partType === "category") {
// categoryKey="table.col" → table 이 적용 테이블이면 col 이 의존
const key: string = c.categoryKey ?? "";
if (typeof key === "string" && key.includes(".")) {
const [tbl, col] = key.split(".");
if (tableName && tbl && col && tbl === tableName) {
keys.push(col);
}
// 다른 테이블이면 마스터 조회 — 적용 테이블 의존은 아님
} else if (typeof key === "string" && key && tableName) {
// table 명시 안 됨 → 적용 테이블의 컬럼명으로 간주
keys.push(key);
}
}
}
// 중복 제거 + 의미있는 값만
return Array.from(new Set(keys.filter(Boolean)));
}
export interface DependencyCheckResult {
required: string[];
satisfied: string[];
missing: string[];
}
/** 룰의 요구 컬럼 vs 실제 테이블 컬럼 → 충족/누락 분석 */
export function checkRuleDependencies(
rule: NumberingRuleLite | null | undefined,
tableName: string,
tableColumns: Array<{ columnName: string }>,
): DependencyCheckResult {
const required = extractRequiredFormKeys(rule, tableName);
const colSet = new Set(tableColumns.map((c) => c.columnName.toLowerCase()));
const satisfied: string[] = [];
const missing: string[] = [];
for (const k of required) {
if (colSet.has(k.toLowerCase())) satisfied.push(k);
else missing.push(k);
}
return { required, satisfied, missing };
}