# {PROJECT_NAME} PRD (Detailed)

> 이 문서가 법. 여기 없으면 안 만듦. 여기 있으면 반드시 만듦.
>
> 작성일: {DATE}
> 버전: 1.0
> 상태: Draft / Review / Approved

---

## 1. 개요

### 1.1 한 줄 요약
<!-- 이 앱이 뭔지 한 문장으로. "~를 위한 ~앱" 형식 추천 -->

**[타겟 사용자]**를 위한 **[핵심 가치]** 웹앱

예시: "바쁜 직장인을 위한 간편 식단 관리 웹앱"

### 1.2 성공 지표 (KPI)
<!-- 이 프로젝트가 성공했다는 걸 어떻게 알 수 있나? -->

| 지표 | 목표 | 측정 방법 | 기간 |
|------|------|----------|------|
| DAU | 1,000명 | Google Analytics | 출시 후 3개월 |
| 회원가입 전환율 | 30% | 랜딩→가입 비율 | 출시 후 1개월 |
| 리텐션 (D7) | 40% | 7일 후 재방문율 | 출시 후 1개월 |
| NPS | 50+ | 설문 조사 | 출시 후 2개월 |

### 1.3 출시 일정

| 마일스톤 | 예상 일자 | 담당 |
|----------|----------|------|
| PRD 확정 | YYYY-MM-DD | PM |
| 디자인 완료 | YYYY-MM-DD | Designer |
| 개발 완료 | YYYY-MM-DD | Dev |
| QA 완료 | YYYY-MM-DD | QA |
| 출시 | YYYY-MM-DD | All |

---

## 2. 문제 정의

### 2.1 현재 문제
<!-- 사용자가 겪고 있는 문제. 구체적으로. -->

| 문제 | 심각도 | 빈도 | 현재 해결책 |
|------|--------|------|-------------|
| [문제 1] | 높음/중간/낮음 | 매일/주간/월간 | [기존에 어떻게 해결하나?] |
| [문제 2] | | | |
| [문제 3] | | | |

### 2.2 경쟁사 분석

| 경쟁사 | 강점 | 약점 | 우리의 차별점 |
|--------|------|------|---------------|
| [경쟁사 A] | [강점] | [약점] | [우리가 더 잘하는 것] |
| [경쟁사 B] | | | |
| 직접 해결 (엑셀 등) | | | |

### 2.3 우리의 해결책
<!-- 이 앱이 어떻게 해결하나? -->

**핵심 가치 제안**: [한 문장으로]

**차별화 포인트**:
1. [차별점 1]
2. [차별점 2]
3. [차별점 3]

---

## 3. 타겟 사용자

### 3.1 주요 사용자 (Primary)
- **누구**: [예: 20-30대 직장인]
- **특징**: [예: 시간이 없음, 모바일 선호]
- **목표**: [예: 건강한 식단을 쉽게 관리하고 싶음]
- **Pain Point**: [예: 매번 뭘 먹을지 고민]

**페르소나**:
> 김지현 (29세, 마케터)
> "퇴근하고 나면 너무 피곤해서 건강한 식단을 챙기기 어려워요.
> 간편하게 뭘 먹을지 알려주는 앱이 있으면 좋겠어요."

### 3.2 부가 사용자 (Secondary)
- **누구**: [예: 헬스 트레이너]
- **목표**: [예: 고객 식단 관리]

### 3.3 비사용자 (Anti-Persona)
<!-- 이 앱이 타겟하지 않는 사용자 -->
- [예: 전문 영양사 - 이미 전문 도구 사용]

---

## 4. 핵심 기능

### P0 (Must Have) - 없으면 출시 불가
| 기능 | 설명 | 완료 조건 | 담당 |
|------|------|-----------|------|
| 회원가입/로그인 | 소셜 로그인 (Google, Kakao) | 로그인 후 대시보드 진입 | BE |
| [기능 2] | [설명] | [완료 조건] | |
| [기능 3] | [설명] | [완료 조건] | |

