File name
Commit message
Commit date
File name
Commit message
Commit date
File name
Commit message
Commit date
/**
* 학생 회원 도메인 타입 — 순수 데이터 표현, 외부 의존 없음.
*
* 데이터 출처는 백엔드(edupay-backend)의 `GET /api/v1/mngr/user/pagination`이며,
* `lib/data/repositories/student-member-repository.ts`가 응답을 이 타입으로 매핑한다.
*
* **`null`의 의미는 "백엔드가 아직 주지 않는 항목"이다.** 현재 응답이 담고 있는 값은
* 식별자·이름 계열(`userId`/`loginId`/`userNm`) 넷뿐이라 나머지 항목은 전부 `null`로 채워지고
* 화면에서 `-`로 표시된다(화면 컬럼은 유지 — 백엔드가 필드를 추가하면 Repository의 매핑만
* 늘리면 그대로 채워진다). 값이 "비어 있다"와 "제공되지 않는다"를 굳이 구분하지 않는 이유는,
* 조회 전용 화면에서 둘 다 사용자에게는 `-`로 같은 의미이기 때문이다.
*
* 조회 전용 화면(등록/수정/삭제 없음)의 데이터라 모든 필드를 읽기 전용으로 취급한다
* (수정 가능 여부는 UI 계층의 책임이지 타입 자체의 제약은 아니다).
*/
/** 보호자 한 명. 백엔드 `adbkList`의 한 행(`parentNm`·`parentTelNo`)이다. */
export type StudentGuardian = {
name: string | null;
phoneNumber: string | null;
};
export type StudentMember = {
/** 내부 식별자 — 백엔드 `userId`. 목록 행의 key이자 향후 단건 조회의 입력값이다. */
id: string;
/** 화면에 노출되는 회원코드. 백엔드에 전용 필드가 없어 현재는 `userId`를 그대로 쓴다. */
memberCode: string;
/** 백엔드 `userNm`. */
name: string;
/** 백엔드 `loginId`. */
loginId: string;
phoneNumber: string | null;
email: string | null;
/** 회원 역할 — 본 화면(학생 회원 목록)에서는 항상 '학생'이다. */
role: string;
schoolName: string | null;
grade: number | null;
classNumber: number | null;
studentNumber: number | null;
/** 보호자 목록. 한 학생에 여러 명이 등록될 수 있어 배열이다. 없으면 빈 배열. */
guardians: StudentGuardian[];
/** ISO 형식(YYYY-MM-DD) 문자열. */
joinedAt: string | null;
/** ISO 형식(YYYY-MM-DD) 문자열. */
birthDate: string | null;
/** 사용여부. 백엔드가 값도 변경 API도 제공하지 않아 현재는 항상 null이다. */
isActive: boolean | null;
};
/** 값이 없는 항목의 화면 표기. 표·조회 팝업이 같은 문자를 쓰도록 여기 한 곳에 둔다. */
export const EMPTY_FIELD_PLACEHOLDER = '-';
/** 값이 없으면 `-`, 있으면 문자열로 표기한다. */
export function formatOptionalValue(
value: string | number | null
): string {
return value === null ? EMPTY_FIELD_PLACEHOLDER : String(value);
}
/**
* "학년/반/번호" 합성 표기. 표와 조회 팝업이 같은 규칙을 쓰도록 한 곳에 둔다.
*
* **있는 값만 이어 붙인다.** 백엔드 `TB_COM_USER`에는 GRADE·CLS_NO만 있고 학생 번호 컬럼이
* 아예 없어(코드베이스 전체 VO가 그 둘만 쓴다) 번호는 영영 오지 않는다. 셋이 다 있어야
* 표기하던 종전 규칙으로는 실제로 오는 학년·반까지 함께 묻혔다.
*
* 하나도 없으면 `-`다.
*/
export function formatGradeClassNumber(member: StudentMember): string {
const parts = [
member.grade === null ? null : `${member.grade}학년`,
member.classNumber === null ? null : `${member.classNumber}반`,
member.studentNumber === null ? null : `${member.studentNumber}번`,
].filter((part): part is string => part !== null);
return parts.length > 0 ? parts.join(' ') : EMPTY_FIELD_PLACEHOLDER;
}