다크 모드
ID 체계 (EID)
주의
외부에 노출되는 모든 ID는 **반드시 EID (External ID)**를 사용해야 합니다. 내부 DB ID(dbId)는 절대 API 응답이나 클라이언트에 노출하지 않습니다.
개요
truloop은 두 가지 ID 체계를 사용합니다:
| 구분 | 필드명 | 용도 | 노출 범위 |
|---|---|---|---|
| EID (External ID) | eid | 외부 식별자 | API 요청/응답, 클라이언트, URL, 딥링크 |
| DB ID (Internal ID) | dbId (또는 id) | 내부 식별자 | DB FK 관계, 서버 내부 로직 |
TSID (Time-Sorted ID)
EID는 TSID(Time-Sorted Unique Identifier) 방식으로 생성됩니다.
특성
| 항목 | 설명 |
|---|---|
| 생성 방식 | TsidFactory를 통한 생성 |
| 형식 | 문자열 (예: 0HJKQ3N8XZ4M8) |
| 정렬 가능 | 시간 순서에 따라 정렬 가능 (Time-Sorted) |
| 고유성 | 분산 환경에서도 충돌 없는 유일 ID |
| 보안 | 내부 DB 구조를 추측할 수 없음 (순차 증가 아님) |
구현
EidGenerator (interface) — co.butbeautiful.truloop.common.eid
└── TsidEidGenerator (implementation) — co.butbeautiful.truloop.common.eid
└── TsidFactory.create().toString()EidGenerator는:common모듈의co.butbeautiful.truloop.common.eid패키지에 정의된 인터페이스TsidEidGenerator는TsidFactory를 주입받아com.github.f4b6a3.tsid라이브러리를 사용- Koin DI를 통해 싱글톤으로 등록
- 새로운 엔티티 생성 시 Use Case에서
eidGenerator.generate()호출
적용 대상
EID가 부여되는 주요 엔티티:
| 엔티티 | 설명 |
|---|---|
User | 사용자 |
Loop | 룹 (모임) |
LoopMedia | 룹 미디어 (사진/영상/포스터) |
Story | AI 생성 리캡 (내부명: Story) |
GuestParticipant | 비회원 참여자 |
Secretary | AI 비서 |
Mission | 미션 정의 |
Notification | 알림 기록 |
CoverTemplate | 커버 템플릿 |
API 경로에서의 사용
API 경로에서 리소스를 식별할 때는 항상 EID를 사용합니다.
GET /core/api/v3/loops/{eid}
GET /core/api/v3/loops/{eid}/media
POST /core/api/v3/loops/{eid}/participants위험
절대 금지: API 요청/응답에 dbId를 포함하지 마세요. 내부 DB ID가 노출되면 보안 취약점이 됩니다.
내부 DB ID 사용 범위
DB ID(dbId, id)는 다음 경우에만 사용합니다:
- DB 외래 키 관계:
loopId,userId,mediaId등 테이블 간 참조 - 서버 내부 로직: Use Case, Repository 내부에서의 엔티티 조회 및 관계 처리
- 성능 최적화: 인덱스 기반 조회 시 DB ID 사용 (EID 조회 후 내부에서 DB ID로 전환)
설계 원칙
- 외부 ↔ 내부 경계 명확화: Web Adapter(Presentation Layer)에서 EID를 DB ID로 변환하고, 응답 시 DB ID를 EID로 변환
- EID는 불변: 한번 생성된 EID는 변경되지 않음
- 모든 새 엔티티에 EID 부여: 외부에 노출될 가능성이 있는 엔티티는 생성 시 EID를 할당
변경 이력
| 날짜 | 내용 |
|---|---|
| 2026-03-10 | EidGenerator 패키지 경로(co.butbeautiful.truloop.common.eid) 명시. TsidEidGenerator의 TsidFactory 의존성 및 라이브러리 정보 추가. |