### P1 (Should Have) - 출시 후 1주 내
| 기능 | 설명 | 완료 조건 | 담당 |
|------|------|-----------|------|
| [기능 1] | [설명] | [완료 조건] | |

### P2 (Nice to Have) - 추후 검토
| 기능 | 설명 | 예상 시점 | 비고 |
|------|------|----------|------|
| [기능 1] | [설명] | v1.1 | |

---

## 5. Constraints (AI 경계) ⚠️

> **이 섹션은 필수입니다. AI가 임의로 판단하지 않도록 명시적으로 작성하세요.**
> **AI는 생략에서 추론하지 않습니다. 명시되지 않으면 구현하지 않습니다.**

### ✅ ALWAYS (무조건 실행)
<!-- 조건 없이 항상 해야 하는 것 -->
- [ ] 모든 사용자 입력 검증 (빈 값, 형식, 길이)
- [ ] 모든 API 응답에 적절한 HTTP 상태 코드
- [ ] 에러 발생 시 로깅 (console.error 아님, 로깅 시스템 사용)
- [ ] 커밋 전 테스트 실행
- [ ] TypeScript strict 모드
- [ ] 에러 바운더리로 예외 처리
- [ ] API 요청에 로딩/에러 상태 표시
- [ ] 환경별 설정 분리 (dev/staging/prod)

### ⚠️ ASK FIRST (확인 후 실행)
<!-- 구현 전 반드시 확인이 필요한 것 -->
- [ ] DB 스키마 변경 (마이그레이션 필요)
- [ ] 새 의존성 추가
- [ ] 인증/권한 로직 수정
- [ ] API 엔드포인트 추가/삭제
- [ ] 환경 변수 추가
- [ ] 외부 API 연동
- [ ] 결제/과금 관련 로직
- [ ] 사용자 데이터 삭제 로직

### 🚫 NEVER (절대 금지)
<!-- 어떤 상황에서도 해서는 안 되는 것 -->
- [ ] **스펙(이 문서)에 없는 기능 구현**
- [ ] 하드코딩된 시크릿/API 키
- [ ] console.log 프로덕션 배포
- [ ] `any` 타입 사용 (`unknown` 사용)
- [ ] 테스트 없이 커밋
- [ ] 에러 무시 (catch 후 아무것도 안 함)
- [ ] 사용자 입력 직접 SQL/HTML 삽입
- [ ] 민감 정보 로깅 (비밀번호, 토큰 등)
- [ ] `!important` CSS 남용
- [ ] 동기적 localStorage/sessionStorage 남용

### ❌ Out of Scope (이번 버전에서 안 함)
<!-- 명시하지 않으면 AI가 "당연히 필요하겠지"라고 추가할 수 있음 -->
| 기능 | 이유 | 예정 버전 |
|------|------|----------|
| 다국어 지원 | v2에서 검토 | v2.0 |
| 다크모드 | 우선순위 낮음 | v1.2 |
| 네이티브 앱 | 웹 먼저 검증 | 미정 |
| [기능 X] | [이유] | [예정] |
| [기능 Y] | [이유] | [예정] |

---

## 6. Edge Cases (필수) ⚠️

> **각 기능당 최소 3개의 엣지 케이스를 정의하세요.**
> **빈 테이블은 허용되지 않습니다. AI가 임의로 추론하지 않도록 명시하세요.**

### 6.1 회원가입

| 상황 | 입력 | 예상 결과 | 우선순위 |
|------|------|----------|----------|
| 빈 이메일 | "" | 에러: "이메일을 입력하세요" | P0 |
| 잘못된 형식 | "abc" | 에러: "올바른 이메일 형식이 아닙니다" | P0 |
| 이미 가입된 이메일 | "exist@test.com" | 에러: "이미 가입된 이메일입니다" | P0 |
| 비밀번호 너무 짧음 | "123" | 에러: "8자 이상 입력하세요" | P0 |
| 비밀번호 불일치 | pw1 != pw2 | 에러: "비밀번호가 일치하지 않습니다" | P0 |
| 특수문자 없는 비밀번호 | "abcd1234" | 에러: "특수문자를 포함하세요" | P1 |

