Stage 0: SAP(ZAA_ICF)에서 패키지 단위로 프로그램 소스 수집 (ingest/from_sap.py)

- sap/: abap-mcp 의 catalog/sap_client/mcp_server 복사. import 와 .env 탐색만 이 저장소에 맞춤
- ingest/from_sap.py: 패키지명 → GET_PROGRAM_LIST → GET_PROGRAM_SOURCE(+Include) → data/raw/*.txt
  (normalize 가 읽는 수집 JSON 형식 그대로). 받은 파일은 건너뛰고 --force 로 재수집
- normalize: 응답의 TCODE_LIST 를 tcodes.jsonl 로 (from_dir 와 같은 모양, 로더가 적재)
- .env.example 에 SAP_URL/SAP_USER/SAP_PASS, tests/test_from_sap.py

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
byeongwook.choi
2026-09-21 14:13:14 +09:00
co-authored by Claude Fable 5.1
parent 11ae3629b2
commit 921b8ce229
13 changed files with 1595 additions and 1 deletions
+549
View File
@@ -0,0 +1,549 @@
# -*- coding: utf-8 -*-
"""ZAA_ICF API 카탈로그: 메서드 설명, 파라미터, 입력 샘플, 응답 필드 사전, 코드값 해석.
SAP 을 모르는 개발자가 응답을 읽을 수 있도록 한국어 설명을 붙였다.
값은 2026-09-03 실제 서버 응답으로 검증한 것.
"""
# 응답에서 "빈 값이면 [] 로 취급" 할 테이블 필드
LIST_FIELDS = {
"RESULT", "INCLUDE_LIST", "SCREEN_LIST", "TCODE_LIST",
"IMPORT_PARAMETER", "EXPORT_PARAMETER", "CHANGING_PARAMETER",
"TABLES_PARAMETER", "EXCEPTION_LIST", "FIX_VALUES", "USED_TABLES", "MASTERS",
}
# 소스코드처럼 길게 표시할 필드
CODE_FIELDS = ["SOURCE_CODE", "FUNC_SOURCE", "SOURCE", "FLOW_LOGIC"]
# ---------------------------------------------------------------- 필드 사전 (응답 컬럼)
FIELDS = {
# 공통
"RETURN": ("처리 결과", "TYPE(S/W/E) 와 MESSAGE. W 는 결과가 상한에서 잘렸다는 뜻이 대부분."),
"RESULT": ("결과 목록", "조회 결과 행 목록"),
"TYPE": ("결과 유형", "S=성공, W=경고(결과 잘림 등), E=오류(필수값 누락/미존재)"),
"MESSAGE": ("메시지", "사람이 읽는 결과 설명"),
"TOTAL_ROWS": ("전체 건수", "절삭 전 전체 건수. IV_MAX_ROWS 가 있는 목록 API 만 채움 (그 외 0). 잘리지 않았으면 RESULT 건수와 같음"),
"KIND": ("오브젝트 세분류", "REPORT=실행 프로그램, MODULE_POOL=모듈 풀, INCLUDE=Include, FUGR_MAIN=함수그룹 메인(SAPL*), CLASS_POOL/INTERFACE_POOL/TYPE_POOL=클래스·인터페이스·타입 풀, TABLE/STRUCTURE/APPEND/VIEW/TABLE_TYPE/DATA_ELEMENT/DOMAIN=DDIC, CLASS/INTERFACE/FUNCTION_GROUP/FUNCTION/TCODE"),
"MASTERS": ("메인 프로그램 목록", "Include 를 포함하는 메인 프로그램(D010INC). KIND=INCLUDE 일 때만 채움"),
"SPRAS": ("텍스트 언어", "설명 텍스트가 어떤 언어인지. 3=한국어, E=영어, D=독일어"),
"SPRSL": ("텍스트 언어", "설명 텍스트가 어떤 언어인지. 3=한국어, E=영어, D=독일어"),
"LANG_PRIO": ("언어 우선순위", "1=로그인 언어(한국어), 2=영어, 3=독일어, 9=기타. 여러 언어 중 이 순서로 하나만 남김"),
# 패키지
"DEVCLASS": ("패키지", "개발 오브젝트를 묶는 폴더 개념(개발 클래스). Z/Y 로 시작하면 고객 개발"),
"CTEXT": ("패키지 설명", "패키지 짧은 설명"),
"PARENTCL": ("상위 패키지", "패키지 계층의 부모. 비어 있으면 최상위"),
# 프로그램
"OBJ_NAME": ("오브젝트 이름", "프로그램/클래스/테이블 등의 기술적 이름"),
"OBJECT": ("오브젝트 유형", "PROG=프로그램, FUGR=함수그룹, CLAS=클래스, TABL=테이블/구조, DTEL=데이터엘리먼트, TRAN=트랜잭션 등"),
"AUTHOR": ("담당자", "오브젝트 책임자(생성자) 사용자 ID"),
"TEXT": ("제목", "프로그램 제목 텍스트"),
"SUBC": ("프로그램 유형", "1=실행 프로그램(리포트), M=모듈 풀(화면 프로그램), I=Include, F=함수그룹, K=클래스 풀"),
"UDAT": ("최종 변경일", "마지막으로 소스를 바꾼 날짜"),
"UNAM": ("최종 변경자", "마지막으로 소스를 바꾼 사용자"),
"PROGRAM": ("프로그램", "조회한 프로그램 이름"),
"SOURCE_CODE": ("소스 코드", "ABAP 소스 전문(줄바꿈 포함)"),
"SOURCE_SIZE": ("소스 길이", "SOURCE_CODE 의 문자 수"),
"INCLUDE_LIST": ("Include 목록", "프로그램이 끌어다 쓰는 별도 소스 파일(Include)과 그 내용"),
"INCL_NAME": ("Include 이름", "Include 프로그램 이름. 클래스/Enhancement 시스템 include(31~32자, '=' 포함)는 서버가 걸러낸다"),
"SOURCE": ("소스", "해당 Include 의 ABAP 소스"),
"SCREEN_LIST": ("화면 목록", "프로그램에 붙은 화면(Dynpro)과 화면 흐름 로직"),
"SCREEN_NUMBER": ("화면 번호", "4자리 화면 번호 (예: 0100)"),
"FLOW_LOGIC": ("화면 흐름 로직", "PBO(표시 전)/PAI(입력 후) 에 실행되는 모듈 호출 코드"),
"TCODE_LIST": ("트랜잭션 코드", "이 프로그램을 실행하는 트랜잭션 코드(SAP 메뉴에서 치는 명령어)"),
"TCODE": ("트랜잭션 코드", "SAP 화면에서 입력하는 실행 명령어 (예: SE38, VA01)"),
"TTEXT": ("트랜잭션 설명", "트랜잭션 코드 텍스트"),
"PGMNA": ("프로그램", "트랜잭션이 실행하는 프로그램 이름"),
# 함수
"FUNCNAME": ("함수 모듈", "재사용 가능한 ABAP 함수(Function Module) 이름"),
"STEXT": ("함수 설명", "함수 짧은 설명"),
"FUNC_TEXT": ("함수 설명", "함수 짧은 설명"),
"FUGR_NAME": ("함수 그룹", "함수 모듈이 속한 그룹. 메인 프로그램은 SAPL<그룹>, TOP include 는 L<그룹>TOP"),
"FUNC_SOURCE": ("함수 소스", "함수 본문 소스 전문 (FUNCTION ~ ENDFUNCTION). 함수 Include 를 통째로 읽은 것"),
"IMPORT_PARAMETER": ("입력 파라미터", "호출자가 함수에 넘기는 값"),
"EXPORT_PARAMETER": ("출력 파라미터", "함수가 돌려주는 값"),
"CHANGING_PARAMETER": ("변경 파라미터", "넘겨서 받아오는(입출력) 값"),
"TABLES_PARAMETER": ("테이블 파라미터", "내부 테이블(행 목록)로 주고받는 값"),
"EXCEPTION_LIST": ("예외 목록", "함수가 실패 시 던지는 예외 이름"),
"PARAMETER": ("파라미터 이름", "함수 인터페이스 파라미터 이름"),
"DBFIELD": ("참조 타입", "파라미터 타입으로 참조하는 데이터엘리먼트/구조"),
"TYP": ("타입", "TYPE 절로 지정한 타입"),
"DEFAULT": ("기본값", "생략 시 사용되는 값"),
"OPTIONAL": ("선택 여부", "X=생략 가능"),
"REFERENCE": ("참조 전달", "X=값 복사 없이 참조로 전달"),
"DBSTRUCT": ("행 구조", "테이블 파라미터 한 행의 구조"),
"EXCEPTION": ("예외", "예외 이름"),
# 테이블
"TABNAME": ("테이블", "DB 테이블 또는 구조 이름"),
"DDTEXT": ("설명", "사전(Data Dictionary) 설명 텍스트"),
"TABCLASS": ("테이블 종류", "TRANSP=실제 DB 테이블, INTTAB=구조(데이터 없음), VIEW=뷰, CLUSTER/POOL=특수 테이블"),
"IS_CUSTOM": ("고객 개발", "X=Z/Y 로 시작하는 고객 개발 테이블"),
"FIELDNAME": ("필드", "테이블 컬럼 이름"),
"KEYFLAG": ("키 여부", "X=기본 키(Primary Key) 필드"),
"POSITION": ("순서", "테이블 안에서의 컬럼 순서"),
"ROLLNAME": ("데이터엘리먼트", "필드의 의미(설명·라벨)를 정의하는 재사용 타입. 도메인 위에 얹힘"),
"DOMNAME": ("도메인", "필드의 기술 속성(타입·길이·허용값)을 정의하는 재사용 타입"),
"DATATYPE": ("데이터 타입", "CHAR=문자, NUMC=숫자문자, DATS=날짜, TIMS=시간, DEC=소수, CURR=금액, QUAN=수량, INT4=정수, CLNT=클라이언트"),
"LENG": ("길이", "필드 길이(문자 수 또는 자릿수)"),
"DECIMALS": ("소수 자릿수", "소수점 이하 자릿수"),
"OUTPUTLEN": ("출력 길이", "화면 표시 길이"),
"CHECKTABLE": ("체크 테이블", "외래키로 값 유효성을 검사하는 참조 테이블"),
"SCRTEXT_S": ("짧은 라벨", "화면 표시용 라벨(짧음)"),
"SCRTEXT_M": ("중간 라벨", "화면 표시용 라벨(중간)"),
"SCRTEXT_L": ("긴 라벨", "화면 표시용 라벨(김)"),
"ELEMENT": ("데이터엘리먼트 정보", "입력이 데이터엘리먼트인 경우 채워짐"),
"DOMAIN": ("도메인 정보", "데이터엘리먼트의 도메인 또는 입력이 도메인인 경우"),
"LOWERCASE": ("소문자 허용", "X=대소문자 구분 저장(기본은 대문자 변환)"),
"CONVEXIT": ("변환 루틴", "저장값과 표시값을 바꾸는 루틴 (예: ALPHA=앞자리 0 채움)"),
"VALEXI": ("고정값 존재", "X=도메인에 허용값 목록(FIX_VALUES)이 있음"),
"ENTITYTAB": ("값 테이블", "허용값을 관리하는 테이블 (예: MTART → T134)"),
"FIX_VALUES": ("고정값 목록", "도메인에 정의된 허용 값과 설명"),
"DOMVALUE_L": ("", "허용 값"),
"USED_TABLES": ("사용 테이블", "이 데이터엘리먼트를 컬럼 타입으로 쓰는 테이블/구조 전부 (총량 안전 상한 50,000)"),
# CTS
"TRKORR": ("전송 요청 번호", "변경 사항 묶음(Transport Request) 번호. 개발→운영 이관 단위"),
"AS4TEXT": ("요청 설명", "전송 요청 제목"),
"AS4USER": ("소유자", "전송 요청을 만든 사용자"),
"TRFUNCTION": ("요청 유형", "K=워크벤치(프로그램 등 개발물), W=커스터마이징(설정값), T=전송 대상 없음"),
"AS4DATE": ("변경일", "요청 마지막 변경(릴리즈) 날짜"),
"AS4TIME": ("변경 시각", "요청 마지막 변경(릴리즈) 시각"),
"PGMID": ("프로그램 ID", "R3TR=오브젝트 전체, LIMU=오브젝트 일부(메서드/소스 등), CORR=전송 관리 항목"),
# 버전
"OBJNAME": ("오브젝트 이름", "버전 관리 대상 이름"),
"OBJTYPE": ("버전 오브젝트 유형", "REPS=프로그램/Include 소스, CLSD=클래스 정의, METH=메서드, FUNC=함수"),
"VERSNO": ("버전 번호", "00000=활성(현재) 버전, 그 외는 과거 버전. 클수록 최신"),
"KORRNUM": ("전송 요청", "이 버전을 만든 전송 요청 번호"),
"DATUM": ("버전 생성일", "버전이 저장된 날짜"),
"ZEIT": ("버전 생성 시각", "버전이 저장된 시각"),
# 사용처
"MASTER": ("사용/메인 프로그램", "where-used: 해당 오브젝트를 사용하는 프로그램. GET_OBJECT_TYPE: Include 를 포함하는 컴파일 단위(함수그룹이면 SAPL<그룹>, 클래스면 클래스 풀)"),
}
# ---------------------------------------------------------------- 코드값 해석
VALUE_MAPS = {
"TYPE": {"S": "성공", "W": "경고", "E": "오류", "X": "호출 실패"},
"SPRAS": {"3": "한국어", "E": "영어", "D": "독일어", "J": "일본어", "1": "중국어(간체)", "": "(텍스트 없음)"},
"SPRSL": {"3": "한국어", "E": "영어", "D": "독일어", "J": "일본어", "1": "중국어(간체)", "": "(텍스트 없음)"},
"LANG_PRIO": {"1": "로그인 언어", "2": "영어", "3": "독일어", "9": "기타"},
"SUBC": {"1": "실행 프로그램(리포트)", "M": "모듈 풀(화면 프로그램)", "I": "Include", "F": "함수 그룹",
"K": "클래스 풀", "J": "인터페이스 풀", "S": "서브루틴 풀", "T": "타입 풀", "X": "XSLT"},
"OBJECT": {
"PROG": "프로그램", "FUGR": "함수 그룹", "CLAS": "클래스", "INTF": "인터페이스",
"TABL": "테이블/구조", "DTEL": "데이터엘리먼트", "DOMA": "도메인", "TTYP": "테이블 타입",
"VIEW": "", "DDLS": "CDS 뷰", "SHLP": "검색 도움말", "ENQU": "잠금 오브젝트",
"TRAN": "트랜잭션 코드", "MSAG": "메시지 클래스", "DEVC": "패키지", "XSLT": "XSLT 변환",
"SXCI": "BAdI 구현", "ENHO": "인핸스먼트 구현", "ENHS": "인핸스먼트 스팟", "WDYN": "Web Dynpro",
"SFPF": "Adobe 폼", "SFPI": "Adobe 인터페이스", "SSFO": "Smart Form", "FORM": "SAPscript 폼",
"SMIM": "MIME 오브젝트", "NROB": "번호 범위", "TOBJ": "유지보수 뷰", "PARA": "SET/GET 파라미터",
"IWSV": "OData 서비스", "IWPR": "OData 프로젝트", "SRVD": "서비스 정의", "SRVB": "서비스 바인딩",
"BDEF": "비헤이비어 정의", "DCLS": "접근 제어(DCL)", "RELE": "릴리즈 마커", "TABU": "테이블 데이터",
"VDAT": "뷰 데이터", "CDAT": "커스터마이징 데이터", "TDAT": "테이블 데이터(그룹)",
"REPS": "프로그램 소스", "METH": "메서드", "FUNC": "함수 모듈", "DYNP": "화면", "CUAD": "GUI 상태",
"CINC": "클래스 로컬 include", "CPUB": "클래스 public 섹션", "CPRI": "클래스 private 섹션",
"CPRO": "클래스 protected 섹션", "CLSD": "클래스 정의", "REPT": "프로그램 텍스트",
"TABD": "테이블 정의", "DTED": "데이터엘리먼트 정의", "DOMD": "도메인 정의", "MESS": "메시지",
},
"PGMID": {"R3TR": "오브젝트 전체", "LIMU": "오브젝트 일부", "CORR": "전송 관리 항목"},
"TRFUNCTION": {"K": "워크벤치 요청", "W": "커스터마이징 요청", "T": "대상 없는 전송", "C": "재배치(패키지 변경 없음)",
"O": "재배치(패키지 변경)", "E": "재배치(패키지)", "S": "개발/수정 태스크", "R": "리페어",
"X": "미분류 태스크", "Q": "커스터마이징 태스크", "L": "삭제 전송", "D": "패치", "P": "사전 준비"},
"TABCLASS": {"TRANSP": "투명 테이블(실제 DB)", "INTTAB": "구조(데이터 없음)", "VIEW": "", "CLUSTER": "클러스터 테이블",
"POOL": "풀 테이블", "APPEND": "어펜드 구조"},
"DATATYPE": {"CHAR": "문자", "NUMC": "숫자 문자열", "DATS": "날짜(YYYYMMDD)", "TIMS": "시간(HHMMSS)", "DEC": "소수(packed)",
"CURR": "통화 금액", "CUKY": "통화 키", "QUAN": "수량", "UNIT": "단위", "INT1": "1바이트 정수", "INT2": "2바이트 정수",
"INT4": "4바이트 정수", "INT8": "8바이트 정수", "FLTP": "부동소수", "RAW": "바이너리", "LRAW": "긴 바이너리",
"STRG": "문자열", "SSTR": "짧은 문자열", "RSTR": "바이너리 문자열", "CLNT": "클라이언트", "LANG": "언어 키",
"LCHR": "긴 문자", "ACCP": "회계 기간(YYYYMM)", "PREC": "정밀도", "DF16_DEC": "10진 부동소수(16)", "DF34_DEC": "10진 부동소수(34)",
"D16D": "10진 부동소수(16)", "D34D": "10진 부동소수(34)", "D16R": "10진 부동소수(16,raw)", "D34R": "10진 부동소수(34,raw)",
"DATN": "날짜(네이티브)", "TIMN": "시간(네이티브)", "UTCL": "UTC 타임스탬프", "GEOM_EWKB": "지오메트리"},
"KEYFLAG": {"X": "", "": ""},
"IS_CUSTOM": {"X": "고객 개발", "": "SAP 표준"},
"OPTIONAL": {"X": "선택", "": "필수"},
"REFERENCE": {"X": "참조", "": ""},
"LOWERCASE": {"X": "허용", "": "대문자 변환"},
"VALEXI": {"X": "있음", "": "없음"},
"OBJTYPE": {"REPS": "프로그램/Include 소스", "CLSD": "클래스 정의", "METH": "메서드", "FUNC": "함수 모듈", "DYNP": "화면",
"TABD": "테이블 정의", "DTED": "데이터엘리먼트", "DOMD": "도메인", "CINC": "클래스 로컬 include", "CUAD": "GUI 상태",
"REPT": "프로그램 텍스트", "CPUB": "public 섹션", "CPRI": "private 섹션", "CPRO": "protected 섹션"},
"CONVEXIT": {"ALPHA": "앞자리 0 채움/제거", "": "없음"},
}
# 결과 셀 클릭 -> 다른 API 로 이어가기 (필드명 -> [메서드, 파라미터])
LINKS = {
"DEVCLASS": ["GET_OBJECT_LIST_BY_PACKAGE", "IV_PACKAGE"],
"PARENTCL": ["GET_OBJECT_LIST_BY_PACKAGE", "IV_PACKAGE"],
"FUNCNAME": ["GET_FUNCTION_DETAIL", "IV_FUNCTION"],
"TABNAME": ["GET_TABLE_FIELDS", "IV_TABLE"],
"CHECKTABLE": ["GET_TABLE_FIELDS", "IV_TABLE"],
"ENTITYTAB": ["GET_TABLE_FIELDS", "IV_TABLE"],
"ROLLNAME": ["GET_TYPE_INFO", "IV_TYPE_NAME"],
"DOMNAME": ["GET_TYPE_INFO", "IV_TYPE_NAME"],
"DBFIELD": ["GET_TYPE_INFO", "IV_TYPE_NAME"],
"TRKORR": ["GET_CTS_OBJECT_LIST", "IV_TRKORR"],
"KORRNUM": ["GET_CTS_OBJECT_LIST", "IV_TRKORR"],
"TCODE": ["GET_TCODE_INFO", "IV_TCODE"],
"PGMNA": ["GET_PROGRAM_SOURCE", "IV_PROGRAM"],
"MASTER": ["GET_PROGRAM_SOURCE", "IV_PROGRAM"],
"INCL_NAME": ["GET_PROGRAM_SOURCE", "IV_PROGRAM"],
"PROGRAM": ["GET_VERSION_LIST", "IV_OBJNAME"],
# OBJ_NAME 은 OBJECT 유형에 따라 다름 -> 프론트에서 OBJECT 값 보고 분기 (LINKS_BY_OBJECT)
}
LINKS_BY_OBJECT = {
"PROG": ["GET_PROGRAM_SOURCE", "IV_PROGRAM"],
"REPS": ["GET_PROGRAM_SOURCE", "IV_PROGRAM"],
"FUGR": ["GET_FUNCTION_LIST", "IV_FUNC_GROUP"],
"TABL": ["GET_TABLE_FIELDS", "IV_TABLE"],
"DTEL": ["GET_TYPE_INFO", "IV_TYPE_NAME"],
"DOMA": ["GET_TYPE_INFO", "IV_TYPE_NAME"],
"TRAN": ["GET_TCODE_INFO", "IV_TCODE"],
"CLAS": ["GET_VERSION_LIST", "IV_OBJNAME"],
}
MAX_ROWS = {"name": "IV_MAX_ROWS", "label": "최대 건수", "type": "number",
"desc": "생략/0 이면 전건 (안전 상한 50,000). 지정하면 그 건수까지만. 잘리면 TYPE=W + '(전체 M건)' + RETURN.TOTAL_ROWS=M (2026-09-04 상한 제거)"}
# ---------------------------------------------------------------- 메서드
METHODS = [
# ------------------------------------------------ 1
{
"name": "GET_PACKAGE_LIST", "title": "패키지 목록", "group": "1. 탐색 (어디에 뭐가 있나)",
"summary": "고객 개발(Z/Y) 패키지 목록을 가져온다. 패키지는 개발물을 담는 폴더 같은 것이라, 시스템 탐색의 시작점이다.",
"when": "처음 시스템을 볼 때, 또는 '영업/재무 관련 개발물이 어디 있지?' 를 설명 텍스트로 찾을 때.",
"params": [
{"name": "IV_PATTERN", "label": "패키지명 패턴", "type": "string", "placeholder": "ZFI*",
"desc": "* 와일드카드 사용. 생략하면 Z* 와 Y* 전부"},
{"name": "IV_SEARCH_TEXT", "label": "설명 검색어", "type": "string", "placeholder": "API",
"desc": "패키지 설명(CTEXT)에 이 문자열이 포함된 것만. 대소문자 구분"},
MAX_ROWS,
],
"samples": [
{"label": "전체 CBO 패키지 (기본, 전건)", "params": {}, "note": "이 시스템은 237개. 상한 없이 전건"},
{"label": "이름 패턴 ZFI*", "params": {"IV_PATTERN": "ZFI*"}},
{"label": "설명에 'API' 포함", "params": {"IV_SEARCH_TEXT": "API"}},
{"label": "상한 5건 → W 응답", "params": {"IV_MAX_ROWS": 5}, "note": "RETURN.TYPE=W, 메시지에 전체 건수, TOTAL_ROWS=237"},
],
},
# ------------------------------------------------ 3
{
"name": "GET_OBJECT_LIST_BY_PACKAGE", "title": "패키지 안의 오브젝트", "group": "1. 탐색 (어디에 뭐가 있나)",
"summary": "한 패키지에 들어 있는 모든 개발 오브젝트(프로그램, 클래스, 테이블, 함수그룹, 트랜잭션…)를 유형별로 나열한다.",
"when": "패키지를 골랐고 그 안에 뭐가 있는지 볼 때. OBJECT 컬럼 값으로 다음에 부를 API 가 정해진다.",
"params": [
{"name": "IV_PACKAGE", "label": "패키지", "type": "string", "required": True, "placeholder": "ZFI01",
"desc": "GET_PACKAGE_LIST 의 DEVCLASS 값"},
{"name": "IV_OBJ_TYPE", "label": "오브젝트 유형", "type": "string", "placeholder": "PROG",
"desc": "PROG/FUGR/CLAS/TABL/DTEL/DOMA/TRAN/VIEW … 생략 시 전체"},
MAX_ROWS,
],
"samples": [
{"label": "ZFI01 전체 (2,874건)", "params": {"IV_PACKAGE": "ZFI01", "IV_MAX_ROWS": 5000},
"note": "PROG 1,132 / DTEL 832 / TABL 428 / TRAN 201 / DOMA 128 ... 기본 상한(2000)이면 W"},
{"label": "ZFI01 테이블만 (428건)", "params": {"IV_PACKAGE": "ZFI01", "IV_OBJ_TYPE": "TABL"}},
{"label": "ZFI01 함수 그룹만 (14건)", "params": {"IV_PACKAGE": "ZFI01", "IV_OBJ_TYPE": "FUGR"}},
{"label": "ZFI01 프로그램 전건 (1,132건)", "params": {"IV_PACKAGE": "ZFI01", "IV_OBJ_TYPE": "PROG"},
"note": "Include(SUBC=I) 946건이 포함돼 GET_PROGRAM_LIST(177건)보다 많다"},
{"label": "ZFI01 프로그램 상한 500 → W", "params": {"IV_PACKAGE": "ZFI01", "IV_OBJ_TYPE": "PROG", "IV_MAX_ROWS": 500},
"note": "TYPE=W, 메시지 '(전체 1132건)', TOTAL_ROWS=1132"},
{"label": "필수값 누락 → E", "params": {}, "note": "IV_PACKAGE 없이 호출하면 오류 응답"},
],
"notes": ["2026-09-04 수정: 상한에서 잘려도 TYPE=S 였던 결함 → W + '(전체 M건)' + TOTAL_ROWS. 이어서 기본 상한 자체를 없앴다 (생략 시 전건).",
"정렬이 OBJECT 알파벳순이라 IV_MAX_ROWS 로 잘리면 뒤쪽 유형(TABL, TRAN …)이 통째로 빠진다. 전체가 필요하면 IV_MAX_ROWS 를 생략.",
"PROG 에는 Include 프로그램과 TADIR 항목만 남은 삭제 프로그램도 포함된다 (GET_PROGRAM_LIST 는 기본 1+M 만)."],
},
# ------------------------------------------------ 2
{
"name": "GET_PROGRAM_LIST", "title": "프로그램 목록", "group": "2. 프로그램",
"summary": "패키지 또는 이름 패턴으로 ABAP 프로그램을 찾는다. 제목, 유형, 최종 변경자/일자를 함께 준다.",
"when": "특정 패키지의 프로그램을 훑거나, 'ZSD*' 처럼 이름 규칙으로 찾을 때. 기본은 실행 프로그램(1)과 화면 프로그램(M)만.",
"params": [
{"name": "IV_PACKAGE", "label": "패키지", "type": "string", "placeholder": "ZFI01", "desc": "패키지로 필터"},
{"name": "IV_PATTERN", "label": "프로그램명 패턴", "type": "string", "placeholder": "ZFI1*", "desc": "* 와일드카드. 패키지와 패턴 둘 다 없으면 빈 결과"},
{"name": "IV_SUBC", "label": "프로그램 유형", "type": "string", "placeholder": "1",
"desc": "1=실행 프로그램, M=모듈 풀, I=Include, F=함수그룹, K=클래스 풀. 생략 시 1+M"},
MAX_ROWS,
],
"samples": [
{"label": "패키지 ZFI01 (177건)", "params": {"IV_PACKAGE": "ZFI01"}},
{"label": "이름 패턴 Z* (10건)", "params": {"IV_PATTERN": "Z*", "IV_MAX_ROWS": 10}},
{"label": "ZFI01 의 Include 만 (946건)", "params": {"IV_PACKAGE": "ZFI01", "IV_SUBC": "I"}},
{"label": "필터 없음 → 안내 메시지", "params": {}, "note": "전건 조회 방지: S + 메시지, 결과 0건"},
],
},
# ------------------------------------------------ 4
{
"name": "GET_PROGRAM_SOURCE", "title": "프로그램 소스", "group": "2. 프로그램",
"summary": "프로그램의 ABAP 소스 전문을 가져온다. 옵션으로 Include 소스, 화면 흐름 로직, 연결된 트랜잭션 코드까지.",
"when": "코드를 읽거나 분석할 때. 모듈 풀(SAPM*) 은 실제 로직이 Include 에 있으므로 IV_WITH_INCLUDE=X 가 사실상 필수.",
"params": [
{"name": "IV_PROGRAM", "label": "프로그램", "type": "string", "required": True, "placeholder": "SAPMZSFT0"},
{"name": "IV_WITH_INCLUDE", "label": "Include 포함", "type": "flag", "desc": "X 면 INCLUDE_LIST 에 각 Include 소스 포함"},
{"name": "IV_WITH_SCREEN", "label": "화면 포함", "type": "flag", "desc": "X 면 SCREEN_LIST 에 화면 흐름 로직 포함"},
],
"samples": [
{"label": "모듈 풀 + Include + 화면 (SAPMZSFT0)", "params": {"IV_PROGRAM": "SAPMZSFT0", "IV_WITH_INCLUDE": "X", "IV_WITH_SCREEN": "X"},
"note": "근무 달력 유지보수. Include 1개, 화면 2개, 트랜잭션 ZSCAL"},
{"label": "리포트 소스만 (ZFI1000 계정별잔액조회)", "params": {"IV_PROGRAM": "ZFI1000"}},
{"label": "SAP 표준 (SAPMV45A, 화면 318개)", "params": {"IV_PROGRAM": "SAPMV45A", "IV_WITH_SCREEN": "X"}, "note": "응답 큼"},
{"label": "없는 프로그램 → E", "params": {"IV_PROGRAM": "ZZZ_NOT_EXIST"}},
],
"notes": ["Include 목록은 D010INC 기준이라 전이적으로 포함된 include 까지 전부 온다 (표준 SAPMV45A 는 1800개 이상). 클래스/Enhancement 시스템 include 는 서버가 걸러낸다 (2026-09-04 수정. 그 전엔 'CL_...==CU' 류가 섞였음).",
"소스에 제어문자(0x0C 등)가 있으면 원문 XML 이 규격 위반 → 이 서버가 파싱 전 제거함."],
},
# ------------------------------------------------ 5
{
"name": "GET_FUNCTION_LIST", "title": "함수 모듈 목록", "group": "3. 함수 모듈",
"summary": "함수 그룹 또는 이름 패턴으로 함수 모듈(재사용 API 단위)을 찾는다.",
"when": "패키지 오브젝트 목록에서 FUGR 을 봤을 때 그 안의 함수를 볼 때, 또는 'BAPI_USER*' 처럼 이름으로 찾을 때.",
"params": [
{"name": "IV_FUNC_GROUP", "label": "함수 그룹", "type": "string", "placeholder": "ZFG_FI02", "desc": "GET_OBJECT_LIST_BY_PACKAGE 의 FUGR 이름"},
{"name": "IV_PATTERN", "label": "함수명 패턴", "type": "string", "placeholder": "BAPI_USER_GET*", "desc": "* 와일드카드. 그룹과 패턴 둘 다 없으면 빈 결과"},
MAX_ROWS,
],
"samples": [
{"label": "함수 그룹 ZFG_FI02 (14건, 전표/BP 처리)", "params": {"IV_FUNC_GROUP": "ZFG_FI02"}},
{"label": "함수 그룹 ZLEASE01", "params": {"IV_FUNC_GROUP": "ZLEASE01"}},
{"label": "이름 패턴 ZFIBP_* (고객 함수)", "params": {"IV_PATTERN": "ZFIBP_*"}},
{"label": "이름 패턴 BAPI_USER_GET*", "params": {"IV_PATTERN": "BAPI_USER_GET*"}},
{"label": "필터 없음 → 안내 메시지", "params": {}},
],
},
# ------------------------------------------------ 6
{
"name": "GET_FUNCTION_DETAIL", "title": "함수 모듈 상세", "group": "3. 함수 모듈",
"summary": "함수 하나의 본문 소스(FUNC_SOURCE), 인터페이스(입력/출력/변경/테이블 파라미터, 예외), 함수 그룹의 TOP/FORM include 소스를 준다.",
"when": "함수를 호출하거나 그 동작을 이해해야 할 때. 파라미터 표만 봐도 시그니처를 알 수 있다.",
"params": [
{"name": "IV_FUNCTION", "label": "함수 모듈", "type": "string", "required": True, "placeholder": "BAPI_USER_GET_DETAIL"},
],
"samples": [
{"label": "SAP 표준 BAPI_USER_GET_DETAIL", "params": {"IV_FUNCTION": "BAPI_USER_GET_DETAIL"}},
{"label": "고객 함수 ZFI_CHECK_STCD2 (사업자번호 체크)", "params": {"IV_FUNCTION": "ZFI_CHECK_STCD2"}, "note": "소스 출처 INCLUDE LZFG_FI02U01"},
{"label": "없는 함수 → E", "params": {"IV_FUNCTION": "Z_NOT_EXIST_FM"}},
],
"notes": ["FUNC_SOURCE 는 함수 Include(L<그룹>U##)를 통째로 읽은 것이라 FUNCTION ~ ENDFUNCTION 과 긴 줄(72자 초과)이 그대로 온다. RETURN.MESSAGE 에 출처가 찍힌다.",
"2026-09-04 수정 전에는 항상 빈값이었다 (RPY_FUNCTIONMODULE_READ 의 SOURCE 테이블은 이 시스템에서 채워지지 않고 NEW_SOURCE 파라미터도 없음).",
"파라미터 목록의 행 태그는 <item> 이 아니라 <RSIMP>/<RSEXP>/<RSCHA>/<RSTBL>/<RSEXC> 다. 이 서버의 파서는 이를 목록으로 처리한다 (직접 파싱할 때 주의)."],
},
# ------------------------------------------------ 7
{
"name": "GET_TABLE_LIST", "title": "테이블 목록", "group": "4. 테이블 / 타입",
"summary": "이름 패턴 또는 설명 검색어로 DB 테이블/구조를 찾는다.",
"when": "'고객' 관련 테이블이 뭐가 있는지 설명으로 찾거나, Z 테이블 전체를 훑을 때.",
"params": [
{"name": "IV_PATTERN", "label": "테이블명 패턴", "type": "string", "placeholder": "ZFIT*"},
{"name": "IV_SEARCH_TEXT", "label": "설명 검색어", "type": "string", "placeholder": "고객", "desc": "DDTEXT 부분 일치. 로그인 언어(한국어)/영어/독일어 텍스트 대상"},
{"name": "IV_CUSTOM_ONLY", "label": "고객 개발만", "type": "flag", "desc": "X 면 Z*/Y* 테이블만"},
MAX_ROWS,
],
"samples": [
{"label": "Z 테이블 50건", "params": {"IV_PATTERN": "Z*", "IV_CUSTOM_ONLY": "X", "IV_MAX_ROWS": 50}},
{"label": "설명에 '고객'", "params": {"IV_SEARCH_TEXT": "고객", "IV_MAX_ROWS": 20}},
{"label": "이름 ZFIT* (737건)", "params": {"IV_PATTERN": "ZFIT*"}},
{"label": "필터 없음 → 안내 메시지", "params": {}},
],
},
# ------------------------------------------------ 8
{
"name": "GET_TABLE_FIELDS", "title": "테이블 필드(컬럼)", "group": "4. 테이블 / 타입",
"summary": "테이블의 컬럼 목록: 키 여부, 타입/길이, 데이터엘리먼트, 도메인, 체크 테이블, 한국어 설명·라벨.",
"when": "테이블 구조를 알아야 할 때(스키마 문서 대용). ROLLNAME 을 클릭하면 타입 상세로 이어진다.",
"params": [
{"name": "IV_TABLE", "label": "테이블", "type": "string", "required": True, "placeholder": "ZFIT0000"},
],
"samples": [
{"label": "고객 테이블 ZFIT0000 (권한별 유저ID 관리)", "params": {"IV_TABLE": "ZFIT0000"}},
{"label": "SAP 표준 MARA (자재 마스터, 304컬럼)", "params": {"IV_TABLE": "MARA"}},
{"label": "T000 (클라이언트)", "params": {"IV_TABLE": "T000"}},
{"label": "없는 테이블 → E", "params": {"IV_TABLE": "ZZZ_NOPE"}},
],
},
# ------------------------------------------------ 9
{
"name": "GET_TYPE_INFO", "title": "타입(데이터엘리먼트/도메인) 정보", "group": "4. 테이블 / 타입",
"summary": "데이터엘리먼트 또는 도메인 이름을 주면 타입·길이·라벨·변환 루틴·허용값(고정값) 목록을 준다.",
"when": "필드 값이 무슨 뜻인지, 어떤 값이 들어올 수 있는지 알고 싶을 때. 예: MTART 의 허용값은 T134 테이블, XFELD 는 X/공백.",
"params": [
{"name": "IV_TYPE_NAME", "label": "데이터엘리먼트 또는 도메인", "type": "string", "required": True, "placeholder": "BUKRS",
"desc": "먼저 데이터엘리먼트로 찾고, 없으면 도메인으로 간주"},
],
"samples": [
{"label": "BUKRS (회사 코드)", "params": {"IV_TYPE_NAME": "BUKRS"}},
{"label": "XFELD (체크박스, 고정값 2개)", "params": {"IV_TYPE_NAME": "XFELD"}},
{"label": "MTART (자재 유형, 값 테이블 T134)", "params": {"IV_TYPE_NAME": "MTART"}},
{"label": "고객 타입 ZE_AUTHCODE (권한관리코드, 고정값 7개)", "params": {"IV_TYPE_NAME": "ZE_AUTHCODE"}},
{"label": "없는 타입 → E", "params": {"IV_TYPE_NAME": "ZZZ_NOPE"}},
],
},
# ------------------------------------------------ 10
{
"name": "GET_FIELD_LIST_BY_TEXT", "title": "업무 용어로 필드 역검색", "group": "4. 테이블 / 타입",
"summary": "'회사코드' 같은 업무 용어로 데이터엘리먼트를 찾고, 그 엘리먼트를 쓰는 테이블·필드까지 같이 준다.",
"when": "테이블/필드 이름을 전혀 모를 때. 자연어 → 기술 이름 매핑의 출발점.",
"params": [
{"name": "IV_SEARCH_TEXT", "label": "검색어", "type": "string", "required": True, "placeholder": "회사코드"},
{"name": "IV_CUSTOM_ONLY", "label": "고객 개발만", "type": "flag", "desc": "X 면 Z/Y 엘리먼트와 Z/Y 테이블만"},
MAX_ROWS,
],
"samples": [
{"label": "'회사코드' 고객 개발만", "params": {"IV_SEARCH_TEXT": "회사코드", "IV_CUSTOM_ONLY": "X", "IV_MAX_ROWS": 10}},
{"label": "'레코드생성일' 전체", "params": {"IV_SEARCH_TEXT": "레코드생성일", "IV_MAX_ROWS": 10}},
{"label": "'자재' 전체 20건", "params": {"IV_SEARCH_TEXT": "자재", "IV_MAX_ROWS": 20}},
{"label": "'회사코드' 전체 10건 (BUKRS 계열은 사용 테이블 수천 건)", "params": {"IV_SEARCH_TEXT": "회사코드", "IV_MAX_ROWS": 10},
"note": "사용 테이블은 제한 없이 전부 온다 (2026-09-04 20건 상한 제거)"},
{"label": "일치 없음 → S, 0건", "params": {"IV_SEARCH_TEXT": "zzqqxx없는용어"}, "note": "2026-09-04 수정 전에는 응답 본문이 비어 있었음"},
{"label": "필수값 누락 → E", "params": {}},
],
"notes": ["USED_TABLES 는 엘리먼트당 제한 없이 전부 온다 (2026-09-04 20건 고정 상한 제거). 사용 테이블 총량이 안전 상한 50,000 을 넘으면 조회를 멈추고 TYPE=W + 안내 메시지 (그 뒤 후보의 USED_TABLES 는 빈값). 검색어를 좁히거나 IV_CUSTOM_ONLY=X, IV_MAX_ROWS 로 줄일 것.",
"2026-09-04 수정: 후보 0건이면 CHECK 로 빠져 응답 본문이 0바이트였던 결함. 지금은 빈 RESULT 를 정상 XML 로 돌려준다."],
},
# ------------------------------------------------ 11
{
"name": "GET_CTS_LIST", "title": "전송 요청(CTS) 목록", "group": "5. 변경 이력 (CTS / 버전)",
"summary": "기간 내 릴리즈된 전송 요청(Transport Request) 목록. 전송 요청은 '변경 사항 묶음' 으로, 개발→운영 이관 단위다.",
"when": "최근 누가 무엇을 바꿨는지 볼 때. 결과의 TRKORR 로 GET_CTS_OBJECT_LIST 를 부르면 바뀐 오브젝트가 나온다.",
"params": [
{"name": "IV_DATE_FROM", "label": "시작일", "type": "date", "required": True, "placeholder": "2025-01-01", "desc": "반드시 YYYY-MM-DD (YYYYMMDD 는 인식 못함)"},
{"name": "IV_DATE_TO", "label": "종료일", "type": "date", "required": True, "placeholder": "2026-12-31"},
{"name": "IV_USER", "label": "소유자", "type": "string", "placeholder": "PWC322063", "desc": "요청 소유자 사용자 ID"},
{"name": "IV_FUNCTION", "label": "요청 유형", "type": "string", "placeholder": "K", "desc": "K=워크벤치, W=커스터마이징. 생략 시 K+W"},
MAX_ROWS,
],
"samples": [
{"label": "최근 1년, 20건", "params": {"IV_DATE_FROM": "2025-09-03", "IV_DATE_TO": "2026-09-03", "IV_MAX_ROWS": 20}},
{"label": "2020~ 워크벤치만 5건", "params": {"IV_DATE_FROM": "2020-01-01", "IV_DATE_TO": "2026-12-31", "IV_FUNCTION": "K", "IV_MAX_ROWS": 5}},
{"label": "잘못된 날짜 형식 → E", "params": {"IV_DATE_FROM": "20200101", "IV_DATE_TO": "20261231"}, "note": "YYYYMMDD 는 빈 값으로 취급됨"},
],
"notes": ["릴리즈 완료(TRSTATUS=R) 된 상위 요청만. 하위 태스크는 제외."],
},
# ------------------------------------------------ 12
{
"name": "GET_CTS_OBJECT_LIST", "title": "전송 요청의 변경 오브젝트", "group": "5. 변경 이력 (CTS / 버전)",
"summary": "전송 요청(과 그 하위 태스크)에 담긴 오브젝트 목록.",
"when": "특정 배포에 무엇이 포함됐는지 확인할 때.",
"params": [
{"name": "IV_TRKORR", "label": "전송 요청 번호", "type": "string", "required": True, "placeholder": "EEDK9A1KSP"},
],
"samples": [
{"label": "작은 요청 EEDK9A1KSP (3건)", "params": {"IV_TRKORR": "EEDK9A1KSP"}},
{"label": "큰 요청 S4HK961147 (1000건+)", "params": {"IV_TRKORR": "S4HK961147"}},
{"label": "필수값 누락 → E", "params": {}},
],
},
# ------------------------------------------------ 13
{
"name": "GET_VERSION_LIST", "title": "오브젝트 버전 이력", "group": "5. 변경 이력 (CTS / 버전)",
"summary": "오브젝트의 저장된 버전 목록(버전 번호, 전송 요청, 작성자, 일시). 전송 시점마다 버전이 남는다.",
"when": "언제 누가 바꿨는지 추적할 때. 버전이 0건이면 한 번도 전송된 적 없는 오브젝트.",
"params": [
{"name": "IV_OBJNAME", "label": "오브젝트 이름", "type": "string", "required": True, "placeholder": "ZCL_FI_LS_ALV_GRID"},
{"name": "IV_OBJTYPE", "label": "버전 오브젝트 유형", "type": "string", "required": True, "placeholder": "CLSD",
"desc": "REPS=프로그램/Include, CLSD=클래스 정의, METH=메서드, FUNC=함수, TABD=테이블 정의. 함수그룹 TOP 은 L<그룹>TOP + REPS"},
],
"samples": [
{"label": "클래스 ZCL_FI_LS_ALV_GRID (6버전)", "params": {"IV_OBJNAME": "ZCL_FI_LS_ALV_GRID", "IV_OBJTYPE": "CLSD"}},
{"label": "함수그룹 TOP LZLEASE01TOP (6버전)", "params": {"IV_OBJNAME": "LZLEASE01TOP", "IV_OBJTYPE": "REPS"}},
{"label": "테이블 정의 ZRPFXT0010 (TABD, 8버전)", "params": {"IV_OBJNAME": "ZRPFXT0010", "IV_OBJTYPE": "TABD"},
"note": "테이블도 버전 이력은 나온다. 단 GET_VERSION_SOURCE 는 TABD 를 지원하지 않아 정의 diff 는 불가"},
{"label": "버전 이력 없는 프로그램 ZFI1000 (0건)", "params": {"IV_OBJNAME": "ZFI1000", "IV_OBJTYPE": "REPS"}, "note": "ZFI01 은 이관 패키지라 버전 이력이 없다"},
{"label": "필수값 누락 → E", "params": {}},
],
},
# ------------------------------------------------ 14
{
"name": "GET_VERSION_SOURCE", "title": "특정 버전의 소스", "group": "5. 변경 이력 (CTS / 버전)",
"summary": "버전 번호를 지정해 그 시점의 소스를 가져온다. 두 버전을 받아 diff 하면 변경 내용을 알 수 있다.",
"when": "변경 전/후 비교. GET_VERSION_LIST 로 버전 번호를 고른 뒤 두 버전을 받아 diff 한다.",
"params": [
{"name": "IV_OBJNAME", "label": "오브젝트 이름", "type": "string", "required": True, "placeholder": "LZLEASE01TOP"},
{"name": "IV_OBJTYPE", "label": "버전 오브젝트 유형", "type": "string", "required": True, "placeholder": "REPS"},
{"name": "IV_VERSNO", "label": "버전 번호", "type": "string", "placeholder": "00000", "desc": "생략/00000 = 활성(현재) 소스. 그 외 = 과거 버전"},
],
"samples": [
{"label": "활성 버전 LZLEASE01TOP", "params": {"IV_OBJNAME": "LZLEASE01TOP", "IV_OBJTYPE": "REPS"}},
{"label": "활성 버전 ZFI1000", "params": {"IV_OBJNAME": "ZFI1000", "IV_OBJTYPE": "REPS", "IV_VERSNO": "00000"}},
{"label": "과거 버전 LZLEASE01TOP 00001", "params": {"IV_OBJNAME": "LZLEASE01TOP", "IV_OBJTYPE": "REPS", "IV_VERSNO": "00001"}},
{"label": "없는 버전 → E", "params": {"IV_OBJNAME": "LZLEASE01TOP", "IV_OBJTYPE": "REPS", "IV_VERSNO": "99999"}},
{"label": "TABD 과거 버전 → E (테이블 정의는 미지원)", "params": {"IV_OBJNAME": "ZRPFXT0010", "IV_OBJTYPE": "TABD", "IV_VERSNO": "00001"},
"note": "GET_VERSION_LIST 에는 8버전이 있지만 소스 조회는 REPS 만 지원. 활성(00000)도 '소스를 읽을 수 없습니다' E"},
{"label": "CLSD 과거 버전 → E (REPS 만 지원)", "params": {"IV_OBJNAME": "ZCL_ZAA_AGENT_API", "IV_OBJTYPE": "CLSD", "IV_VERSNO": "00001"}},
],
"notes": ["과거 버전은 표준 함수 SVRS_GET_REPS_FROM_OBJECT 로 버전 DB 에서 읽는다 (2026-09-04 수정. 그 전엔 없는 함수 SVRS2_GET_VERSION_REPOS_46 을 불러 HTTP 500).",
"과거 버전은 IV_OBJTYPE=REPS(프로그램/Include) 만 지원. 클래스는 메서드 Include 이름(ZCL_X=====CM001 형태)으로 조회.",
"활성 버전은 READ REPORT 로 읽으므로 CLSD(클래스) 타입은 '소스를 읽을 수 없습니다' 가 정상.",
"함수 그룹 TOP include 는 내용이 안 바뀌어도 전송 때마다 버전이 생겨 여러 버전이 같은 소스일 수 있다."],
},
# ------------------------------------------------ 15
{
"name": "GET_WHERE_USED_LIST", "title": "사용처 역추적 (Where-Used)", "group": "6. 관계 추적",
"summary": "테이블/데이터엘리먼트/함수/프로그램을 어떤 프로그램들이 사용하는지 찾는다.",
"when": "영향도 분석: '이 테이블 바꾸면 어디가 깨지나'. 표준 오브젝트는 결과가 많으니 IV_MAX_ROWS 를 작게.",
"params": [
{"name": "IV_OBJ_TYPE", "label": "오브젝트 유형", "type": "string", "required": True, "placeholder": "TABL",
"desc": "검증됨: TABL(테이블/구조), DE(데이터엘리먼트), FUNC(함수), PROG(프로그램). 별칭 DS/STRU, DTEL/DD 도 동작. TB/TA 는 오류(rc=7)"},
{"name": "IV_OBJ_NAME", "label": "오브젝트 이름", "type": "string", "required": True, "placeholder": "ZFIT0000"},
MAX_ROWS,
],
"samples": [
{"label": "고객 테이블 ZFIT0000 사용처 (7건)", "params": {"IV_OBJ_TYPE": "TABL", "IV_OBJ_NAME": "ZFIT0000"}},
{"label": "테이블 T000 사용처 (5건)", "params": {"IV_OBJ_TYPE": "TABL", "IV_OBJ_NAME": "T000", "IV_MAX_ROWS": 5}},
{"label": "데이터엘리먼트 BUKRS (5건)", "params": {"IV_OBJ_TYPE": "DE", "IV_OBJ_NAME": "BUKRS", "IV_MAX_ROWS": 5}},
{"label": "함수 ZFI_CHECK_STCD2 (1건)", "params": {"IV_OBJ_TYPE": "FUNC", "IV_OBJ_NAME": "ZFI_CHECK_STCD2"}},
{"label": "잘못된 유형 TB → E (rc=7)", "params": {"IV_OBJ_TYPE": "TB", "IV_OBJ_NAME": "T000"}},
],
"notes": ["표준 오브젝트(MARA, BUKRS 등)는 사용처가 수천 건이라 느릴 수 있음. IV_MAX_ROWS 는 잘라주기만 하고 조회 자체를 줄이진 않음."],
},
# ------------------------------------------------ 16
{
"name": "GET_TCODE_INFO", "title": "트랜잭션 코드 ↔ 프로그램", "group": "6. 관계 추적",
"summary": "트랜잭션 코드(사용자가 SAP 에서 치는 명령어)로 실행 프로그램을 찾거나, 프로그램으로 트랜잭션 코드를 찾는다.",
"when": "사용자가 'VA01 화면' 이라고 말할 때 그 뒤의 프로그램을 찾거나, 프로그램이 어떤 메뉴로 실행되는지 볼 때.",
"params": [
{"name": "IV_TCODE", "label": "트랜잭션 코드", "type": "string", "placeholder": "ZFI1000", "desc": "둘 중 하나는 필수"},
{"name": "IV_PROGRAM", "label": "프로그램", "type": "string", "placeholder": "SAPMV45A"},
],
"samples": [
{"label": "T코드 ZFI1000 → 프로그램", "params": {"IV_TCODE": "ZFI1000"}},
{"label": "T코드 ZSCAL → 모듈 풀 SAPMZSFT0", "params": {"IV_TCODE": "ZSCAL"}},
{"label": "프로그램 SAPMV45A → T코드 25개", "params": {"IV_PROGRAM": "SAPMV45A"}},
{"label": "없는 T코드 → E", "params": {"IV_TCODE": "ZZZ_NOPE"}},
],
},
# ------------------------------------------------ 17
{
"name": "GET_OBJECT_TYPE", "title": "오브젝트 유형 판별", "group": "6. 관계 추적",
"summary": "이름 하나를 주면 그것이 실행 프로그램인지 Include 인지 테이블·구조·뷰·타입·클래스·함수·T코드인지 판별한다. Include 면 그것을 포함하는 메인 프로그램 목록(D010INC)까지 준다.",
"when": "사용처(where-used)나 CTS 오브젝트 목록에 섞여 나온 이름을 실행 단위(루트 프로그램)로 정리할 때. 이름 규칙에 의존하지 않고 Include → 메인 프로그램을 찾는 유일한 방법.",
"params": [
{"name": "IV_OBJ_NAME", "label": "오브젝트 이름", "type": "string", "required": True, "placeholder": "ZFIMLS0010F01",
"desc": "프로그램/Include/테이블/구조/뷰/테이블타입/데이터엘리먼트/도메인/클래스/인터페이스/함수그룹/함수/T코드 이름"},
],
"samples": [
{"label": "Include → 메인 프로그램 (ZFIMLS0010F01)", "params": {"IV_OBJ_NAME": "ZFIMLS0010F01"}, "note": "KIND=INCLUDE, MASTERS 에 ZFIMLS0010"},
{"label": "함수그룹 Include (LZLEASE01TOP)", "params": {"IV_OBJ_NAME": "LZLEASE01TOP"}, "note": "MASTERS 에 SAPLZLEASE01"},
{"label": "실행 프로그램 + T코드 동명 (ZFI1000)", "params": {"IV_OBJ_NAME": "ZFI1000"}, "note": "RESULT 2행: PROG/REPORT 와 TRAN/TCODE"},
{"label": "테이블 (ZFIT0000)", "params": {"IV_OBJ_NAME": "ZFIT0000"}},
{"label": "클래스 풀 이름 (ZCL_FI_LS_ALV_GRID=...CP 형태는 TRDIR 로 CLASS_POOL)", "params": {"IV_OBJ_NAME": "ZCL_FI_LS_ALV_GRID"}, "note": "클래스 이름은 CLASS"},
{"label": "없는 이름 → E", "params": {"IV_OBJ_NAME": "ZZZ_NOPE"}},
],
"notes": ["2026-09-07 추가 (cts-diff-tester 의 루트 프로그램 정규화용). 같은 이름이 여러 유형에 있으면 RESULT 에 전부 나오고 KIND 는 첫 행(프로그램 우선).",
"MASTERS 는 D010INC 기준이라 활성화된 적 없는 Include 는 비어 있을 수 있다 (그때 RETURN.TYPE=W)."],
},
]
CATALOG = {
"methods": METHODS,
"fields": {k: {"label": v[0], "desc": v[1]} for k, v in FIELDS.items()},
"value_maps": VALUE_MAPS,
"links": LINKS,
"links_by_object": LINKS_BY_OBJECT,
"code_fields": CODE_FIELDS,
"list_fields": sorted(LIST_FIELDS),
"conventions": [
"요청: POST /sap/bc/ZAA_ICF/{METHOD}, Content-Type: application/json, 바디 {\"INPUT\": {\"IV_...\": ...}}",
"응답: asXML. <DATA> 아래 <RETURN>(TYPE/MESSAGE) + 결과. 반복 행은 <item>.",
"응답 XML 선언이 encoding=\"utf-16\" 이지만 실제는 UTF-8 → 이 서버가 선언을 떼고 파싱.",
"날짜(DATS) 파라미터는 YYYY-MM-DD.",
"플래그(CHAR1) 파라미터는 'X' 가 참.",
"목록 API 의 IV_MAX_ROWS 는 생략하면 전건(안전 상한 50,000). 지정해서 잘리면 RETURN.TYPE=W, MESSAGE 에 전체 건수, RETURN.TOTAL_ROWS.",
"이름류 파라미터는 서버가 대문자로 바꾸지만, 검색어(IV_SEARCH_TEXT)는 원문 그대로 비교.",
],
}