다크모드
BE 참고 — 멤버(Member) 데이터 모델 · 불변식
2026-07-15 계약 연결 탭 정리
계약 연결 시트에서 실제 목적지가 아닌 화살표 탭을 제거했다. 멤버·차량·일원·증빙·페이·노트 관계와 CRUD/API 계약은 그대로이며, 이번 변경은 탐색 UI 잔여 요소 제거다.
독자: BE 개발자/AI. 데이터 모델·코드 체계·불변식·엣지케이스. 정본 정책:
CLAUDE.md§1(코드 분류 체계) · §0-6(엔티티 속성 vs 연결 컬렉션). as-built(FE 프로토타입)과 확정 규칙을 구분 표기. 프로토타입 데이터 소스는useMemberForm.js데모 싱글톤(영속 백엔드 ❌예정).
1. 코드 4계층 (식별 체계)
멤버는 CLAUDE.md §1 코드 분류 체계를 그대로 따른다.
| 계층 | 필드(as-built) | 생성 | 수정 | 고유성 범위 | 고객 노출 |
|---|---|---|---|---|---|
| 고유코드 (Unique ID) | (PK, 미노출) | 시스템 자동 | 절대 불변 | 시스템 DB 전체 | 없음 |
| 관리코드 (Management Code) | mgmtCode | 자동(mgmt-####) 또는 직접 입력 | 최초 등록만 | 페이지/테이블 단위 | 상세 우측 상단 미니멀 |
| 등록번호 (Registration Number) | regNum | 직접 입력 또는 [자동입력] | 최초 등록만 | 준식별(중복 가능) | 테이블 + 상세 |
| 이름(명) (Name) | name | 직접 입력 | 가능 | 중복 허용 | 테이블 + 상세 |
불변식 (invariants)
- 고유코드 = 절대 불변 PK. 시스템 내부 참조 전용. 어떤 경로로도 변경 불가.
- 관리코드·등록번호·생년월일 = 최초 등록 시에만 결정/변경. 이후 read-only. (FE:
edit모드에서mgmtCode는 폼 비노출,regNum·birthDate는disabled.create에서만 입력.) - 이름 = 중복 허용. 관리코드가 고유성을 보장하므로 동일 대상을 두 번 등록해도 무방(예: 동일 사업자 2회 등록).
join key 이원화
- 내부 조인 = 고유코드(PK). 시스템 간/테이블 간 관계는 고유코드로 건다.
- 고객 표시·고객 측 참조 = 관리코드. 고객이 보거나 입력하는 식별자는 관리코드. 두 키를 혼동하지 말 것(내부 무결성 = 고유코드, 고객 UX = 관리코드).
2. 엔티티 속성 필드 (한 몸)
useMemberForm.js record/draft 코어 바인딩. 통째 read↔edit + 단일 저장(또는 카드별 부분 저장).
| 그룹 | 필드 | 비고 |
|---|---|---|
| 기본 | type(개인|법인), regNum, name, representative, birthDate, sex(남자|여자|기타) | |
| 컨택 | mobile, phone, fax, email | |
| 주소 | roadAddress, lotAddress, detailAddress, postalCode | |
| 코드 | mgmtCode | 관리코드(§1) |
자연인(개인) 이름 = 대표자
- 개인:
representative를 별도 보관하지 않고name과 동기화한다. FE watch: 개인이면representative = name. BE는 개인의 대표자 컬럼을 이름의 미러로 취급(또는 null + 표시 시 name 사용). - 법인:
name(법인명)과representative(대표자명)는 독립 필드. 둘 다 필수.
필수(valid) 규칙
FE 게이트: type && regNum && name && representative 모두 채워져야 저장 활성. (개인은 representative가 name으로 자동 충족.) BE도 동일 필수 검증 권장.
3. 등록번호(regNum) 포맷
준식별 코드. 중복 허용(준식별이므로 unique 제약 걸지 말 것). [자동입력] 생성 규칙(as-built autoRegNum):
| 타입 | 조건 | 포맷 |
|---|---|---|
| 개인 | 생년월일(8자리) 있음 | 생년월일6 - 영숫자7 (예: 800229-1234abc) |
| 개인 | 6자리만 | 앞6 - 영숫자7 |
| 개인 | 없음 | 영숫자6 - 영숫자7 |
| 법인 | — | 영숫자6 - 영숫자7 |
- 영숫자 토큰은 첫 글자가 소문자 영문(순수 숫자열 회피). 하이픈 1개로 6+7 분절.
- 주민/사업자등록번호 등 실제 등록번호도 이 자리에 들어갈 수 있음(준식별 —
CLAUDE.md§1-3). 자동입력은 데모용 placeholder 성격이며, 고객이 실제값으로 덮어쓸 수 있다. - ⚠ 포맷 검증/마스킹은 BE 확정 규칙으로 별도 정의 필요(❌예정). 현재 FE는 자유 입력.
4. 엔티티 속성 vs 연결 컬렉션 (1:N)
멤버에는 독립 생명주기를 갖는 연결 컬렉션이 1:N으로 매달린다. 속성과 분리 저장·분리 CRUD.
| 컬렉션 | 카디널리티 | 키 식별(목록 노출) | 비고 |
|---|---|---|---|
| 차량(Vehicle) | 1:N | 차량등록번호 + 차량명 | 대표(main) 플래그 |
| 일원(Associate) | 1:N | 등록번호 + 이름 | 대표(main) 플래그 |
| 사업자(Business) | 1:N | 사업자등록번호 + 상호 | 증빙 탭 |
| 현금영수증(CashReceipt) | 1:N | 발급수단번호 | 증빙 탭, 자진발급/기본용도 |
| 가상계좌(VirtualBankAccount) | 1:N | 기관 + 계좌번호 + 예금주 | 페이 탭, 고정/상태 |
| 자동이체(DirectDebit) | 1:N | 기관 + 계좌/카드번호 + 명의 | 페이 탭, 계좌/카드 타입·유효기간·상태 |
| 노트(Note) | 1:N | 제목 + 내용 + 수정일 | CRM 노트 |
- 연결 컬렉션은 멤버 속성 저장 트랜잭션과 무관. 각자 생성/연결(link)/해제(unlink)/삭제 액션을 가진다(증빙·페이는 삭제, 차량·일원은 연결/해제도 지원 = 다른 멤버와 공유 가능 자원).
- "연결(link)/해제(unlink)" 존재 = 차량·일원·사업자는 멤버 전속이 아니라 공유 가능 마스터 리소스일 수 있음. 해제는 관계만 끊고 리소스 자체는 보존. 삭제는 리소스 제거. BE 모델링 시 구분.
5. 상태머신 / 라이프사이클
- 멤버 속성 자체에 명시적 상태머신은 없음(create→영속, edit로 일부 필드 갱신).
- 가상계좌·자동이체는
status(정상 등) 보유 — 별도 도메인 문서로 위임(❌예정).
6. 엣지케이스
- 동일 사업자 2회 등록: 이름 중복 허용 + 관리코드로 구분. 등록번호도 동일할 수 있음(준식별). unique 제약은 관리코드(테이블 단위)에만.
- 개인↔법인 타입 변경: as-built은 create에서 결정. 사후 타입 변경 정책 미정(❌예정 — 대표자 필드 출현/소멸·등록번호 포맷 영향).
- 등록번호/생년월일 정정 필요 시: 최초 등록만 변경 가능 정책상, 오기 정정은 별도 운영 절차 필요(❌예정 — 현재 UI상 불가).
- 대표자 누락(법인): valid 게이트가 막음. 개인은 자동 충족.