@@ -3,7 +3,140 @@ import { tts } from "./tts.controller.js";
33
44const router = Router ( ) ;
55
6- // POST /tts
6+ /**
7+ * @swagger
8+ * /api/ai/tts:
9+ * post:
10+ * tags:
11+ * - AI
12+ * summary: TTS 음성 생성
13+ * description: |
14+ * 입력한 텍스트를 음성(MP3)으로 변환해 **binary(audio/mpeg)** 로 응답합니다.
15+ * - `voiceKey`가 없으면 `ADULT_FEMALE_DEFAULT`를 기본값으로 사용합니다.
16+ *
17+ * ### Notes (테스트/정책)
18+ * - **CORS 정책**: 브라우저(Swagger UI/HTML 테스트)에서 호출 시, 서버의 CORS 허용 Origin이 아니면 요청이 차단되어 `Failed to fetch`가 발생할 수 있습니다.
19+ * - 로컬 테스트 예: `http://localhost:5500`, `http://127.0.0.1:5500` (Live Server), `http://localhost:5173` (Vite)
20+ * - **Swagger UI 제한**: 응답이 `audio/mpeg`(binary)이므로 Swagger UI에서 재생/미리보기가 환경에 따라 정상 동작하지 않을 수 있습니다.
21+ * - 실제 재생 검증은 **curl로 파일 저장(out.mp3)** 또는 **HTML fetch(blob) 테스트**, **클라이언트(안드로이드) 구현**에서 확인을 권장합니다.
22+ *
23+ * requestBody:
24+ * required: true
25+ * content:
26+ * application/json:
27+ * schema:
28+ * type: object
29+ * properties:
30+ * text:
31+ * type: string
32+ * description: 읽을 문장 (필수)
33+ * example: "어제 라면을 먹고 잤더니 부었어요"
34+ * voiceKey:
35+ * type: string
36+ * description: 보이스 키 (선택, 기본값 ADULT_FEMALE_DEFAULT)
37+ * enum:
38+ * - KID_MALE
39+ * - KID_FEMALE
40+ * - ADULT_MALE_DEFAULT
41+ * - ADULT_FEMALE_DEFAULT
42+ * - ELDER_MALE
43+ * - ELDER_FEMALE
44+ * example: "ADULT_FEMALE_DEFAULT"
45+ * speed:
46+ * type: number
47+ * description: |
48+ * 속도 (선택, 기본값 1.0)
49+ * - ※ 서버 로직에서 지원 중(0 이하 불가). 문서 요구사항에 없다면 프론트는 생략해도 됩니다.
50+ * example: 1.0
51+ * required:
52+ * - text
53+ * examples:
54+ * default:
55+ * summary: 기본 요청 예시
56+ * value:
57+ * text: "어제 라면을 먹고 잤더니 부었어요"
58+ * voiceKey: "ADULT_FEMALE_DEFAULT"
59+ *
60+ * responses:
61+ * 200:
62+ * description: 성공 (MP3 바이너리 스트림)
63+ * content:
64+ * audio/mpeg:
65+ * schema:
66+ * type: string
67+ * format: binary
68+ * 400:
69+ * description: 잘못된 요청 (AI003) - text 누락/빈 문자열 또는 voiceKey/speed 검증 실패
70+ * content:
71+ * application/json:
72+ * schema:
73+ * $ref: "#/components/schemas/ErrorResponse"
74+ * examples:
75+ * missingText:
76+ * summary: text 누락/빈 문자열
77+ * value:
78+ * success: false
79+ * error:
80+ * code: "AI003"
81+ * message: "요청 값이 올바르지 않습니다"
82+ * detail:
83+ * field: "text"
84+ * invalidVoiceKey:
85+ * summary: voiceKey가 enum에 없음
86+ * value:
87+ * success: false
88+ * error:
89+ * code: "AI003"
90+ * message: "요청 값이 올바르지 않습니다"
91+ * detail:
92+ * field: "voiceKey"
93+ * invalidSpeed:
94+ * summary: speed가 0 이하
95+ * value:
96+ * success: false
97+ * error:
98+ * code: "AI003"
99+ * message: "요청 값이 올바르지 않습니다"
100+ * detail:
101+ * field: "speed"
102+ * 408:
103+ * description: AI 응답 시간 초과 (AI001)
104+ * content:
105+ * application/json:
106+ * schema:
107+ * $ref: "#/components/schemas/ErrorResponse"
108+ * example:
109+ * success: false
110+ * error:
111+ * code: "AI001"
112+ * message: "AI 응답 시간 초과"
113+ * detail: null
114+ * 500:
115+ * description: AI 모델 처리 오류(AI002) 또는 서버 내부 오류(SERVER_ERROR)
116+ * content:
117+ * application/json:
118+ * schema:
119+ * $ref: "#/components/schemas/ErrorResponse"
120+ * examples:
121+ * aiModelError:
122+ * summary: AI 모델 처리 오류
123+ * value:
124+ * success: false
125+ * error:
126+ * code: "AI002"
127+ * message: "AI 모델 처리 중 오류"
128+ * detail: null
129+ * serverError:
130+ * summary: 서버 내부 오류
131+ * value:
132+ * success: false
133+ * error:
134+ * code: "SERVER_ERROR"
135+ * message: "서버 내부 오류가 발생했습니다"
136+ * detail: null
137+ */
138+
139+ // POST /api/ai/tts
7140router . post ( "/" , tts ) ;
8141
9- export default router ;
142+ export default router ;
0 commit comments