크라우니 ERP 공통 인프라 갭 4종(X-G1~X-G4) + FI 개별항목 필터조회
개요
ERP-A(:9981, FI/CO/MM/SD/PP)·ERP-B(:9983, HR/QM/PM/PS/WM) 양쪽 서버에 공통 승인 워크플로,
RBAC, 환율 팩트 공용화, 다중 법인 필터, FI 계정별 필터조회를 추가했다. 프록시(감사서버 :9802)의
/api/erp/approve 셀id 대역 라우팅은 이미 배선돼 있어(2026-07-22 STR 처방), 이번 작업은 A/B
양쪽 서버의 라우트 핸들러 구현에 집중했다.
무엇을 했는지
X-G1 승인 워크플로(공통)
승인처리(셀id, 결정, 승인자사번) 함수를 셀코어ERP.한선(양 서버 공용 코어)에 1회 추가.
- 대상 셀 S사상==음(2)일 때만 처리: 승인(1)→사상티+단계4, 반려(0)→사상타+단계6.
- 처리 후 감사 셀(모듈=원셀 모듈, 문서유형=98, 선행=대상셀, 승인자 기록) 생성.
- 4상: 셀 없음=타, 비음 셀=타, 승인자 미등록=옴, 권한 없음=타, 정상 처리=티/타.
- 라우트:
POST /api/approve (A/B 양쪽 동일 추가), 본문 셀id|결정|승인자사번.
X-G2 RBAC
승인자직급조회(사번) — HR_사원.psv 필드3(직급) 직독.
직급승인허용(직급) — 신설 data/master/공통_승인권한.psv(직급|허용) 조회. 직급 7/8/9(부장급 이상)만 허용.
X-G3 환율 팩트 공용화
- A서버
/api/fact/fx-rate?k=USD 추가. 기존 erp_FI.한선의 FI_통화코드()/FI_환율() 재사용
(data/마스터_환율.psv 그대로, 신규 마스터 불필요).
X-G4 다중 법인
- 신설
data/master/공통_법인.psv(법인코드|명코드|기본통화), 시드 1000|1|KRW, 2000|2|USD.
GET /api/fact/org-exists?k= (A) — 법인 존재 확인.
GET /api/ledger/{MOD}?org= (A/B) — 장부행에 org 필드가 없어 셀 S조직으로 정확 판정.
⚠️최초 구현이 장부행마다
셀슬롯()(O(n) 전체스캔)을 호출해 O(장부행수×셀넷크기) 콰드러틱으로
단일스레드 서버가 CPU100% 무응답 스톨(실측).
셀조직맵()으로 셀넷을 1회만 스캔해 id→조직
해시맵을 만들고 장부행은
맵꺼내() O(1) 조회로 수정 → 문제 해소, 3.5초 내 응답.
GET /api/cells/by-org?org= (A/B, 보너스) — 모듈 무관 셀 직스캔.
FI 개별항목 필터조회
- FI 장부행(셀id|유형|사상|금액|메시지)엔 계정 필드가 없어 셀넷 직스캔으로 대응.
GET /api/cells/fi-by-account?k=1001 (A) — S모듈==FI(1) 그리고 S주체(차변계정)==k 필터, PSV 원본 그대로 text/plain.
관련 파일
/Users/ef/crowny-erp/core/libs/셀코어ERP.한선 — 승인처리/승인자직급조회/직급승인허용 추가
/Users/ef/crowny-erp/core/servers/ERP통합서버.한선 — A서버 라우트(approve/fx-rate/org-exists/ledger org필터/cells 필터 3종)
/Users/ef/crowny-erp/core/servers/ERP서버B.한선 — B서버 라우트(approve/ledger org필터/cells/by-org)
/Users/ef/crowny-erp/data/master/공통_승인권한.psv — 신설(직급|허용)
/Users/ef/crowny-erp/data/master/공통_법인.psv — 신설(법인코드|명코드|기본통화)
/Users/ef/crowny-erp/data/규칙/사상규칙.psv — R600/R601 승인 규칙 행 추가
검증
- 컴파일 A/B 에러 0 (hanseonc_high, 138557/121650+α 큐브).
- 배포: cp .toau → lsof kill 9981/9983 → LaunchAgent(KeepAlive) 자동 재기동 → health 2종 200.
- 승인 종단(A대역, FI): bill-note 6000만원(음 셀 1939 생성) → approve(1939|1|5003, 직급9임원) →
사상 음→티, 감사 셀 1940(선행=1939, 승인자=5003) 생성 확인(cells/scan since=1938으로 append-log 4행 확인).
- 반려: 새 음 셀 1941 → approve(1941|0|5003) → 타.
- 권한없는 사번(5001, 직급3): approve(cid|1|5001) → 타(승인 권한 없음(직급3)).
- 비음 셀 재승인(1939, 이미 티): approve(1939|1|5003) → 타(음 상태가 아니라 승인 대상 아님).
- 미등록 사번(99999): approve(cid|1|99999) → 옴(승인자 미등록).
- B대역 라우팅(HR leave, 사번6002 잔여15·15일 신청→음 셀 5001784): approve(5001784|1|5003, 프록시가
5000000≤id<1000만→9983 라우팅) → 티, 승인 확정. 프록시 대역 라우팅 실증.
- fx-rate:
/api/fact/fx-rate?k=USD → {ok:true,value:1700}.
- org-exists: k=1000→1, k=9999→0.
- ledger org필터:
/api/ledger/FI?org=1000 → JSON 배열(788행 중 org=1000 매치만).
- FI 계정필터:
/api/cells/fi-by-account?k=101 → 해당 계정 거래 셀 PSV 원본 행.
- 스모크 회귀:
ERP페이지스모크.sh 138/138 PASS (신규 approve는 스펙 미포함이라 별도 검증).
- 사상규칙.psv R600/R601 추가, crownycode-learn.sh add 학습 완료.
잔여 이슈
장부JSON필터/셀조직맵은 요청마다 신규 해시맵을 만들어 버림(맵 재사용 캐시 없음) — 고빈도
호출 시 맵힙 누적 여지 있음(가드레일 "맵힙 고갈" 주의사항). 현재 트래픽 규모에선 문제 없으나
프로덕션 스케일에서는 프로세스 전역 캐시(권한검증.한선
_조직캐시 패턴)로 전환 고려.
/api/cells/by-org 전체 셀넷 스캔은 셀넷 크기(현재 ~2000행, 19+세션 동시성장 중)에 비례해
느려짐(실측 7.8초) — 향후 셀넷이 더 커지면 셀조직맵 방식으로 전환 필요.
- 공통_승인권한.psv 직급 매핑(7/8/9=부장/이사/임원)은 HR_사원.psv에 직급명 텍스트가 없어
숫자 코드 기준으로 정의(HR임원직급=9 상수와 일치 확인). 명칭 매핑이 필요해지면 HR_조직.psv나
별도 직급명.psv 신설 검토.