/** * 공통코드 도메인 — 순수 데이터 표현, 외부 의존 없음. * * 백엔드 `TB_SYS_COM_CD`(그룹)와 `TB_SYS_COM_CD_DTL`(상세)의 두 층이며, 둘 다 * `/api/v1/mngr/code/**`(ROLE_ADMIN)로 읽고 쓴다. * * 이 파일은 두 종류의 소비자를 함께 섬긴다. * - 코드관리 화면(SYS_COD_001): 그룹·상세를 편집한다 → `CommonCodeGroup`·`CommonCodeDetail` * - 다른 화면의 선택지: 상세코드를 `{code,label}`로만 쓴다 → `CommonCode` */ /** 선택지로 쓸 때의 최소 표현. 화면이 코드 편집에 관심이 없을 때 쓴다. */ export type CommonCode = { /** 백엔드 `comDtlCd` — 저장·전송에 쓰는 코드값. */ code: string; /** 백엔드 `cdNm` — 화면에 보이는 이름. */ label: string; }; /** 코드 그룹 ID — 화면이 문자열을 직접 적지 않도록 여기 모은다. */ export const CODE_GROUP = { /** 꾸미기 아이템 카테고리. */ decorationItemCategory: 'ITEM_CATE_CD', /** 1:1문의 진행상태. */ inquiryAnswerStatus: 'BBS_ANS_CD', /** FAQ 유형. */ faqType: 'BBS_FAQ_CD', /** 포인트 지급기준의 「이벤트」 — 기획 "등록된 코드중에서 선택"(사용자 확정). */ pointEvent: 'COM_EVENT_CD', /** 학교(학교급). */ school: 'COM_SCHUL_CD', /** 학년. 학교마다 다르므로 `atrbNm`에 학교 코드를 넣어 조회한다. */ grade: 'GRD_CD', } as const; /** 값이 없는 항목의 화면 표기. */ export const EMPTY_FIELD_PLACEHOLDER = '-'; /** * 공통코드(그룹) — 시안의 "공통코드 목록" 한 줄. * * `TB_SYS_COM_CD`의 컬럼은 이 셋이 전부다(+감사 컬럼). 시안 등록 팝업의 "분류코드"에 * 해당하는 컬럼은 **없다** — 그 셀렉트는 코드ID 접두사를 채워 주는 입력 보조일 뿐이고 * 저장되는 값은 `comCd` 하나다(사용자 확정 사항). */ export type CommonCodeGroup = { /** 백엔드 `comCd` — PK이자 화면의 "코드ID". 상세코드를 묶는 키다. */ comCd: string; /** 백엔드 `cdNm` — 화면의 "코드명". */ name: string; /** 백엔드 `cdExpln` — 화면의 "코드설명". */ description: string | null; /** 백엔드 `frstRegDtStr` — `YYYY-MM-DD`. */ createdAt: string | null; }; /** * 상세코드 — 시안의 "상세코드 목록" 한 줄. * * ⚠️ `description`은 지금 **항상 null이다** — 목록 조회 SQL이 `DTL_CD_EXPLN`을 select하지 * 않는다. 등록 INSERT에서도 빠져 있어 수정으로만 저장된다(Repository 주석 참조). */ export type CommonCodeDetail = { /** 백엔드 `comCd` — 이 상세코드가 속한 그룹. */ comCd: string; /** 백엔드 `comDtlCd` — 그룹 안에서의 코드값. 화면의 "상세코드ID". */ comDtlCd: string; /** 백엔드 `cdNm` — 화면의 "상세코드명"이자 등록 팝업의 "코드값의미". */ name: string; /** 백엔드 `dtlCdExpln`. */ description: string | null; /** 백엔드 `sortSeq` — 등록 팝업의 "정렬번호"이자 목록의 "번호". */ sortSeq: number; /** 백엔드 `frstRegDtStr` — `YYYY-MM-DD`. */ createdAt: string | null; }; /** * 코드ID 접두사(시안의 "분류코드") — 저장되는 값이 아니라 코드ID를 지을 때의 작명 규칙이다. * 시안 목록이 전부 `CMS004`처럼 접두사 3자 + 일련번호라 그 규칙을 화면이 거들게 한다. * * 백엔드에 분류 컬럼이 생기면 이 상수 대신 그 코드 목록을 쓰면 된다. */ export const CODE_ID_PREFIXES: readonly string[] = ['CMS', 'SYS', 'FSC', 'CST']; export const DEFAULT_CODE_ID_PREFIX = CODE_ID_PREFIXES[0]; /** * 코드ID에서 접두사를 읽는다 — 앞 3자가 아는 접두사면 그것을, 아니면 기본값을 돌려준다. * 수정 팝업이 기존 코드ID로 셀렉트의 초기값을 정할 때 쓴다. */ export function readCodeIdPrefix(comCd: string): string { const head = comCd.slice(0, 3).toUpperCase(); return CODE_ID_PREFIXES.includes(head) ? head : DEFAULT_CODE_ID_PREFIX; } /** * 접두사를 바꿔 끼운 코드ID를 만든다. 기존 값이 아는 접두사로 시작하면 그 자리를 갈아 끼우고, * 아니면 앞에 덧붙인다 — 사용자가 이미 적어 둔 일련번호를 지우지 않기 위해서다. */ export function applyCodeIdPrefix(comCd: string, prefix: string): string { const rest = CODE_ID_PREFIXES.includes(comCd.slice(0, 3).toUpperCase()) ? comCd.slice(3) : comCd; return `${prefix}${rest}`; } export function formatOptionalText(value: string | null | undefined): string { return value === null || value === undefined || value === '' ? EMPTY_FIELD_PLACEHOLDER : value; } /** 코드값 → 이름. 목록에 없는 코드는 코드값 자체를 보여준다(이름을 지어내지 않는다). */ export function formatCommonCode( codes: readonly CommonCode[], code: string ): string { return codes.find((item) => item.code === code)?.label ?? code; } export function isKnownCommonCode( codes: readonly CommonCode[], code: string ): boolean { return codes.some((item) => item.code === code); }