docs(ai-character): Phase 1 검증 기록 정리

This commit is contained in:
Yu Sung
2026-07-27 15:03:42 +09:00
parent 185cce6177
commit ba43dd829e
4 changed files with 1460 additions and 72 deletions

View File

@@ -26,6 +26,7 @@
3. 사용자 인터뷰 결정과 최초 API Contract가 충돌하면 이 문서의 “API 계약 보정사항”을 우선한다.
4. 미결 사항과 외부 의존 계약은 추측으로 구현하지 않는다. **미결**에는 추천안을, **외부 의존**에는 제공 주체와 영향을 함께 기록한다.
5. 완료된 미결 사항과 제공 완료된 외부 의존 계약은 결정일과 결정 내용을 “결정 기록”에 추가한 뒤 관련 수용 기준까지 갱신한다.
6. goal 실행의 objective·순서·완료 증거·범위는 `plan-task.md``Phase Goal``Goal 실행`을 기준으로 한다. goal 수행 중 제품 결정이 바뀌면 이 문서의 결정 기록과 요구사항을 먼저 갱신한다.
---
@@ -231,6 +232,8 @@ AI 캐릭터를 생성하고, AI 캐릭터가 사람 크리에이터처럼 콘
| AUDIO-024 | 확정 | `audio/x-m4a``.m4a` 파일에 한해 호환 MIME으로 허용한다. 실제 MP4/M4A 컨테이너·코덱 검증을 통과해야 하며 다른 확장자와의 조합은 거부한다. |
| AUDIO-025 | 확정 | 오디오 soft delete 성공 시 선택 캐릭터의 오디오 active-only 목록으로 이동하고 성공 알림을 표시한다. 현재 상세 화면에 머물지 않는다. |
| AUDIO-026 | 확정 | 재생 오류를 signed URL 만료로 구분하거나 추정하지 않는다. media error만으로 상세·목록을 자동 재조회하거나 자동 재생하지 않고, 일반 오류와 수동 재시도·페이지 새로고침 안내를 제공한다. |
| AUDIO-027 | 확정 | 오디오 콘텐츠 생성 시 `themeId`는 필수이며, 프론트엔드는 `GET /api/v2/admin/ai-characters/audio-content-themes`로 테마 목록을 불러와 선택 UI를 제공한다. |
| AUDIO-028 | 확정 | 오디오 콘텐츠 테마 목록 조회는 query/body 없이 호출하며 응답의 `themeId`, `themeName`, `imageUrl`만 사용한다. |
수정 화면은 즉시 공개로 재초기화하지 않는다. 서버의 기존 `releaseDateUtc``status`로 공개 방식과 날짜를 초기화하고, 관리자가 바꾸지 않으면 기존 값을 유지한다.
@@ -314,7 +317,7 @@ AI 캐릭터를 생성하고, AI 캐릭터가 사람 크리에이터처럼 콘
| ID | 상태 | 요구사항 |
|---|---|---|
| FILE-001 | 확정 | 캐릭터·오디오 cover·시리즈·커뮤니티 image의 최대 크기는 10MB다. |
| FILE-001 | 확정 | 캐릭터·오디오 cover·시리즈·커뮤니티 image의 최대 크기는 `10,485,760 bytes` 이하다. `10,485,761 bytes`부터 거부한다. |
| FILE-002 | 확정 | 기본 image 형식은 JPEG(`.jpg`/`.jpeg`, `image/jpeg`)와 PNG(`.png`, `image/png`)다. WebP 등 다른 형식은 허용하지 않는다. |
| FILE-003 | 확정 | GIF(`.gif`, `image/gif`)는 커뮤니티 image에서만 허용한다. 캐릭터·시리즈·오디오 cover에서는 거부한다. |
| FILE-004 | 확정 | 커뮤니티 JPEG/PNG image는 자유 aspect ratio로 크롭하며 결과의 최대 가로 폭은 800px, 세로는 선택한 crop ratio에 따라 결정한다. |
@@ -334,7 +337,7 @@ AI 캐릭터를 생성하고, AI 캐릭터가 사람 크리에이터처럼 콘
#### Image crop UI 흐름
1. 새 image 선택 직후 resource별 MIME과 10MB 제한을 먼저 검증한다.
1. 새 image 선택 직후 resource별 MIME과 `10,485,760 bytes` 이하 제한을 먼저 검증한다.
2. 커뮤니티 GIF이면 원본 가로를 검사한다. 800px 초과는 inline 오류로 차단하고, 800px 이하는 crop Dialog 없이 원본 비율과 animation을 유지한다.
3. 캐릭터 image, 커뮤니티 JPEG/PNG, 시리즈 image, 오디오 콘텐츠 cover이면 crop Dialog를 열고 resource별 자유/고정 aspect ratio를 적용한다.
4. crop Dialog에는 현재 crop 영역과 예상 결과 크기를 표시한다.
@@ -602,6 +605,7 @@ Phase 2~6에서 추가되는 오류는 구현 전에 정확한 비2xx status와
| 인증 | POST | `/member/logout` | 제공됨, 공통 endpoint, Bearer header, body 없음 |
| 캐릭터 | GET, POST | `/api/v2/admin/ai-characters` | 제공됨, 필드 보정 필요 |
| 캐릭터 | GET, PUT | `/api/v2/admin/ai-characters/{characterId}` | 제공됨, 필드 보정 필요 |
| 오디오 테마 | GET | `/api/v2/admin/ai-characters/audio-content-themes` | 제공됨, query/body 없음 |
| 오디오 | GET, POST | `/api/v2/admin/ai-characters/{characterId}/audio-contents` | 제공됨, 생성 필드 보정 필요 |
| 오디오 | GET, PUT | `.../audio-contents/{contentId}` | 제공됨 |
| 시리즈 | GET, POST | `/api/v2/admin/ai-characters/{characterId}/series` | 제공됨, enum 보정 필요 |
@@ -623,6 +627,7 @@ Phase 2~6에서 추가되는 오류는 구현 전에 정확한 비2xx status와
| 생성 `isActive` | Character, Audio, Community 예시에 존재 | 모든 생성 요청에서 제거, 서버가 초기값 결정 |
| 수정 `isActive` | 수정 예시에 존재 | 일반 수정에서는 key를 생략하고 soft delete에만 `false`를 보낸다. `true`는 전송하지 않는다. |
| Audio status | 예시에 `OPEN` | 허용값은 `OPEN`, `SCHEDULED`이며 서버 계산 |
| Audio create `themeId` | 누락 | 생성 시 필수이며 오디오 테마 목록 endpoint에서 선택한 `themeId`를 보낸다. |
| Series state | 예시에 `OPEN` | `PROCEEDING`, `SUSPEND`, `COMPLETE`만 허용 |
| Series 생성 state | 요청 예시에 `OPEN` | 생성 요청에서 state 제거 |
| Series 수정 state | 필수처럼 표현 | 선택 필드, 미선택 시 생략하여 기존 값 유지 |
@@ -692,7 +697,7 @@ Phase 2~6에서 추가되는 오류는 구현 전에 정확한 비2xx status와
- MP3, AAC, M4A 업로드의 진행률·취소·재시도와 `1,024,000,000 bytes` 허용·`1,024,000,001 bytes` 거부 경계 검증이 동작한다.
- 오디오 콘텐츠와 커뮤니티 첨부 audio가 동일한 확장자·MIME·최대 크기·재생 길이 정책을 사용한다.
- `.m4a``audio/mp4``audio/x-m4a`를 허용하되 호환 MIME도 실제 MP4/M4A container·codec 검증을 통과해야 한다.
- 모든 image upload가 10MB와 resource별 JPEG/PNG/GIF 허용 범위를 적용한다.
- 모든 image upload가 `10,485,760 bytes` 이하 제한과 resource별 JPEG/PNG/GIF 허용 범위를 적용한다.
- 캐릭터 image는 `1:1`로 크롭하고 최대 800×800px 결과를 업로드한다.
- 커뮤니티 JPEG/PNG는 자유 비율·최대 800px, Series는 `210:297`·최대 1,000px, Audio cover는 `1:1`·최대 800px crop 결과를 업로드한다.
- JPEG/PNG crop 영역이 resource별 최대 출력 폭보다 작으면 확대하지 않고 가능한 원본 pixel 크기로 업로드한다.
@@ -700,6 +705,7 @@ Phase 2~6에서 추가되는 오류는 구현 전에 정확한 비2xx status와
- 커뮤니티 GIF는 crop Dialog를 열지 않고 원본 비율과 animation을 유지해 등록하며, 원본 가로가 800px을 초과하면 제출 전에 거부한다.
- crop Dialog에서 이동·확대/축소·초기화·미리보기·취소/적용을 keyboard와 pointer로 완료할 수 있다.
- 오디오 목록·상세와 커뮤니티 목록 항목의 첨부 오디오가 재생된다.
- 오디오 콘텐츠 생성 시 테마 목록을 query/body 없이 조회하고 선택한 `themeId`를 request JSON에 포함한다.
- media error를 signed URL 만료로 구분하지 않고 일반 재생 오류를 표시한다. 오류만으로 API를 자동 재조회하거나 자동 재생하지 않으며 사용자가 수동 재시도하거나 페이지를 새로고침할 수 있다.
- 커뮤니티는 전용 상세 GET이나 상세·수정 route 없이 목록 응답 기반 Sheet에서 조회·수정·고정·비활성화·댓글 진입을 제공한다.
- Series에 `OPEN`이나 `MONDAY` 같은 잘못된 값을 보내지 않는다.
@@ -750,7 +756,8 @@ Phase 2~6에서 추가되는 오류는 구현 전에 정확한 비2xx status와
| 2026-07-25 | MP3, AAC, M4A, 최대 decimal 1,024MB(`1,024,000,000 bytes`), 재생 길이 무제한을 사용한다. |
| 2026-07-25 | `audio/x-m4a``.m4a` 파일에만 허용하고 실제 MP4/M4A container·codec을 검증한다. |
| 2026-07-25 | 커뮤니티 첨부 audio도 오디오 콘텐츠와 같은 MP3/AAC/M4A, 최대 1,024MB, 재생 길이 무제한 정책을 사용한다. |
| 2026-07-25 | 공통 image upload 최대 크기는 10MB로 한다. |
| 2026-07-25 | 공통 image upload 최대 크기는 10MB로 한다. exact byte 값은 백엔드 확인 후 PRD·API 계약·구현 상수·경계 test를 같은 값으로 정렬한다. |
| 2026-07-27 | 공통 image upload 10MB의 exact byte를 `10,485,760 bytes`로 확정하고 `10,485,761 bytes`부터 거부한다. |
| 2026-07-25 | image는 JPEG/PNG를 허용하고 GIF는 커뮤니티에만 허용한다. Character는 1:1·800px, Community JPEG/PNG는 자유 비율·800px, Series는 210:297·1,000px, Audio cover는 1:1·800px crop UI를 제공한다. Community GIF는 crop·resize하지 않고 원본 가로 800px 초과 시 등록을 거부한다. |
| 2026-07-25 | JPEG/PNG crop 결과는 선택한 원본 crop 영역보다 확대하지 않고 resource별 800px/1,000px을 최대 출력 폭으로만 사용한다. |
| 2026-07-25 | Series crop 세로는 `round(width × 297 ÷ 210)`으로 계산하고 최대 1,000×1,414px, 검증 오차 1px을 적용한다. |
@@ -765,3 +772,4 @@ Phase 2~6에서 추가되는 오류는 구현 전에 정확한 비2xx status와
| 2026-07-26 | 커뮤니티 전용 상세 GET과 상세·수정 route를 추가하지 않는다. 목록 응답 기반 Sheet를 사용하고 첨부 audio URL 갱신 전용 요청은 만들지 않는다. 사용자 새로고침이나 mutation 후 cache 무효화 등 일반 목록 재조회가 있으면 새 응답 값을 사용한다. |
| 2026-07-26 | 문자열 최대 길이와 배열 최대 개수는 초기 UI 작성 후 각 페이지에서 권고값을 정하고 백엔드 호환 확인 후 확정한다. 그 전에는 제공 계약에 없는 최대값을 추정하지 않는다. |
| 2026-07-26 | 댓글 API·팬 댓글 삭제 권한 오류와 FanTalk 목록·상세·답변 수정·중복 답변 계약은 백엔드 제공 대기 사항으로 분류하고 프론트엔드 Open Questions에서 제외한다. |
| 2026-07-27 | 오디오 콘텐츠 생성에는 `themeId`가 필수이며, 테마 선택지는 `GET /api/v2/admin/ai-characters/audio-content-themes`에서 query/body 없이 조회한다. |