/* * 도메인 어휘 카탈로그 조합 — 커널(@operato/twin-kernel)이 SSOT, 여기서는 **노출 형태만** 만든다. * * 이 함수가 정본 진입점이다: GraphQL 리졸버(twinDomainCatalog)와 서버측 소비자(예: operato-twin 의 * board-ai 도구 카테고리)가 같은 조합을 쓰도록 하기 위해 분리했다. 소비자마다 커널을 직접 require 해 * 조합을 재현하면 프로파일 병합(mes.products)이나 능력 메타 포함 여부가 갈린다(방언). */ /* 커널은 CJS 배포 — ESM import 대신 require(리졸버의 기존 관행과 동일). */ const { MES_PRODUCTS } = require('@operato/twin-kernel') const { DOMAIN_CATALOG, CAPABILITIES, capabilitiesForType } = require('@operato/ops-contract') /** * 시스템별(wms/yms/mes) 노드·설비 타입과 각 타입의 능력을 담은 카탈로그. * MES 제품 목록을 mes 프로파일에 병합하고 능력 메타(capabilities)를 함께 싣는다. * * 커널 빌드가 낡아 DOMAIN_CATALOG 가 없으면 명시 throw — 무의미한 null 대신 원인을 알린다. * 조치: 커널 재빌드 후 dist/dist-cjs 를 node_modules 에 복사. */ export function domainCatalog(): any { if (!DOMAIN_CATALOG) { throw new Error('DOMAIN_CATALOG missing — @operato/twin-kernel build is stale. Rebuild kernel and copy dist/dist-cjs into node_modules.') } return { ...DOMAIN_CATALOG, mes: { ...DOMAIN_CATALOG.mes, products: MES_PRODUCTS ?? [] }, capabilities: CAPABILITIES ?? {} } } /** * 타입 → 능력. 커널의 `capabilitiesForType` 이 정본이며 여기서는 **시스템 미상** 경우만 보완한다 * (커널 함수는 system 을 요구). 소비자가 조회 규칙을 각자 재현하지 않도록 이 함수를 쓸 것. * * @param typeKey 노드 타입 또는 무버 kind * @param system wms | yms | mes. 모르면 생략 — 전 프로파일에서 처음 일치하는 타입의 능력을 쓴다. */ export function capabilitiesOfType(typeKey: string, system?: string): string[] { if (!typeKey) return [] if (system && DOMAIN_CATALOG?.[system]) { try { return capabilitiesForType(system, typeKey) ?? [] } catch { /* 커널이 모르는 조합 — 아래 전 프로파일 탐색으로 넘어간다. */ } } for (const profile of Object.values(DOMAIN_CATALOG ?? {}) as any[]) { const t = (profile?.types ?? []).find((x: any) => x.key === typeKey) if (Array.isArray(t?.capabilities)) return t.capabilities } return [] }