### 6.2 로그인

| 상황 | 입력 | 예상 결과 | 우선순위 |
|------|------|----------|----------|
| 미가입 이메일 | "new@test.com" | 에러: "가입되지 않은 이메일입니다" | P0 |
| 잘못된 비밀번호 | 틀린 pw | 에러: "비밀번호가 일치하지 않습니다" | P0 |
| 소셜 로그인 취소 | 취소 버튼 | 로그인 페이지로 복귀, 에러 없음 | P0 |
| 5회 연속 실패 | 5번 틀림 | 계정 15분 잠금 + 안내 메시지 | P0 |
| 네트워크 끊김 | 요청 중 오프라인 | 에러: "네트워크 연결을 확인하세요" + 재시도 버튼 | P0 |
| 토큰 만료 | 만료된 세션 | 자동 로그아웃 + 로그인 유도 | P0 |

### 6.3 [기능 2]

| 상황 | 입력 | 예상 결과 | 우선순위 |
|------|------|----------|----------|
| [상황 1] | [입력] | [결과] | P0 |
| [상황 2] | [입력] | [결과] | P0 |
| [상황 3] | [입력] | [결과] | P0 |
| [상황 4] | [입력] | [결과] | P1 |

### 6.4 [기능 3]

| 상황 | 입력 | 예상 결과 | 우선순위 |
|------|------|----------|----------|
| [상황 1] | [입력] | [결과] | P0 |
| [상황 2] | [입력] | [결과] | P0 |
| [상황 3] | [입력] | [결과] | P0 |

### 6.5 공통 엣지 케이스

| 상황 | 예상 동작 | 우선순위 |
|------|----------|----------|
| 네트워크 끊김 | 오프라인 안내 + 재시도 버튼 | P0 |
| 토큰 만료 중 요청 | 자동 갱신 또는 로그인 유도 | P0 |
| 동시 수정 (다른 탭/기기) | 충돌 알림 + 새로고침 유도 | P1 |
| 대용량 데이터 | 페이지네이션/무한스크롤 | P1 |
| 브라우저 뒤로가기 | 상태 유지 또는 적절히 리셋 | P1 |
| 새로고침 | 현재 상태 유지 (가능하면) | P1 |

---

## 7. 사용자 플로우

### 7.1 핵심 플로우 다이어그램

```
[랜딩] → [회원가입] → [온보딩] → [대시보드]
                                      ↓
                              [핵심 기능 사용]
                                      ↓
                              [결과 확인/저장]
```

### 7.2 플로우별 상세

#### 회원가입 플로우
```
1. 랜딩 페이지 방문
   ↓
2. "시작하기" 클릭
   ↓
3. 소셜 로그인 선택 (Google/Kakao)
   ↓
4. 권한 동의
   ↓
5. 추가 정보 입력 (선택)
   ↓
6. 대시보드 진입
```

#### [핵심 기능] 플로우
```
1. [시작 조건]
   ↓
2. [단계 1]
   ↓
3. [단계 2]
   ↓
4. [완료 상태]
```

---

## 8. 화면 구조

### 8.1 사이트맵
```
/                     # 랜딩 페이지
├── /login            # 로그인
├── /signup           # 회원가입
├── /onboarding       # 온보딩 (첫 사용자)
├── /dashboard        # 대시보드 (로그인 필요)
│   ├── /dashboard/[기능1]
│   ├── /dashboard/[기능2]
│   └── /dashboard/history
├── /settings         # 설정
│   ├── /settings/profile
│   ├── /settings/notification
│   └── /settings/account
└── /404              # 에러 페이지
```

### 8.2 주요 화면 명세

