File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
/**
* 관리자 회원 도메인 타입 — 순수 데이터 표현, 외부 의존 없음.
*
* 데이터 출처는 백엔드(edupay-backend)의 `GET /api/v1/mngr/admin/pagination`이며,
* `lib/data/repositories/admin-member-repository.ts`가 응답을 이 타입으로 매핑한다.
*
* 값이 없는 항목은 `null`로 채워지고 화면에서 `-`로 표시된다.
*/
/** 역할 코드 — 백엔드 `roleId`. 코드 체계를 백엔드가 확정하지 않아 문자열로 다룬다. */
export type AdminRoleCode = string;
export type AdminMember = {
/** 내부 식별자 — 백엔드 `userId`. 목록 행의 key이자 수정/삭제의 입력값이다. */
id: string;
/** 백엔드 `userNm`. */
name: string;
/** 백엔드 `loginId`. 등록 후에는 변경할 수 없다(시안 ADM_ADM_103_p ①). */
loginId: string;
/** 백엔드 목록 응답에 없다 — mock으로 등록한 행에만 값이 있다. */
phoneNumber: string | null;
/** 백엔드 목록 응답에 없다 — mock으로 등록한 행에만 값이 있다. */
email: string | null;
/** 백엔드 `roleId`. 표기용 이름은 `formatAdminRoleLabel`이 만든다. */
roleCode: AdminRoleCode;
/** ISO 형식(YYYY-MM-DD) 문자열. 백엔드 목록 응답에 없다(정렬에만 쓰이고 select되지 않는다). */
createdAt: string | null;
/** 백엔드 `acctLockYn` — 계정 잠김 여부. 시안의 "잠김여부"는 이 값의 반대(활성/비활성)다. */
isLocked: boolean | null;
/** 백엔드 `useYn` — 사용 여부. */
isActive: boolean | null;
/** 백엔드 `loginFailCnt` — 로그인 연속 실패 횟수. 잠김 사유 판단용이라 목록에는 노출하지 않는다. */
loginFailCount: number | null;
};
/** 값이 없는 항목의 화면 표기. 표·팝업이 같은 문자를 쓰도록 여기 한 곳에 둔다. */
export const EMPTY_FIELD_PLACEHOLDER = '-';
/** 값이 없으면 `-`, 있으면 문자열로 표기한다. */
export function formatOptionalValue(value: string | number | null): string {
return value === null ? EMPTY_FIELD_PLACEHOLDER : String(value);
}
/**
* 역할 코드 → 화면 표기 이름.
*
* **백엔드에 역할 코드 목록을 주는 API도, 코드 상수도 없다** — `TB_ADM_USER.ADM_ROLE_CD`를
* 그대로 내려줄 뿐이고 코드값의 정의는 어디에도 없다(백엔드 저장소 전체 검색으로 확인).
* 시안(ADM_ADM_101)이 요구하는 표기는 "최고관리자/일반관리자" 둘이고, 실제로 관측된 코드는
* 로그인 토큰의 `roleId` 클레임에서 본 `ROLE_SYSTEM` 하나뿐이다(`lib/domain/admin-user.ts`).
*
* 그래서 아래 표는 **잠정 매핑**이며, 표에 없는 코드는 임의의 이름을 지어내지 않고 코드를 그대로
* 노출한다 — 잘못된 역할 이름을 보여주는 것보다 낯선 코드를 보여주는 편이 낫다(권한 화면이라
* 표기 오류의 대가가 크다). 시안의 "역할 선택" 목록은 원래 [시스템관리 > 역할관리]가 등록한
* 역할을 가져와야 하는데 그 화면도 API도 아직 없어, 지금은 이 표가 곧 선택지다.
*
* 백엔드가 역할 코드 API를 내면 이 표를 지우고 그 응답으로 대체한다.
*/
const ADMIN_ROLE_LABEL_BY_CODE: Record<string, string> = {
ROLE_SYSTEM: '최고관리자',
ROLE_ADMIN: '일반관리자',
};
export const ADMIN_ROLE_OPTIONS: ReadonlyArray<{
value: AdminRoleCode;
label: string;
}> = Object.entries(ADMIN_ROLE_LABEL_BY_CODE).map(([value, label]) => ({
value,
label,
}));
/** 시안의 "역할 선택" 기본값 — 잠정 매핑의 첫 항목(최고관리자). */
export const DEFAULT_ADMIN_ROLE_CODE: AdminRoleCode = 'ROLE_SYSTEM';
/** 역할 코드를 화면 표기로 바꾼다. 모르는 코드는 코드 그대로 노출한다(위 주석 참조). */
export function formatAdminRoleLabel(roleCode: AdminRoleCode): string {
return ADMIN_ROLE_LABEL_BY_CODE[roleCode] ?? roleCode;
}
/**
* 시안(ADM_ADM_103_p ③)의 "잠김여부" 표기. 항목은 활성/비활성이고, **잠기지 않은 계정이 활성**이다
* — 백엔드 필드가 `acctLockYn`(잠김 여부)이라 의미가 뒤집혀 있어 이 변환을 한 곳에 모아 둔다.
*/
export const ADMIN_LOCK_STATUS_OPTIONS: ReadonlyArray<{
value: string;
label: string;
}> = [
{ value: 'false', label: '활성' },
{ value: 'true', label: '비활성' },
];
export function formatAdminLockStatusLabel(isLocked: boolean | null): string {
if (isLocked === null) {
return EMPTY_FIELD_PLACEHOLDER;
}
return isLocked ? '비활성' : '활성';
}