17 KiB
크리에이터 커뮤니티 게시물 본문 번역 PRD
문서 정보
| 항목 | 내용 |
|---|---|
| 상태 | 구현 및 로컬 자동 검증 완료 · 테스트 서버 수동 검증 대기 |
| 작성일 / 최종 수정일 | 2026-09-10 |
| 결정권자 | 요청 사용자 |
| 산출물 범위 | 코드·자동 테스트·MySQL DDL 작성. 실제 DDL 적용·배포·Papago/HTTP 검증은 테스트 서버에서 수행한다. |
| API 계약 | 별도 파일을 만들지 않고 이 문서의 API 계약 절에 통합 |
| 기준 템플릿 | docs/sample/sample-prd.md |
1. 목표와 현재 동작
크리에이터 커뮤니티 게시물의 본문을 한국어·영어·일본어로 제공한다. 작성한 원문은 보존하고, 원문 이외의 지원 언어 번역을 저장한다. 이용자는 요청 언어에 맞는 본문을 상세·목록·미리보기에서 읽는다.
현재 코드에서 확인한 사실:
| 근거 파일 | 확인한 동작 |
|---|---|
src/main/kotlin/kr/co/vividnext/sodalive/explorer/profile/creatorCommunity/CreatorCommunity.kt |
원문 content는 있으나 원문 언어와 번역 저장 구조는 없다. |
src/main/kotlin/kr/co/vividnext/sodalive/content/AudioContentService.kt |
상세 조회에서 요청 언어의 번역을 조회한다. 번역이 없으면 해당 언어 작업을 예약하고 원문 응답을 유지한다. 원문 언어가 없는 경우에는 이 예약 분기에 들어가지 않는다. |
src/main/kotlin/kr/co/vividnext/sodalive/content/LanguageDetectEvent.kt |
커밋 후 비동기 언어 감지, 언어 저장, 번역 이벤트 발행 흐름이 있다. |
src/main/kotlin/kr/co/vividnext/sodalive/i18n/translation/ResourceTranslationJobScheduler.kt |
리소스의 원문 언어를 제외한 지원 언어 전체 또는 지정한 한 언어의 작업을 예약한다. |
src/main/kotlin/kr/co/vividnext/sodalive/i18n/translation/TranslationJobScheduler.kt |
원문 언어가 ko, en, ja인 비어 있지 않은 텍스트만 예약한다. 동일 리소스·필드·목표 언어·원문 해시 작업은 중복 생성하지 않는다. |
src/main/kotlin/kr/co/vividnext/sodalive/i18n/translation/TranslationJobWorker.kt |
저장된 작업을 처리하고 번역 메모리와 조회용 번역을 저장한다. 주기 기본값은 600000ms이며 실제 환경 설정에 따라 달라진다. |
이번 기능은 오디오 상세의 누락 번역 예약 방식을 따른다. 다만 기존 커뮤니티 게시물은 언어 정보 자체가 없으므로, 상세 조회에서 비동기 언어 감지까지 연결해야 한다. 오디오 상세가 현재 언어 미확정 데이터도 감지한다고 가정하지 않는다.
2. 포함 범위와 제외 범위
포함
- 본문
content만 번역하며 무료·유료 게시물에 같은 언어 정책을 적용한다. - 신규 게시물 저장 후 자동 감지·번역, 실제 본문 변경 후 언어 재감지·번역 갱신.
- 기존 게시물은 상세 조회를 계기로 필요한 언어를 감지하고 요청 언어의 누락 번역을 예약한다.
- 기존 커뮤니티 API와 v2 상세·목록, 채널 홈의 고정/일반 게시물, 홈 추천 인기 커뮤니티, 팔로잉 소식의 본문·미리보기.
- 공유 생성·수정 서비스를 사용하는 AI 캐릭터 관리자 작성 경로도 같은 저장 처리를 적용한다. 이는 별도 관리자 기능 추가가 아니라 동일 게시물의 생성·수정 누락 방지다.
제외
- 댓글·답글·첫 댓글, 이미지 내부 문자, 첨부 오디오 음성의 번역.
- 기존 게시물 일괄 번역, 목록·홈·미리보기·댓글 조회에서 언어 감지 또는 번역 작업 예약.
- 번역 수동 편집·언어 선택 입력·원문 보기 토글·번역 상태 API·실시간 완료 알림.
- 푸시 알림 문구·알림 이력의 번역, 정산 화면과 관리자 편집용 원문 응답 변경.
- 공통 언어 지원 범위, 다른 콘텐츠의 수정 정책, 추천 순위/스냅샷 생성 방식의 변경.
3. 확정 요구사항
| ID | 요구사항 | 수용 기준 | 연결 Goal |
|---|---|---|---|
CCT-001 |
원문을 보존하고 본문만 지원 언어로 번역해 저장한다. | 한국어·영어·일본어 각각을 원문으로 작성하면 다른 두 언어의 본문 번역이 저장되고 원문은 유지된다. 댓글과 첨부 파일은 바뀌지 않는다. | P1-T1, P1-T2, P2-T1 |
CCT-002 |
원문 언어가 없으면 본문으로 자동 감지한다. | 요청자의 앱 언어를 원문 언어로 추정하지 않는다. 감지 결과를 저장하고 번역으로 이어진다. | P1-T2 |
CCT-003 |
신규 게시물은 저장 성공 후 원문 이외의 지원 언어 번역을 예약한다. | 저장 롤백에는 감지/번역이 실행되지 않는다. 저장 응답이 외부 번역 완료를 기다리지 않는다. | P2-T1 |
CCT-004 |
실제 본문 수정 시 언어를 다시 감지하고 번역을 갱신한다. | 한국어에서 영어로 변경해도 새 언어와 새 본문으로 처리한다. 동일 본문 제출·이미지·고정·댓글 허용 여부만 변경하면 재번역하지 않는다. | P2-T1 |
CCT-005 |
기존 게시물은 상세 조회에서만 누락 번역을 예약한다. | 번역 미완료 상세는 원문을 반환한다. 원문 언어가 없으면 감지 후 해당 상세 요청 언어만 예약한다. 언어가 같으면 번역 작업은 없다. | P2-T2 |
CCT-006 |
상세·목록·미리보기에서 저장된 유효한 번역을 사용한다. | 레거시 목록/최신 목록, v2 커뮤니티 목록, 채널 홈, 홈 추천, 팔로잉 소식에 같은 언어의 저장 번역이 적용된다. 목록 계열만 조회하면 감지/번역 작업은 0건이다. | P2-T2, P3-T1, P3-T2 |
CCT-007 |
번역이 없거나 실패했거나 현재 본문에 맞지 않으면 현재 원문을 제공한다. | 수정 커밋 후 새로 시작한 요청에서는 수정 전 번역을 반환하지 않는다. 늦게 도착한 이전 감지/번역 결과도 새 본문을 덮어쓰지 않는다. | P1-T1, P1-T2, P2-T1, P3-GATE |
CCT-008 |
기존 조회 권한과 유료 본문 제한을 번역문에도 적용한다. | 차단·성인·비활성 필터와 구매/소유자 판정은 유지한다. 번역문을 선택한 다음 기존 미리보기 제한을 적용해 미구매자에게 전체 본문이 노출되지 않는다. | P2-T2, P3-T1, P3-T2 |
CCT-009 |
기존 API 구조와 언어 결정 방식을 유지한다. | Accept-Language를 처리하는 LangContext를 사용한다. 응답 본문 문자열의 언어만 달라지고 필드·상태 코드·인증·페이지 규칙은 유지한다. |
P2-T2, P3-T1, P3-T2 |
CCT-010 |
기존 감지 캐시·번역 메모리·큐·워커를 재사용한다. | 반복 상세 조회나 이전 본문으로의 복원에서 불필요한 번역 호출을 만들지 않는다. 목록 번역 조회는 게시물별 쿼리 대신 일괄 조회한다. | P1-T1, P1-T2, P3-GATE |
4. 처리 흐름
4.1 신규 작성과 본문 수정
- 기존 검증·소유권 확인을 거쳐 원문을 저장한다. 본문 변경 시 이전 언어를 비우고 본문 개정 번호를 증가시킨다.
- 저장 트랜잭션 커밋 후 해당 본문의 언어를 비동기로 감지한다. 원문 정보가 이미 있으면 감지를 생략한다.
- 감지 결과가 현재 본문의 결과임을 확인하고 원문 언어를 저장한다.
- 지원 언어 중 원문을 제외한 언어를 예약한다. 기존 메모리를 재사용할 수 있으면 조회용 번역을 복원한다.
- 워커가 완료하면 다음 조회부터 번역문을 제공한다. 완료 전에는 현재 원문을 제공한다.
4.2 기존 게시물 상세 조회
- 기존 접근 권한과 노출 정책을 확인한다.
- 요청 언어의 현재 본문에 대응하는 번역이 있으면 사용한다.
- 번역이 없으면 원문 응답을 유지하고 누락 처리만 예약한다. 언어 미확정이면 감지 요청에 상세 요청 언어를 전달한다.
- 감지 후 원문과 요청 언어가 다를 때 해당 언어만 예약한다. 신규 작성의 전체 언어 예약과 구분한다.
- 외부 감지/번역은 HTTP 응답을 기다리게 하지 않는다. 다음 조회부터 완성된 번역을 사용한다.
4.3 목록·홈·미리보기
권한 필터와 페이지 선정 → 페이지 내 게시물의 유효한 번역 일괄 조회 → 번역 또는 현재 원문 선택 → 기존 유료 미리보기·표시 규칙 적용 순서로 처리한다. 이 경로는 언어 감지, 메모리에서 조회 모델 재생성, 번역 작업 예약을 하지 않는다. 저장된 번역이 없는 기존 게시물은 상세 조회 또는 본문 수정 전까지 원문으로 남는다.
5. API 계약과 조회 표면
공개 필드는 추가하지 않는다. content와 여기서 파생되는 게시물 미리보기 문자열을 요청 언어로 반환한다.
언어는 LangInterceptor → Lang.fromAcceptLanguage → LangContext를 그대로 사용한다.
지원 언어는 ko, en, ja이고 헤더 누락/미지원 언어 처리는 기존 한국어 기본값을 유지한다.
자동 번역문을 원문 CreatorCommunity.content에 덮어쓰지 않는다.
| API | 대상 | 누락 처리 예약 |
|---|---|---|
POST /creator-community, PUT /creator-community |
신규 작성·실제 본문 수정 후 처리. multipart 계약 유지 | 커밋 후 전체 목표 언어 |
GET /creator-community/{id} |
레거시 상세 content |
요청 언어만 |
GET /creator-community, GET /creator-community/latest |
레거시 목록·팔로우 최신 목록 content |
없음 |
GET /api/v2/creator-channels/community-posts/{postId} |
v2 상세 게시물 content |
요청 언어만 |
GET /api/v2/creator-channels/{creatorId}/community |
커뮤니티 탭 게시물 content |
없음 |
GET /api/v2/creator-channels/{creatorId}/home |
고정/일반 커뮤니티 항목 content |
없음 |
GET /api/v2/home/recommendations |
인기 커뮤니티 항목 본문·파생 미리보기 | 없음 |
GET /api/v2/home/following |
recentNews의 커뮤니티 게시물 본문 |
없음 |
관리자 게시물 조회는 편집 원문을 유지한다. 같은 작성 서비스를 호출하는 관리자 생성·수정은 CCT-003~004를 따른다.
댓글 전용 조회와 구매 응답은 번역 예약 진입점으로 추가하지 않는다.
6. 데이터·비동기 정합성 설계 기준
다음 기술 설계는 현재 구현과 DDL에 반영됐다. 실제 MySQL 적용 여부는 테스트 서버 수동 검증에서 확인한다.
| 저장 대상 | 계획 |
|---|---|
creator_community |
nullable language_code, 본문 변경에만 증가하는 content_revision을 추가한다. 기존 행은 언어 NULL, 개정 번호 0으로 시작한다. |
creator_community_translation |
게시물 ID, locale, 번역 본문, 번역 기준 개정 번호, 원문 해시·언어를 저장한다. (creator_community_id, locale) 유일성을 보장한다. |
| 공통 감지/번역 저장소 | 기존 감지 캐시와 번역 메모리의 정규화·키, translation_job 처리 흐름을 유지한다. 커뮤니티 대상 enum과 원문 추출/조회 모델 저장 분기를 추가한다. |
- 감지 이벤트에 본문 개정 번호와 필요한 경우 목표 언어를 전달한다. 본문이 변경되었거나 비활성화되면 이전 결과를 적용하지 않는다.
- 번역문은 현재 본문의 개정 번호·원문 언어가 일치할 때만 조회한다. 오래된 작업의 결과에 현재 개정 번호를 임의로 붙이지 않는다.
- 감지 결과 저장과 번역 upsert의 개정 확인은 DB 갱신과 원자적으로 처리한다. 외부 API 호출 동안 행 잠금을 유지하지 않는다.
updatedAt은 고정·이미지 등 수정에도 변하므로 본문 개정 판단에 사용하지 않는다.- 원문 A → B → A 복원 시 기존 COMPLETED 작업 때문에 번역이 영구 누락되지 않도록 현재 메모리로 조회 모델을 먼저 복원한다.
- 기존 정규화는 공백·개행을 합친다. 원문 표시의 개행은 원문 그대로 보존하고, 번역 결과는 기존 번역기의 출력 정책을 따른다.
7. 예외·권한·성능
| 상황 | 처리 |
|---|---|
| 빈 본문 또는 공백만 있는 본문 | 기존 저장 검증은 바꾸지 않는다. 감지·번역은 생략하고 원문을 반환한다. |
| 감지 실패 또는 지원하지 않는 원문 언어 | 원문 유지. 지원하지 않는 언어의 번역 작업은 기존 scheduler 정책에 따라 생성하지 않는다. 언어 미확정 게시물의 다음 상세에서 감지를 다시 시도할 수 있다. |
| 번역 실패 | 원문 유지. 기존 워커의 재시도/최종 FAILED 정책을 재사용한다. 반복 상세 조회가 최종 실패 작업을 무한 재생성하지 않는다. |
| 번역 도중 본문 변경·비활성화 | 오래된 결과를 현재 게시물의 번역으로 노출하지 않는다. 삭제/비활성 게시물은 기존 조회 정책대로 숨긴다. |
| 유료 게시물 미구매 | 선택된 번역 또는 원문에 기존 코드포인트 기준 제한을 적용한다. 기존 15자 기준·짧은 본문 절반·말줄임 처리는 유지한다. |
| 목록에 여러 게시물 | 페이지 단위 번역 일괄 조회. 기존 정렬·개수·페이지·추천 후보를 변경하지 않고 추가 N+1을 만들지 않는다. |
외부 감지/번역 실패는 작성·조회 성공을 번역 완료 여부에 종속시키지 않는다. 인증 실패나 DB 장애까지 성공으로 숨기지는 않는다. 본문·자격증명·유료 콘텐츠 전문을 새 로그에 남기지 않는다. 기존 감지/번역 저장소의 텍스트 저장 정책은 재사용한다. 번역 완료 시간 SLA나 워커 주기 조정은 이번 요청에 포함하지 않는다.
8. 성공 기준과 추적성
| 수용 시나리오 | 완료 증거 |
|---|---|
| 한·영·일 원문으로 신규 작성 후 다른 두 언어 제공 | P2-GATE의 생성→감지→작업→저장 통합 검증 |
| 언어 없는 기존 글: 목록은 원문/작업 0건, 상세는 원문/감지 후 요청 언어 예약 | P2-T2 통합 테스트와 배포 후 수동 HTTP 검증 |
| 한국어 본문을 영어로 수정하고 이전 비동기 작업을 늦게 완료 | 현재 원문 폴백과 오래된 결과 차단 테스트 |
| 상세 번역 저장 후 목록·채널 홈·추천·팔로잉 모두 요청 언어 제공 | P3-T1~T2, P3-GATE의 표면별 검증 |
| 미구매자는 번역 미리보기만, 구매자·소유자는 기존 권한에 따른 본문 제공 | 레거시/v2 권한·코드포인트 경계 회귀 검증 |
| 언어 감지/번역 실패, 반복 조회, 본문 복원 | 원문 유지·작업 중복 방지·번역 메모리 재사용 검증 |
구현 완료는 위 자동 검증 증거가 기록된 뒤에 판정했다. 실제 MySQL·Papago·HTTP 검증은 테스트 서버 수동 검증으로 분리한다.
9. 인터뷰 결과와 Decision Log
최종 모호성 점수: 0.04. 차원별 명확성: Goal 1.00, Scope 1.00, Constraints 0.95, Success 0.95, Context 0.85. 이는 누락 확인용 판단 지표이며, 코드 검증이나 구현 완료를 의미하지 않는다. 열린 제품 질문은 없다. 테스트 환경 자격증명과 DDL 적용 절차는 테스트 서버 배포 단계에서 확인할 실행 조건이다.
| ID | 상태 | 결정 | 근거 / 영향 |
|---|---|---|---|
DEC-001 |
확정 | 본문만 번역, 댓글 제외 | 사용자 인터뷰 / CCT-001 |
DEC-002 |
확정 | 기존 글은 오디오 상세처럼 누락 번역 예약 | 사용자 제안 및 후속 상세 한정 답변 / CCT-005 |
DEC-003 |
확정 | 목록 본문·미리보기도 저장된 번역 적용 | 사용자 답변 / CCT-006 |
DEC-004 |
확정 | 언어 정보가 없으면 자동 감지 | 사용자 답변 / CCT-002 |
DEC-005 |
확정 | 본문 수정 시 언어 재감지·번역 갱신 | 사용자 yes / CCT-004 |
DEC-006 |
확정 | 목록에서는 예약하지 않고 상세에서만 예약 | 사용자 답변 / CCT-005~006 |
DEC-007 |
확정 | 새 번역 전에는 수정된 원문 표시 | 사용자 yes / CCT-007 |
DEC-008 |
확정 | 채널 홈·홈 추천·팔로잉 소식 포함 | 사용자 yes / CCT-006 |
DEC-009 |
기술 설계 | 기존 API 구조·권한 유지, 언어별 저장 번역을 본문 필드에 적용 | 저장소 규칙 및 최소 변경 원칙 / CCT-008~009 |
DEC-010 |
기술 설계 | 본문 개정 번호와 기존 캐시·큐 재사용 | 수정 직후 원문 표시와 비동기 경합 방지 / CCT-007, CCT-010 |
결정 날짜는 모두 2026-09-10이다. 범위 변경 시 이 결정 기록과 요구사항을 먼저 갱신하고 plan-task.md를 동기화한다.