#### 랜딩 페이지 (/)
- **목적**: 서비스 소개 + 가입 유도
- **디자인**: [Figma 링크]
- **핵심 요소**:
  - Hero 섹션 (한 줄 요약 + CTA)
  - 문제/해결 섹션
  - 기능 소개 (3개)
  - 사회적 증거 (후기, 숫자)
  - 가격표 (있으면)
  - FAQ
  - Footer

#### 대시보드 (/dashboard)
- **목적**: 핵심 기능 제공
- **디자인**: [Figma 링크]
- **핵심 요소**:
  - 네비게이션 (상단/사이드)
  - [요소 1]
  - [요소 2]
- **상태별 UI**:
  - 로딩 중: 스켈레톤 UI
  - 데이터 없음: Empty State + CTA
  - 에러: 에러 메시지 + 재시도 버튼

### 8.3 상태별 UI 정의

| 화면 | 로딩 | 빈 상태 | 에러 |
|------|------|---------|------|
| 대시보드 | 스켈레톤 | "아직 데이터가 없어요" + CTA | "불러오기 실패" + 재시도 |
| 목록 | 스켈레톤 (3줄) | "항목이 없어요" + 추가 버튼 | 인라인 에러 |
| 상세 | 전체 스켈레톤 | N/A | 전체 에러 화면 |

---

## 9. 디자인 시스템

### 9.1 색상
| 용도 | 색상 | HEX |
|------|------|-----|
| Primary | [색상명] | #0EA5E9 |
| Secondary | [색상명] | #64748B |
| Success | Green | #22C55E |
| Warning | Yellow | #EAB308 |
| Error | Red | #EF4444 |
| Background | White | #FFFFFF |
| Text | Dark | #0F172A |

### 9.2 타이포그래피
| 용도 | 폰트 | 크기 | 굵기 |
|------|------|------|------|
| H1 | Pretendard | 32px | Bold |
| H2 | Pretendard | 24px | SemiBold |
| Body | Pretendard | 16px | Regular |
| Caption | Pretendard | 14px | Regular |

### 9.3 반응형 브레이크포인트
| 이름 | 범위 | 레이아웃 |
|------|------|----------|
| Mobile | ~767px | 1 column |
| Tablet | 768~1023px | 2 column |
| Desktop | 1024px~ | 3+ column |

### 9.4 컴포넌트
- **버튼**: Primary / Secondary / Ghost / Danger
- **입력**: Text / Select / Checkbox / Radio
- **카드**: Default / Hover / Selected
- **모달**: Confirm / Alert / Form

### 9.5 디자인 리소스
- Figma: [링크]
- 아이콘: Lucide / Heroicons
- 일러스트: [출처]

---

## 10. 기술 스택

### 10.1 프론트엔드
| 구분 | 선택 | 버전 | 이유 |
|------|------|------|------|
| 프레임워크 | Next.js | 14.x | SSR + App Router |
| 언어 | TypeScript | 5.x | 타입 안정성 |
| 스타일링 | Tailwind CSS | 3.x | 빠른 개발 |
| 상태관리 | Zustand | 4.x | 단순함 |
| 폼 | React Hook Form | 7.x | 성능 |
| 유효성검사 | Zod | 3.x | 타입 연동 |

### 10.2 백엔드
| 구분 | 선택 | 버전 | 이유 |
|------|------|------|------|
| 런타임 | Node.js | 20.x | LTS |
| 프레임워크 | Express / Fastify | - | [이유] |
| 언어 | TypeScript | 5.x | FE와 통일 |
| ORM | Prisma | 5.x | 타입 안전 |
| 유효성검사 | Zod | 3.x | FE와 공유 |

### 10.3 데이터베이스
| 구분 | 선택 | 이유 |
|------|------|------|
| 메인 DB | PostgreSQL | 안정성, JSON 지원 |
| 캐시 | Redis | 세션, 캐싱 |
| 파일 저장 | S3 / Cloudflare R2 | 비용 |

