Skip to content

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·birthDatedisabled. 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. 엣지케이스

  1. 동일 사업자 2회 등록: 이름 중복 허용 + 관리코드로 구분. 등록번호도 동일할 수 있음(준식별). unique 제약은 관리코드(테이블 단위)에만.
  2. 개인↔법인 타입 변경: as-built은 create에서 결정. 사후 타입 변경 정책 미정(❌예정 — 대표자 필드 출현/소멸·등록번호 포맷 영향).
  3. 등록번호/생년월일 정정 필요 시: 최초 등록만 변경 가능 정책상, 오기 정정은 별도 운영 절차 필요(❌예정 — 현재 UI상 불가).
  4. 대표자 누락(법인): valid 게이트가 막음. 개인은 자동 충족.