대상 레포: /Users/biuea/sports-application (backend/src/main/resources/db/migration/)
이 문서는 설계 산출물이며 DDL 전문 작성·실행은 private-mysql-implementer가 담당한다.
실측한 기존 마이그레이션 컨벤션 (SSOT)
항목
실측 결과
근거
파일 명명
순차 정수V{정수}__{snake_case}.sql — private-db-schema-convention의 타임스탬프 형식 아님
레포 db/migration/ 전수
최신 버전
V37 (V37__fix_cart_items_active_unique.sql)
실측
신규 시작 번호
V38~
—
번호 배정 조정 방침 (공통, 잠정): 현재 배정 ② partner=V38/V39/V40 · ③ limited_drops=V41 · ⑥ alerts=V42는 세 과제가 같은 db/migration/ 네임스페이스를 공유해 발생한 잠정 배정이다. 먼저 머지되는 쪽이 V38부터 순차 점유하고, 나중 쪽은 origin/dev 기준 최신 번호로 재배정한다. 구현 시 origin/dev 기준 워크트리에서 최신 버전을 실측 후 확정한다.
| COMMENT | 전 컬럼·테이블 COMMENT 필수 | V20__create_mcp_tokens.sql, V21__create_mcp_audit_logs.sql |
| 인덱스 명명 | INDEX idx_{table}_{cols} / UNIQUE KEY uq_{table}_{cols} + 인덱스 COMMENT | V20, V21 |
| 시간 컬럼 | DATETIME(6) | 전수 |
| BOOLEAN | TINYINT(1) NOT NULL DEFAULT 0 | V20:13-14 |
| status | VARCHAR(32) (ENUM 금지) | V20:12 |
| FK | 물리 FK 없음, 일반 컬럼(user_id, partner_id) | 전수 |
| 감사 로그 | append-only, created_*만 (updated/deleted 없음), 90일 보관 | V21:1-5 |
| ip/UA 길이 | ip_addr VARCHAR(45), client_user_agent VARCHAR(500) | V21:15-16 |
| 낙관락 | version BIGINT NOT NULL DEFAULT 0 | V20:17 |
신규 3개 테이블은 전부 가산(additive) — 기존 테이블·데이터 무영향. CREATE TABLE은 신규 객체 생성이므로 기존 테이블에 락을 유발하지 않는다.
저장소 선택
데이터 단위
저장소
채택 사유
partner (신원·상태)
MySQL
관계형·트랜잭션·낮은 볼륨. 기본 저장소
partner_api_key (자격증명 라이프사이클)
MySQL
상태 전이·유니크 제약(key_hash)·트랜잭션 필요
partner_audit_log (감사)
MySQL
append-only 정형 로그. 기존 mcp_audit_logs 선례와 동일 패턴. 조회는 partner_id+기간 범위
MongoDB 미채택: 세 단위 모두 정형 스키마·유니크 제약·관계형 조회(파트너별 감사)로 private-mongodb-convention의 문서형/스키마리스 채택 근거(가변 스키마·중첩 집계·샤딩 규모)에 해당하지 않는다. 전부 MySQL.
테이블 정의
1. partner — 협력사 신원 (V38)
컬럼
타입
NULL
기본값
COMMENT / 근거
id
BIGINT AUTO_INCREMENT
NOT NULL
—
PK
name
VARCHAR(255)
NOT NULL
—
협력사 표시명 (운영자 입력)
status
VARCHAR(32)
NOT NULL
—
상태: ACTIVE | SUSPENDED (ENUM 금지 → VARCHAR)
linked_user_id
BIGINT
NOT NULL
—
연동 전용 User id (users.id, 물리 FK 없음). owner_id 네임스페이스로 해석
version
BIGINT
NOT NULL
0
낙관락(@Version) — 동시 상태 전이 lost-update 방지 (mcp_tokens 선례)
created_at
DATETIME(6)
NOT NULL
—
생성 시각 (UTC)
created_by
BIGINT
NULL
—
생성자 user_id (ADMIN)
updated_at
DATETIME(6)
NOT NULL
—
마지막 수정 시각
updated_by
BIGINT
NULL
—
마지막 수정자 user_id
soft-delete 미도입: Partner 라이프사이클은 status(ACTIVE/SUSPENDED)로 완결. 삭제는 본 과제 범위 밖(TDD Non-Goals). deleted_at 없음 — 단순함 우선.
2. partner_api_key — 인증 키 (V39)
컬럼
타입
NULL
기본값
COMMENT / 근거
id
BIGINT AUTO_INCREMENT
NOT NULL
—
PK. partner_<id>_<random>의 <id>가 이 값 (필터가 parseKeyId로 추출)
partner_id
BIGINT
NOT NULL
—
소유 파트너 (partner.id, 물리 FK 없음)
key_hash
VARCHAR(255)
NOT NULL
—
BCrypt 해시 (평문은 발급 시 1회 노출). Stripe 패턴
status
VARCHAR(32)
NOT NULL
—
상태: ACTIVE | REVOKED (ENUM 금지 → VARCHAR)
revoked_at
DATETIME(6)
NULL
—
폐기·재발급 시각 (NULL=활성)
last_used_at
DATETIME(6)
NULL
—
마지막 인증 성공 시각 (필터가 갱신)
created_at
DATETIME(6)
NOT NULL
—
발급 시각 (UTC)
created_by
BIGINT
NULL
—
발급자 user_id (ADMIN)
append-only에 가까움. 상태 변경은 status/revoked_at만 — updated_* 생략(폐기 시각이 유일한 변경 이벤트, revoked_at으로 기록).
last_used_at 갱신은 쓰기 발생: 인증 성공마다 1회 UPDATE. 볼륨 ≈ 파트너 요청 수(수천/일)로 무시 가능.
3. partner_audit_log — 파트너 활동 감사 (V40, append-only)
컬럼
타입
NULL
COMMENT / 근거
id
BIGINT AUTO_INCREMENT NOT NULL
—
PK
partner_id
BIGINT NOT NULL
—
요청 파트너 (partner.id)
user_id
BIGINT NOT NULL
—
연동 User id (owner로 귀속된 계정)
http_method
VARCHAR(10) NOT NULL
—
GET/POST/PATCH/PUT/DELETE
request_path
VARCHAR(512) NOT NULL
—
요청 경로 (쿼리스트링 제외)
target_resource
VARCHAR(255) NULL
—
대상 리소스 식별자 (예: productId) — 파싱 실패 시 NULL
status_code
INT NOT NULL
—
응답 HTTP 상태 코드 (201/401/403/404 등)
latency_ms
INT NOT NULL
—
처리 소요 시간 (밀리초)
ip_addr
VARCHAR(45) NULL
—
클라이언트 IP (IPv4/IPv6). mcp 선례 길이
client_user_agent
VARCHAR(500) NULL
—
User-Agent 문자열. mcp 선례 길이
called_at
DATETIME(6) NOT NULL
—
요청 시각 (UTC, 조회·정렬 기준)
created_at
DATETIME(6) NOT NULL
—
레코드 적재 시각 (append-only)
mcp_audit_logs와 테이블 미공유 (도메인 격리, ADR-001 / TDD FR-8·방안 F 미채택). 컬럼 구성은 mcp 선례를 준용.
컨벤션 위반 점검: FK 없음 OK / ENUM 없음(status VARCHAR) OK / JSON 없음 OK / BOOLEAN 없음 OK / DATETIME(6) OK / 전 컬럼·테이블 COMMENT 대상(implementer 작성) OK / PK=id, 참조={entity}_id OK.
Document History
날짜
변경 내용
2026-07-03
최초 작성 — 기존 컨벤션 실측(순차 정수 최신 V37), partner/partner_api_key/partner_audit_log 3테이블 정의, 쿼리→인덱스 매핑(ESR), 용량·90일 보관, expand-contract 배포 순서