### 10.4 인프라
| 구분 | 선택 | 이유 |
|------|------|------|
| 호스팅 (FE) | Vercel | Next.js 최적화 |
| 호스팅 (BE) | Railway / Render | 간편함 |
| DB 호스팅 | Supabase / Neon | 무료 티어 |
| 모니터링 | Sentry | 에러 추적 |
| 분석 | Google Analytics | 무료 |

### 10.5 배포 환경

| 환경 | URL | 용도 | 배포 조건 |
|------|-----|------|----------|
| Development | localhost:3000 | 개발 | - |
| Staging | staging.example.com | QA/테스트 | PR 머지 시 |
| Production | example.com | 실서비스 | 수동 승인 |

---

## 11. 데이터 모델

### 11.1 ERD
```
┌─────────┐       ┌─────────┐
│  users  │───1:N─│  posts  │
└─────────┘       └─────────┘
     │
     1
     │
     N
┌─────────┐
│settings │
└─────────┘
```

### 11.2 테이블 정의

#### users
| 컬럼 | 타입 | 설명 | 제약 | 인덱스 |
|------|------|------|------|--------|
| id | uuid | PK | NOT NULL | PK |
| email | varchar(255) | 이메일 | UNIQUE, NOT NULL | UNIQUE |
| name | varchar(100) | 이름 | NOT NULL | - |
| avatar_url | text | 프로필 이미지 | NULL 가능 | - |
| provider | varchar(20) | 소셜 로그인 제공자 | NOT NULL | - |
| provider_id | varchar(255) | 소셜 ID | NOT NULL | IDX |
| created_at | timestamp | 생성일 | DEFAULT now() | - |
| updated_at | timestamp | 수정일 | DEFAULT now() | - |

#### [테이블 2]
| 컬럼 | 타입 | 설명 | 제약 | 인덱스 |
|------|------|------|------|--------|
| | | | | |

### 11.3 인덱스 전략
| 테이블 | 인덱스 | 컬럼 | 용도 |
|--------|--------|------|------|
| users | idx_users_email | email | 로그인 조회 |
| users | idx_users_provider | provider, provider_id | 소셜 로그인 |
| posts | idx_posts_user_created | user_id, created_at DESC | 사용자별 목록 |

### 11.4 캐싱 전략
| 키 패턴 | TTL | 무효화 조건 |
|---------|-----|-------------|
| user:{id} | 1시간 | 프로필 수정 시 |
| posts:user:{id}:page:{n} | 5분 | 새 글 작성 시 |

---

## 12. API 설계

### 12.1 공통 사항

**Base URL**: `https://api.example.com/v1`

**인증**: Bearer Token (JWT)
```
Authorization: Bearer {access_token}
```

**공통 응답 형식**:
```json
// 성공
{
  "data": { ... },
  "meta": { "total": 100, "page": 1 }
}

// 실패
{
  "error": {
    "code": "ERROR_CODE",
    "message": "사용자 메시지",
    "details": { ... }
  }
}
```

### 12.2 인증 API

#### POST /auth/login
소셜 로그인

**Request**:
```json
{
  "provider": "google",
  "token": "소셜_토큰"
}
```

**Response** (200):
```json
{
  "data": {
    "access_token": "jwt_token",
    "refresh_token": "refresh_token",
    "user": {
      "id": "uuid",
      "email": "user@example.com",
      "name": "홍길동"
    }
  }
}
```

**Errors**:
| 코드 | 상황 |
|------|------|
| 400 | 잘못된 토큰 |
| 401 | 인증 실패 |

#### POST /auth/refresh
토큰 갱신

**Request**:
```json
{
  "refresh_token": "refresh_token"
}
```

### 12.3 핵심 리소스 API

#### GET /api/[리소스]
목록 조회

**Query Parameters**:
| 파라미터 | 타입 | 필수 | 설명 |
|----------|------|------|------|
| page | number | N | 페이지 (기본 1) |
| limit | number | N | 개수 (기본 20, 최대 100) |
| sort | string | N | 정렬 (created_at:desc) |

