# Model Domain

> SESSION.md의 도메인 정의를 바탕으로 유비쿼터스 언어(서술형 도메인 모델)를 작성한다. ERD 대신 "A는 B를 할 수 있다" 형식의 자연어 명세로 domain-model.md를 생성한다.

- Skill: `ureca-corp/model-domain` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds add ureca-corp/model-domain`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ureca-corp/model-domain/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: ureca-corp (https://skillmd.com/u/ureca-corp)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/ureca-corp/model-domain

---


# Skill: Model Domain

## 목적

도메인의 **유비쿼터스 언어**를 정의하고 서술형 명세로 작성

**철학**: "ERD 그리기 말고, 말로 설명하기"

---

## 입력

- 도메인 이름 (예: "users")
- Phase 2 결과 (SESSION.md의 완전한 도메인 정의)

---

## 출력

- `ai-context/domain-books/{domain}/domain-model.md`
- 용어 정의 + 관계 규칙 + 제약 조건 + 생명주기

---

## 유비쿼터스 언어란?

**해당 도메인 전용이면서 개발자가 쉽게 이해할 수 있는 전용 언어**

### ❌ 잘못된 접근 (ERD)

```
┌─────────┐        ┌──────────────┐
│  User   │───1:N──│ Translation  │
└─────────┘        └──────────────┘
```

### ✅ 올바른 접근 (유비쿼터스 언어)

```
"사용자는 여러 개의 번역 기록을 가질 수 있다."
"번역 기록은 반드시 한 명의 사용자에게 속한다."
```

---

## 작동 방식

### 1. 용어 추출

SESSION.md에서 해당 도메인의 엔티티와 속성을 읽고, 각 개념을 한글 용어로 정의한다:

```
SESSION.md → users 도메인:
  속성: ID, Email, DisplayName, ProfileImage, PreferredLanguage, CreatedAt

용어 정의:
  사용자 (User)             — 앱을 사용하는 개인
  식별자 (ID)               — 사용자를 고유하게 구분하는 값
  이메일 (Email)            — 로그인 및 연락용 이메일 주소
  표시 이름 (DisplayName)   — 다른 사용자에게 보이는 이름
  프로필 사진 (ProfileImage) — 사용자의 프로필 이미지 경로
  선호 언어 (PreferredLanguage) — 사용자가 선호하는 언어 설정
  가입 시각 (CreatedAt)     — 사용자가 가입한 날짜와 시간
```

### 2. 관계 규칙 생성

SESSION.md의 관계 정의를 서술형 문장으로 변환한다:

```
1:N 관계 (User → Translation):
  "사용자는 여러 개의 번역 기록을 가질 수 있다."
  "번역 기록은 반드시 한 명의 사용자에게 속한다."
  "사용자가 삭제되면 모든 번역 기록도 함께 삭제된다."
```

### 3. 제약 조건 추출

SESSION.md의 제약 정의를 자연어로 변환한다:

```
Email Unique → "이메일 (Email)은 중복될 수 없다."
ID 자동생성 → "식별자 (ID)는 시스템이 자동으로 생성한다."
```

### 4. 생명주기 정의

생성·수정·삭제 각 단계를 단계별 흐름도로 작성한다.

---

## domain-model.md 구조

```markdown
# {domain} 도메인 모델

> 생성일: {오늘 날짜}
> Phase: 3 (Domain Modeler)
> 상태: ✅ 완료

---

## 📖 유비쿼터스 언어 (용어 정의)

> 이 도메인에서 사용하는 전용 용어들

### 핵심 용어

| 용어 | 정의 | 예시 |
|------|------|------|
| 사용자 (User) | 앱을 사용하는 개인 | "홍길동", "john@example.com" |
| 식별자 (ID) | 사용자를 고유하게 구분하는 값 | "u_123abc" |
| ... | ... | ... |

---

## 📐 관계 규칙

> 이 도메인의 엔티티들이 어떻게 연결되는지 서술형으로 정의

### 사용자와 번역 기록

**규칙 1**: 사용자는 여러 개의 번역 기록을 가질 수 있다.
- 한 사용자가 0개 이상의 번역을 요청할 수 있음
- 예: "홍길동 사용자는 10개의 번역 기록을 가지고 있다"

**규칙 2**: 번역 기록은 반드시 한 명의 사용자에게 속한다.
- 모든 번역은 누가 요청했는지 기록됨
- 예: "이 번역 기록은 john@example.com 사용자의 것이다"

---

## ✅ 제약 조건

> 엔티티가 지켜야 하는 규칙

### 필수 규칙

1. **식별자 (ID)**는 시스템이 자동으로 생성한다.
   - 사용자가 직접 설정할 수 없음

2. **이메일 (Email)**은 중복될 수 없다.
   - 이미 존재하는 이메일로는 가입 불가
   - 예: "user@example.com"으로 이미 가입되어 있으면 다시 가입 불가

---

## 🔄 생명주기

