돌아가기 5단계 - 사용자 및 역할
프로젝트에 참여할 멤버를 추가하고 역할을 할당하는 마지막 단계입니다.

## 멤버 추가

워크스페이스 멤버 중 프로젝트에 참여할 사용자를 선택하여 추가합니다.

## 역할 할당

추가된 각 멤버에게 역할을 할당합니다.

| 역할 | 설명 |
|------|------|
| **리더(Leader)** | 프로젝트를 총괄하는 리더 역할 |
| **매니저(Manager)** | 프로젝트 운영을 관리하는 매니저 역할 |

:::note[역할 변경]
프로젝트 생성 후에도 멤버의 역할을 변경하거나 새로운 멤버를 추가할 수 있습니다.
:::

## 프로젝트 생성

모든 설정이 완료되면 **"생성"** 버튼을 클릭하여 프로젝트를 생성합니다.

```mermaid
graph LR
  A["생성 클릭"] --> B{결과}
  B -->|성공| C["태스크 관리 화면으로 이동"]
  B -->|실패| D["오류 단계로 이동 + 오류 메시지 표시"]

  style C fill:#ecfdf5,stroke:#10b981
  style D fill:#fef2f2,stroke:#ef4444
```

:::caution[생성 실패 시]
서버 오류가 발생하면 오류가 발생한 단계로 자동 이동하며, 해당 필드에 오류 메시지가 표시됩니다. 오류를 수정한 후 다시 생성을 시도하세요.
:::

## API 흐름

5단계는 다른 단계와 달리 **Draft 임시 저장이 아닌 최종 프로젝트 생성**을 수행합니다. "생성" 버튼을 클릭하면 아래 순서로 API가 호출됩니다.

### 1. 단계별 데이터 검증 — `POST /projects/`

멤버-역할 데이터를 `phase: 5`와 함께 전송하여 검증합니다.

**Request**

```json
POST /projects/

{
  "phase": 5,
  "member_roles": [
    { "member": 12, "role": "leader" },
    { "member": 34, "role": "manager" },
    { "member": 56, "role": "manager" }
  ]
}
```

| 필드 | 타입 | 필수 | 설명 |
|------|------|------|------|
| `phase` | `integer` | 필수 | 현재 단계 번호 (`5`) |
| `member_roles` | `array` | 필수 | 멤버-역할 매핑 목록 |
| `member_roles[].member` | `integer` | 필수 | 워크스페이스 멤버 ID |
| `member_roles[].role` | `string` | 필수 | 할당할 역할 코드 |

:::note[빈 멤버 필터링]
멤버가 선택되지 않은 행(`member`가 falsy인 항목)은 자동으로 필터링되어 전송되지 않습니다.
:::

**Response (201 Created)**

```json
{
  "member_roles": [
    { "member": 12, "role": "leader" },
    { "member": 34, "role": "manager" }
  ]
}
```

### 2. 기본 역할 목록 조회 — `GET /projects/default_roles/`

멤버 설정 화면 진입 시 프로젝트에서 사용 가능한 기본 역할 목록을 조회합니다.

**Request**

```
GET /projects/default_roles/
```

**Response (200 OK)**

```json
[
  { "id": 1, "display_name": "리더", "code": "leader" },
  { "id": 2, "display_name": "매니저", "code": "manager" }
]
```

### 3. 최종 프로젝트 생성 — `POST /projects/`

5단계 검증이 성공하면 Draft에서 1~4단계의 모든 누적 데이터를 조회한 뒤, 5단계 데이터와 병합하여 **`phase` 필드 없이** 최종 프로젝트 생성 API를 호출합니다.

**Request**

```json
POST /projects/

{
  "title": "자동차 객체 검출 프로젝트",
  "description": "COCO 데이터셋을 사용한 자동차 객체 검출 어노테이션",
  "category": "image",
  "access_level": "public",
  "caution": "sensitive_content",
  "image": "https://storage.example.com/thumbnails/abc123.png",
  "data_collection": 1,
  "configuration": {
    "schema_type": "dm_schema",
    "classification": { ... }
  },
  "can_discard": false,
  "count_max_assignments_per_task": 3,
  "project_plugins": [],
  "member_roles": [
    { "member": 12, "role": "leader" },
    { "member": 34, "role": "manager" }
  ]
}
```

:::tip[phase 없이 전송]
최종 생성 요청에는 `phase` 필드가 포함되지 않습니다. `phase`가 없으면 서버는 단계별 검증이 아닌 실제 프로젝트 생성을 수행합니다.
:::

**Response (201 Created)**

프로젝트가 성공적으로 생성되면 생성된 프로젝트 정보가 반환됩니다.

```json
{
  "id": 42,
  "title": "자동차 객체 검출 프로젝트",
  "description": "COCO 데이터셋을 사용한 자동차 객체 검출 어노테이션",
  "category": "image",
  "access_level": "public",
  "data_collection": 1,
  "configuration": { ... },
  "can_discard": false,
  "count_max_assignments_per_task": 3,
  "project_plugins": [],
  "member_roles": [...]
}
```

성공 시 반환된 `id`를 사용하여 **태스크 관리 화면** (`/projects/{id}/task/manage/tasks`)으로 자동 이동합니다.

**Error Response (400 Bad Request)**

최종 생성 시 여러 단계에 걸친 오류가 반환될 수 있습니다. 시스템은 첫 번째 오류가 있는 단계로 자동 이동합니다.

```json
{
  "title": ["이 필드는 필수 항목입니다."],
  "data_collection": ["유효하지 않은 pk \"999\" - 객체가 존재하지 않습니다."],
  "configuration": ["유효하지 않은 설정입니다."]
}
```

### 전체 API 흐름 요약

```mermaid
graph TD
  A["생성 클릭"] --> B["POST /projects/ (phase: 5)\n멤버-역할 검증"]
  B -->|성공| C["GET /drafts/CREATE/\n1~4단계 Draft 조회"]
  C --> D["POST /projects/ (phase 없음)\nDraft + 5단계 병합하여 최종 생성"]
  D -->|201 Created| E["태스크 관리 화면으로 이동\n/projects/{id}/task/manage/tasks"]
  D -->|400 Error| F["오류 발생 단계로 이동\n필드별 오류 메시지 표시"]
  B -->|실패| G["5단계에서 오류 표시"]

  style E fill:#ecfdf5,stroke:#10b981
  style F fill:#fef2f2,stroke:#ef4444
  style G fill:#fef2f2,stroke:#ef4444
```