**Response** (200):
```json
{
  "data": [
    {
      "id": "uuid",
      "title": "제목",
      "created_at": "2024-01-01T00:00:00Z"
    }
  ],
  "meta": {
    "total": 100,
    "page": 1,
    "limit": 20,
    "total_pages": 5
  }
}
```

#### POST /api/[리소스]
생성

**Request**:
```json
{
  "title": "제목",
  "content": "내용"
}
```

**Response** (201):
```json
{
  "data": {
    "id": "uuid",
    "title": "제목",
    "content": "내용",
    "created_at": "2024-01-01T00:00:00Z"
  }
}
```

**Errors**:
| 코드 | 상황 |
|------|------|
| 400 | 유효성 검사 실패 |
| 401 | 인증 필요 |

#### GET /api/[리소스]/:id
단건 조회

#### PATCH /api/[리소스]/:id
수정

#### DELETE /api/[리소스]/:id
삭제

---

## 13. 에러 처리

### 13.1 HTTP 상태 코드
| 코드 | 의미 | 사용 상황 |
|------|------|----------|
| 200 | OK | 성공 |
| 201 | Created | 생성 성공 |
| 400 | Bad Request | 입력 오류 |
| 401 | Unauthorized | 인증 필요 |
| 403 | Forbidden | 권한 없음 |
| 404 | Not Found | 리소스 없음 |
| 409 | Conflict | 중복 |
| 422 | Unprocessable | 비즈니스 로직 오류 |
| 500 | Internal Error | 서버 오류 |

### 13.2 에러 코드 목록
| 코드 | HTTP | 상황 | 사용자 메시지 |
|------|------|------|---------------|
| AUTH_REQUIRED | 401 | 토큰 없음 | "로그인이 필요합니다" |
| AUTH_INVALID | 401 | 토큰 유효하지 않음 | "다시 로그인해주세요" |
| AUTH_EXPIRED | 401 | 토큰 만료 | "세션이 만료되었습니다" |
| FORBIDDEN | 403 | 권한 없음 | "접근 권한이 없습니다" |
| NOT_FOUND | 404 | 리소스 없음 | "찾을 수 없습니다" |
| VALIDATION_ERROR | 400 | 입력 오류 | [필드별 메시지] |
| DUPLICATE | 409 | 중복 | "이미 존재합니다" |
| INTERNAL_ERROR | 500 | 서버 오류 | "잠시 후 다시 시도해주세요" |

### 13.3 유효성 검사 에러 형식
```json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "입력값을 확인해주세요",
    "details": {
      "email": "올바른 이메일 형식이 아닙니다",
      "password": "8자 이상 입력해주세요"
    }
  }
}
```

---

## 14. Acceptance Criteria (Gherkin) ⚠️

> **각 기능에 대해 정상/실패 시나리오를 모두 작성하세요.**
> **"should NOT" 구문으로 하지 말아야 할 것도 명시하세요.**