> 엔티티가 어떻게 생성, 수정, 삭제되는지

### 생성 (가입)

\`\`\`
사용자가 가입을 요청한다
    ↓
이메일이 중복되지 않는지 확인한다
    ↓
모든 필수 정보가 제공되었는지 확인한다
    ↓
사용자 엔티티를 생성한다
    ↓
식별자(ID)와 가입 시각(CreatedAt)을 자동으로 설정한다
\`\`\`

**규칙**: 가입 시 선호 언어가 제공되지 않으면 기본값은 '영어'로 설정된다.

### 수정 (프로필 편집)

...

### 삭제 (탈퇴)

...
```

---

## 작성 원칙

### ✅ 좋은 명세 (서술형)

- "사용자는 여러 개의 번역 기록을 가질 수 있다."
- "번역 기록은 반드시 한 명의 사용자에게 속한다."
- "이메일은 중복될 수 없다."

### ❌ 나쁜 명세 (기술적)

- "User 테이블의 id 컬럼은 UUID 타입"
- "Translation.user_id는 User.id를 참조하는 Foreign Key"
- "email 컬럼에 UNIQUE 제약"

→ **말로 설명하기!** 테이블/컬럼 언급 금지.

---

## 관계 표현 패턴

### 1:N 관계

```
"A는 여러 개의 B를 가질 수 있다."
"B는 반드시 하나의 A에 속한다."
```

**예시**:
- "사용자는 여러 개의 번역 기록을 가질 수 있다."
- "번역 기록은 반드시 한 명의 사용자에게 속한다."

### 1:1 관계

```
"A는 하나의 B를 가진다."
"B는 반드시 하나의 A에 속한다."
```

**예시**:
- "사용자는 하나의 프로필을 가진다."
- "프로필은 반드시 한 명의 사용자에게 속한다."

### N:M 관계

```
"A는 여러 개의 B와 연결될 수 있다."
"B는 여러 개의 A와 연결될 수 있다."
```

**예시**:
- "사용자는 여러 개의 관심 태그를 가질 수 있다."
- "태그는 여러 명의 사용자와 연결될 수 있다."

### Cascade 관계

```
"A가 삭제되면 모든 B도 함께 삭제된다."
```

**예시**:
- "사용자가 삭제되면 모든 번역 기록도 함께 삭제된다."

---

## 제약 조건 패턴

### 필수/선택

```
"X는 반드시 제공되어야 한다."
"Y는 선택 사항이다."
```

### 유일성

```
"X는 중복될 수 없다."
```

### 형식 검증

```
"X는 반드시 Y 형식이어야 한다."
```

**예시**:
- "이메일은 반드시 유효한 형식이어야 한다. (@ 기호 포함)"

### 값 범위

```
"X는 A, B, C 중 하나여야 한다."
"Y는 최소 N 이상이어야 한다."
```

**예시**:
- "선호 언어는 '한국어' 또는 '영어'만 가능하다."
- "표시 이름은 최소 1자 이상이어야 한다."

### 자동 생성

```
"X는 시스템이 자동으로 생성한다."
```

---

## 생명주기 작성 가이드

### 생성 (Create)

```
요청자가 생성을 요청한다
    ↓
[검증 단계 1]
    ↓
[검증 단계 2]
    ↓
엔티티를 생성한다
    ↓
[자동 설정 단계]
```

### 수정 (Update)

```
요청자가 수정을 요청한다
    ↓
권한을 확인한다
    ↓
[검증 단계]
    ↓
변경 가능한 필드만 수정한다
```

**수정 가능/불가능 필드 명시 필수**

### 삭제 (Delete)

```
요청자가 삭제를 요청한다
    ↓
권한을 확인한다
    ↓
연결된 데이터를 확인한다
    ↓
[Cascade 처리]
    ↓
엔티티를 삭제한다
```

---

## 기술 용어 금지 목록

작성 후 아래 키워드가 없는지 확인한다:

| 금지 영역 | 키워드 |
|---------|-------|
| 데이터베이스 | 테이블, 컬럼, Foreign Key, Primary Key, Index, UUID, VARCHAR, INT, TIMESTAMP |
| 프레임워크 | FastAPI, SQLAlchemy, Alembic, Pydantic |
| 프로토콜 | HTTP, REST, GraphQL, WebSocket |
| 클라우드 | PostgreSQL, MySQL, Redis, S3 |

---

## 검증 체크리스트

domain-model.md 작성 완료 후:

- [ ] 용어 테이블에 모든 핵심 용어 포함
- [ ] 각 용어에 정의와 예시 있음
- [ ] 관계 규칙이 서술형으로 작성됨
- [ ] 모든 관계에 예시 포함
- [ ] 제약 조건에 이유 설명
- [ ] 생명주기 3단계 (생성/수정/삭제) 모두 포함
- [ ] 기술 용어 (테이블, 컬럼, FK, UUID 등) 0개
- [ ] 한글 용어 사용 (영어 병기는 괄호 안에)

