Skip to content

BE 참고 — 멤버(Member) 데이터 모델 · 불변식

2026-09-15 KST — 증빙 단일 커밋 경계

증빙 0..1 정책과 기존 flat 담당자 14필드는 유지합니다: evidencePrimary{Department,Name,Mobile,Phone,Fax,Email,Note}, evidenceSecondary{Department,Name,Mobile,Phone,Fax,Email,Note}.

SECTION_FIELDS.evidence가 증빙 본문과 두 담당자를 함께 소유합니다. 별도 evidencePrimary/evidenceSecondary 편집 섹션은 제거하지만 데이터 키는 변경하지 않습니다. 담당자만 바뀌어도 evidence가 dirty가 되며, 한 저장 호출로 전체 증빙을 반영합니다. 취소는 세 영역 모두를 원복하고 일반 mobile/phone/fax/email은 커밋 범위 밖에 둡니다. 시트 통합 저장은 기존 전체 작업본 경계를 유지합니다.

선택 이벤트는 draft 변경이며 자동 저장이 아닙니다. 현재 구현은 프런트 메모리 저장이고 DB·API·인증·알림 전송을 확장하지 않습니다. 센터는 CustomerBusinessEvidence.primaryContact/secondaryContact로 같은 7항목을 소유합니다. UI 일관성이 제품 간 서버 스키마 통합을 뜻하지 않습니다.

2026-09-14 KST — 어드민 보안 편집 UI 개정

프런트에 신규 패스워드·확인 입력을 추가하되 기존 패스워드 조회/표시는 하지 않습니다. 신규 값은 컴포넌트 메모리의 초안뿐이며 저장은 미연동으로 비활성입니다. 기존 일반 속성 patch·storage·URL·로그·emit·API에 패스워드를 섞지 않습니다. 이는 아래 최초 UI의 패스워드 입력 미제공 설명을 대체하며 API·DB·인증 정책 변경은 아닙니다. 서버 연동 시 어드민 권한 검증, 계정 대상 검증, 패스워드 정책 및 감사 기록을 별도 확정해야 합니다.

2026-09-14 KST — 계정 정보 분리 (프런트 구현)

식별 카드의 고정 순서는 mgmtCode → regNum → name이며 누락된 값은 —입니다. 이 절이 아래 관리코드 누락 행 생략 문장을 대체합니다. 관리코드는 시스템 발급·불변·중복 불가라는 사용자 정책을 표시 설계에 반영하되, 이번 변경은 실제 발급·고유성 검증·기존 생성 폼을 수정하지 않습니다. 등록번호 중복 허용 여부는 미확인 상태이며 UI만으로 보장하지 않습니다.

계정 탭은 일반 연락 email/mobile과 별도 원천을 요구합니다. 현재 원천·계정 연결 adapter가 없어 식별자는 —, 연결 상태는 확인할 수 없음이며 변경·재설정 요청을 비활성화합니다. 인증정보·비밀번호·OTP는 표시·수집·저장·전송하지 않습니다. 실제 계정 이메일/휴대전화 변경, 재인증·검증·초대·연결·권한·비밀번호 재설정 계약은 후속 범위입니다. 계정 초안은 UI 내부에서만 유지하며 기존 useMemberForm의 draft/patch에 섞지 않습니다. DB/API/schema 변경이나 인증 완료를 의미하지 않습니다.

2026-09-14 KST — 식별 정보 표시 경계

헤더의 이름과 상단 식별 카드의 이름·관리코드·등록번호는 동일한 저장 record를 참조합니다. 표시 중복은 허용하되 수정·저장 소유권은 기존 일반 속성 폼 하나이며 draft를 식별 카드에 미리 반영하지 않습니다. 관리코드·등록번호 등 누락된 값은 행을 유지하고 —로 표시합니다. 이 변경은 UI 합성만 바꾸며 관리코드 생성·고유성, 등록번호 중복 허용·수정 정책과 DB/API를 변경하거나 검증하지 않습니다. 사용자 지정 불변 정책과 기존 최초 생성 폼 간 차이는 별도 식별자 계약 검증 대상으로 남습니다.

2026-09-13 KST — 상세 탐색·속성 표 개정

멤버 상세의 일반·차량·일원·증빙·페이·노트 탭을 관리코드 요약 바로 아래로 옮깁니다. 기본·연락처·주소는 일반 패널의 항목/값 2열 조회 표이며 원문 데이터를 줄이거나 변환하지 않습니다. 생년월일·성별은 별도 행으로 표시하되 개인/법인 모두 기존 값을 유지합니다.

이 변경은 UI 합성이며 schema/API/식별자/권한/저장 범위를 바꾸지 않습니다. 관리코드는 내부 PK나 로그인 계정 ID로 대체하지 않습니다. 탭 상태는 호스트의 탐색 상태이며 저장 payload에 포함하지 않습니다. 일반↔증빙 이동 중 draft는 유지하고 기존 통합 저장 또는 카드별 섹션 저장만 commit합니다. 상세 닫힘·대상 변경 시 미저장 UI 상태를 정리합니다. 기존 in-memory 예제의 영속성·전송 기능을 추가한 것으로 해석하지 않습니다.

2026-09-13 KST — 샘플 도로명주소

useMemberForm.js의 데모 roadAddress만 사용자 지정 전체 주소로 바꿨습니다. 지번·상세주소·우편번호, 실제 멤버 데이터, 스키마·API·영속 저장은 변경하지 않습니다.

2026-09-09 KST — 관련 탭 UI 채택

차량·일원·증빙·페이·노트를 single CardBody의 접근 가능한 ETabs로 전환했습니다. 기존 관련 표 7개와 행/command, useMemberForm의 record/draft/mode 및 카드별·통합 편집 흐름은 보존됩니다. 탭 이동은 draft를 저장하거나 초기화하지 않으며 native checkbox/하위 disclosure 상태를 유지합니다. 새 멤버 생성 중에만 관련 영역을 숨깁니다.

이번 변경은 표 전용 scroll과 탐색/표면 합성입니다. 관련 목록은 기존 메모리 기반 예제이며 연결·해제·삭제를 새 서버 mutation으로 구현한 것이 아닙니다. 데이터 모델·권한·API·트랜잭션·식별자 계약은 변경하지 않습니다.

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) 플래그
증빙(Evidence)0..1유형(사업자/현금영수증) + 유형별 필드증빙 탭 카드 하나(생성 시 속성 카드). 법인은 사업자만. ADR MEMBER-EVIDENCE-SINGLE-2026-09-12
가상계좌(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 게이트가 막음. 개인은 자동 충족.