```gherkin
Feature: 회원가입

Scenario: 정상 회원가입
  Given 신규 사용자가 회원가입 페이지에서
  When 올바른 이메일과 비밀번호를 입력하고 가입 버튼을 클릭하면
  Then 계정이 생성되어야 함
  And 대시보드로 자동 이동해야 함
  And 환영 이메일이 발송되어야 함
  And 비밀번호는 해시되어 저장되어야 함 (평문 저장 금지)

Scenario: 중복 이메일로 회원가입 시도
  Given 이미 가입된 이메일 "exist@test.com"으로
  When 회원가입을 시도하면
  Then 계정이 생성되지 않아야 함 (NOT)
  And "이미 가입된 이메일입니다" 에러가 표시되어야 함
  And 이메일 필드에 포커스가 가야 함

Scenario: 약한 비밀번호로 회원가입 시도
  Given 8자 미만의 비밀번호로
  When 회원가입을 시도하면
  Then 계정이 생성되지 않아야 함 (NOT)
  And "8자 이상 입력하세요" 에러가 표시되어야 함
  And 비밀번호 강도 표시기가 "약함"을 표시해야 함

Feature: 로그인

Scenario: 정상 로그인
  Given 가입된 사용자 "user@test.com"이
  When 올바른 비밀번호로 로그인하면
  Then 대시보드로 이동해야 함
  And 세션이 생성되어야 함
  And 로그인 시도 횟수가 리셋되어야 함

Scenario: 잘못된 비밀번호로 로그인
  Given 가입된 사용자가
  When 잘못된 비밀번호로 로그인 시도하면
  Then 로그인 되지 않아야 함 (NOT)
  And "비밀번호가 일치하지 않습니다" 표시되어야 함
  And 비밀번호 필드가 초기화되어야 함
  And 로그인 시도 횟수가 증가해야 함
  And 구체적인 실패 이유(이메일 존재 여부 등)를 노출하지 않아야 함 (보안)

Scenario: 5회 로그인 실패 시 잠금
  Given 4회 로그인 실패한 사용자가
  When 5번째 잘못된 비밀번호로 시도하면
  Then 계정이 15분간 잠겨야 함
  And "계정이 일시 잠금되었습니다. 15분 후 시도하세요" 표시
  And 관리자에게 알림이 발송되어야 함 (선택)

Scenario: 소셜 로그인 취소
  Given 사용자가 소셜 로그인을 시작했다가
  When 제공자 화면에서 취소하면
  Then 에러 없이 로그인 페이지로 복귀해야 함
  And 이전 입력 상태가 유지되어야 함

Feature: [기능 2]

Scenario: [정상 케이스]
  Given [조건]
  When [행동]
  Then [결과]
  And [추가 확인]

Scenario: [실패 케이스]
  Given [조건]
  When [행동]
  Then [실패 결과] (NOT)
  And [에러 메시지]

Scenario: [엣지 케이스]
  Given [특수 조건]
  When [행동]
  Then [예상 결과]
```

---

## 15. 비기능 요구사항

### 15.1 성능
| 항목 | 목표 | 측정 방법 |
|------|------|----------|
| FCP (First Contentful Paint) | < 1.5초 | Lighthouse |
| LCP (Largest Contentful Paint) | < 2.5초 | Lighthouse |
| TTI (Time to Interactive) | < 3초 | Lighthouse |
| API 응답 (p95) | < 500ms | APM |
| Lighthouse 점수 | > 90점 | Lighthouse |

### 15.2 보안
- [ ] HTTPS 필수 (TLS 1.2+)
- [ ] SQL Injection 방지 (ORM 사용)
- [ ] XSS 방지 (escape, CSP)
- [ ] CSRF 방지 (토큰)
- [ ] CORS 설정 (화이트리스트)
- [ ] Rate Limiting (100 req/min)
- [ ] 민감 데이터 암호화
- [ ] 보안 헤더 설정

### 15.3 접근성 (A11y)
- [ ] 키보드 네비게이션 가능
- [ ] 스크린 리더 호환 (ARIA)
- [ ] 색상 대비 4.5:1 이상
- [ ] 포커스 표시 명확
- [ ] 이미지 alt 텍스트

### 15.4 SEO
- [ ] 시맨틱 HTML
- [ ] 메타 태그 (title, description)
- [ ] OG 태그 (소셜 공유)
- [ ] sitemap.xml
- [ ] robots.txt

---

## 16. 테스트 계획

### 16.1 단위 테스트

| 대상 | 테스트 케이스 | 담당 |
|------|--------------|------|
| 인증 로직 | 토큰 생성/검증/갱신 | BE |
| [핵심 로직 1] | [케이스 목록] | |
| [핵심 로직 2] | [케이스 목록] | |

### 16.2 통합 테스트

| 플로우 | 테스트 케이스 | 담당 |
|--------|--------------|------|
| 회원가입 | 소셜 로그인 → 프로필 생성 → 대시보드 진입 | BE |
| [핵심 플로우] | [케이스] | |

### 16.3 E2E 테스트 (Cypress/Playwright)

| 시나리오 | 단계 | 예상 결과 |
|----------|------|----------|
| 회원가입 | 1. 랜딩 방문 → 2. 가입 클릭 → 3. 소셜 선택 → 4. 권한 동의 | 대시보드 진입 |
| [시나리오 2] | | |

### 16.4 성능 테스트

| 항목 | 조건 | 목표 |
|------|------|------|
| 동시 접속 | 1000명 | 응답 < 1초 |
| DB 쿼리 | 10만 rows | 조회 < 100ms |

---

## 17. 완료 체크리스트 ⚠️

> **이 체크리스트가 모두 완료되어야 "완료"입니다.**
> **부분 완료는 완료가 아닙니다.**

### 기능
- [ ] P0 기능 전체 동작
- [ ] 모든 Edge Case 처리됨 (Section 6 기준)
- [ ] 모든 에러 메시지 사용자 친화적
- [ ] 모든 Acceptance Criteria 통과 (Section 14 기준)

### 품질
- [ ] 테스트 커버리지 > 80%
- [ ] Lighthouse 성능 > 90점
- [ ] Lighthouse 접근성 > 90점
- [ ] TypeScript 에러 0개
- [ ] ESLint 경고/에러 0개
- [ ] 콘솔 에러/경고 0개

### 보안
- [ ] 모든 사용자 입력 검증됨
- [ ] XSS 방지됨
- [ ] SQL Injection 방지됨
- [ ] CORS 설정됨
- [ ] Rate Limiting 적용됨
- [ ] 시크릿 하드코딩 없음
- [ ] HTTPS 적용됨

### 문서
- [ ] README 업데이트됨
- [ ] API 문서 작성됨 (Swagger/Postman)
- [ ] 변경 로그 작성됨
- [ ] 배포 가이드 작성됨

### 배포
- [ ] Staging 환경 테스트 완료
- [ ] Production 배포 완료
- [ ] 모니터링 설정 완료
- [ ] 롤백 계획 준비됨

---

## 18. 마일스톤

| 단계 | 내용 | 산출물 | 완료 조건 | 예상 기간 |
|------|------|--------|-----------|----------|
| M0 | 기획 확정 | PRD v1.0 | PRD 승인 | 1주 |
| M1 | 디자인 | Figma | 디자인 리뷰 통과 | 1주 |
| M2 | 기본 구조 + 인증 | 로그인 동작 | 로그인/회원가입 완료 | 1주 |
| M3 | P0 기능 | 핵심 기능 | P0 전체 완료 | 2주 |
| M4 | P1 기능 + QA | 테스트 완료 | 버그 0개 | 1주 |
| M5 | 배포 | 프로덕션 | 출시 완료 | 1주 |

---

## 19. 리스크 & 대응

| 리스크 | 가능성 | 영향도 | 대응 방안 |
|--------|--------|--------|----------|
| 일정 지연 | 중 | 높음 | P1→P2 이동, 스코프 축소 |
| 기술적 한계 | 낮음 | 중 | 대안 기술 검토 |
| 인력 부족 | 중 | 높음 | 외주/추가 채용 |

---

## 변경 로그

| 날짜 | 버전 | 변경 내용 | 작성자 | 검토자 |
|------|------|----------|--------|--------|
| {DATE} | 1.0 | 최초 작성 | | |

---

## 부록

### A. 용어 정의
| 용어 | 설명 |
|------|------|
| [용어 1] | [설명] |

### B. 참고 자료
- [문서/링크 1]
- [문서/링크 2]

### C. 관련 문서
- 디자인: [Figma 링크]
- API 문서: [Swagger/Postman 링크]
- 기술 스펙: [링크]
