docs(i18n): AWS 공급자 구현과 검증 결과를 기록한다
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
# AWS 언어 감지·번역 Provider PRD
|
||||
|
||||
| 항목 | 내용 |
|
||||
|---|---|
|
||||
| 작성일 | 2026-11-09 |
|
||||
| 최종 수정일 | 2026-11-10 |
|
||||
| 문서 상태 | 기능 구현 및 공용 테스트 설정 회귀 보정 완료 |
|
||||
| 구현 상태 | P4-R1 검증·리뷰 완료, 실제 AWS/IAM 및 전체 테스트 미검증 |
|
||||
| 구현 계획 | [plan-task.md](plan-task.md), P1~P4 완료 및 기존 이력 보존 |
|
||||
| 근거 문서 | [공급자 공통화 PRD](../20261109_감지번역공급자공통화/prd.md), [공급자 확장 가이드](../20261109_감지번역공급자공통화/provider-guide.md) |
|
||||
|
||||
## 목표와 범위
|
||||
|
||||
공통 언어 감지·번역 구조에 AWS Comprehend 감지 Provider와 AWS Translate 번역 Provider를 추가한다. 콘텐츠 등 도메인 호출자는 기존 인터페이스와 coordinator만 사용하며 AWS 분기를 추가하지 않는다. 감지와 번역은 각각 독립적으로 등록하고 기존 캐시, 실패 전환, 저장 계약을 보존한다.
|
||||
|
||||
구현 범위는 두 AWS adapter와 필요한 내부 분할 로직이다. 기존 `LanguageDetectionProvider`, `TranslationProvider`, coordinator 경계, `LanguageProviderId.AWS` 및 안정 code `aws`를 유지한다. 지원 번역 언어는 기존 ko/en/ja이며 AWS를 이유로 확장하지 않는다. 공개 API, DB 스키마, 재시도 계약은 변경하지 않는다.
|
||||
|
||||
## 확정 요구사항
|
||||
|
||||
| ID | 상태 | 요구사항 | 관찰 가능한 수용 기준 |
|
||||
|---|---|---|---|
|
||||
| AWS-001 | 확정 | Comprehend와 Translate는 기존 `cloud.aws.credentials.access-key`, `cloud.aws.credentials.secret-key`, 서울 리전 `cloud.aws.region.static` (`ap-northeast-2`)을 재사용한다. Provider 전용 자격 증명 설정은 추가하지 않는다. | adapter 요청 테스트에서 설정된 자격 증명 공급자와 리전을 사용한다. IAM 정책을 변경하지 않으며 실제 권한은 별도로 검증되지 않았다고 표시한다. |
|
||||
| AWS-002 | 확정 | 감지는 `DetectDominantLanguage`를 호출한다. 짧은 비어 있지 않은 입력도 길이로 사전 차단하지 않고, blank 입력은 기존 가드를 따른다. | 20자 미만 입력이 adapter까지 전달된다. blank 입력은 AWS 호출이 없다. |
|
||||
| AWS-003 | 확정 | 감지 텍스트가 100KB를 넘으면 원문 앞부분의 최대 100000 UTF-8 바이트를 코드포인트 경계에서 잘라 보낸다. 여러 조각의 감지 결과를 합산하지 않는다. 원문 hash/cache key와 번역 원문은 바꾸지 않는다. | prefix가 UTF-8 유효하고 크기 한도를 넘지 않는다. 원문 hash/cache key와 번역 입력은 원문 기준 그대로다. 이 보수적 구현값은 공식 문서의 “100KB”를 구현하는 선택이며 공식 서비스 한도가 정확히 100000바이트라고 주장하지 않는다. |
|
||||
| AWS-004 | 확정 | Comprehend 응답의 내림차순 정렬 결과에서 첫 dominant-language 후보를 사용한다. 언어 코드는 blank가 아니어야 유효하다. 임의 confidence 임계값을 두거나 공개 타입을 변경하지 않는다. | 후보가 없거나 언어 코드가 blank이면 기존 공급자 실패 전환으로 넘어가며, 유효 결과는 첫 후보 코드다. |
|
||||
| AWS-005 | 확정 | Translate에는 source와 target 언어를 명시한다. 입력은 UTF-8 기준 10000바이트 이하 조각으로 나누어 원래 순서대로 번역하고 결합한다. 조각 하나라도 실패하면 해당 Provider의 부분 결과를 버리고 기존 전체 요청 단위 fallback을 따른다. | 경계·순서·결과 개수·전체 실패 동작을 검증한다. 원문과 조각 사이 whitespace를 손실 없이 재구성하고 별도 구분자를 삽입하지 않는다. |
|
||||
| AWS-006 | 확정 | Papago의 기존 5000 UTF-16 코드 단위 분할은 유지한다. 내부 공통 splitter는 완전한 Unicode 코드포인트만 조각 경계로 삼고 공급자별 크기 측정 함수를 적용한다. | Papago 5000 UTF-16 단위 동작과 회귀 테스트가 유지된다. AWS 조각은 UTF-8 바이트 기준이며 한글·보조 평면 문자 경계가 유효하다. |
|
||||
| AWS-007 | 확정 | 새 AWS 번역 결과의 기존 `providerVersion` 필드에는 안정 값 `translate-2017-07-01`을 사용한다. 실제 성공 Provider 귀속, 캐시 우선순위, 부분 성공 금지는 기존 공통화 계약을 따른다. | 캐시 미스 호출 성공 시 저장 귀속은 `aws`; 유효 AWS 캐시 재사용 시 외부 AWS 호출은 없다. 버전 값은 지정한 문자열이다. |
|
||||
| AWS-008 | 확정 | 공용 테스트 설정만 사용하는 Spring 컨텍스트도 AWS Bean을 생성할 수 있도록 테스트 전용 합성 키를 제공한다. 운영의 빈 키 거부와 실계정 호출 금지 경계는 유지한다. | 공용 YAML을 덮어쓰지 않는 설정 회귀 및 기존 전체 앱 컨텍스트 테스트 통과. 빈 운영 키는 계속 초기화 실패. |
|
||||
|
||||
## 동작과 데이터 보존
|
||||
|
||||
- 감지 순서와 번역 순서는 독립이다. AWS가 등록된 이후의 production 순서는 기존 공통화 PRD에서 상속한 PAPAGO → AWS다. 이번 PRD를 위해 순서를 다시 사용자에게 묻지 않는다. 미구현 AWS는 현재 실행 설정에 추가된 것처럼 동작하지 않는다.
|
||||
- 기존 캐시 조회 순서와 실제 성공 Provider 귀속을 유지한다. 캐시 미스에서 앞선 Provider가 실패하면 다음 Provider로 전환하고, 첫 성공 뒤에는 더 호출하지 않는다. 전체 실패는 기존 감지 null 및 번역 worker 오류 흐름을 따른다.
|
||||
- AWS 번역은 결과를 Papago와 섞지 않는다. 분할 중 하나라도 실패하면 AWS의 부분 결과를 버린 뒤 전체 입력을 다음 Provider에 전달한다.
|
||||
- 원문, 인증 정보, 공급자 원시 응답·오류를 새 로그나 worker 오류 문자열에 남기지 않는다. 호출자 공개 타입, API schema, DB schema는 변경하지 않는다.
|
||||
- IAM 변경, 자격 증명 발급, 실제 AWS 유료 호출은 이 문서나 구현 승인에 포함되지 않는다.
|
||||
- 필요한 IAM 작업은 `comprehend:DetectDominantLanguage`, `translate:TranslateText`다. API 호출만 하는 이번 범위에 `TranslateFullAccess`는 필수가 아니다. [공식 API 권한 안내](https://docs.aws.amazon.com/translate/latest/dg/security_iam_id-based-policy-examples.html#security_iam_id-based-policy-examples-console)를 따르며 실제 권한은 미검증이다.
|
||||
|
||||
## 승인된 구현 기술
|
||||
|
||||
다음 기술 설계는 DEC-006에서 승인됐다. 구현 계획에서 버전 pin과 파일 배치를 구체화한다.
|
||||
|
||||
- 새 Comprehend/Translate 모듈에만 AWS SDK for Java v2를 사용한다. 기존 SQS, SES, S3, CloudFront SDK v1은 마이그레이션하지 않는다.
|
||||
- v2의 static credentials provider에 기존 명시적 `cloud.aws` 자격 증명을 연결하고 기존 region 설정을 사용한다.
|
||||
- 동기 SDK client는 Spring lifecycle 관리 Bean으로 제공하고 adapter에 주입한다. 애플리케이션 종료 시 client를 닫는다.
|
||||
- SDK 정확한 버전 pin과 파일·클래스 이름은 제품 결정이 아니라 구현 세부이며, 계획 단계에서 저장소 관례에 맞춰 정한다.
|
||||
- splitter만 내부에서 공유한다. HTTP/SDK adapter는 별도 구현하며 `TranslationProvider` 공개 메서드는 추가하지 않는다.
|
||||
- `providerVersion`은 기존 필드에 `translate-2017-07-01`을 사용한다.
|
||||
|
||||
AWS SDK for Java v1은 2025-12-31에 지원 종료가 공지됐다. 새 모듈에서 v2를 택하는 근거이며 기존 v1 전환 범위를 넓히지는 않는다. AWS는 v1/v2 공존 방식을 공식 지원한다.
|
||||
|
||||
- [AWS SDK for Java v1 지원 종료 안내](https://aws.amazon.com/blogs/developer/announcing-end-of-support-for-aws-sdk-for-java-v1-x-on-december-31-2025/)
|
||||
- [SDK v1/v2 side-by-side 사용 안내](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration-side-by-side.html)
|
||||
|
||||
## 공식 API 근거
|
||||
|
||||
- [Comprehend DetectDominantLanguage](https://docs.aws.amazon.com/comprehend/latest/APIReference/API_DetectDominantLanguage.html): 감지 API, 100KB 입력 한도. 긴 입력 prefix 정책은 DEC-005에서 확정한다.
|
||||
- [Comprehend 언어 감지 품질 안내](https://docs.aws.amazon.com/comprehend/latest/dg/how-languages.html): 20자 이상 권장. 20자 미만을 서비스의 확정 거부 조건으로 해석하지 않는다.
|
||||
- [Translate TranslateText](https://docs.aws.amazon.com/translate/latest/APIReference/API_TranslateText.html): source/target 명시 및 입력 최대 10000 UTF-8 바이트.
|
||||
- [Papago 번역 요청 규격](https://api.ncloud-docs.com/docs/en/ai-naver-papagonmt-translation): 요청당 최대 5000 characters. 정확한 Unicode 계수 단위는 명시되지 않는다. 기존 구현의 UTF-16 `String.length` 상한을 유지하며 실제 Papago 호출은 미검증이다.
|
||||
|
||||
## 검증 기준 및 실행 계획
|
||||
|
||||
아래 검증은 실제 AWS/Papago 계정 호출 없이 완료했다. 2026-11-10 부모 fresh 실행에서 관련 테스트 175건이 통과했고, lint·bootJar 및 실제 SDK localhost 호출도 성공했다. 상세 명령과 실패·재시도 이력은 구현 계획에 보존한다.
|
||||
|
||||
- 내부 splitter 단위 테스트: 정확한 한도와 한도 초과, 한글, supplementary-plane 문자의 UTF-8/UTF-16 경계, 공백을 포함한 원문 손실 없는 재구성, Papago 기존 회귀.
|
||||
- 감지 테스트: prefix 최대 바이트, UTF-8 코드포인트 경계 보존, prefix가 원문의 끝부분을 포함하지 않음, 응답 첫 후보 선택, blank/없음 실패 전환, 짧은 입력 전달, 원문 hash/cache key 보존.
|
||||
- SDK adapter 테스트: 통제된 로컬 transport 또는 외부 경계만 대체한 SDK mock으로 요청 필드와 응답 매핑을 확인한다. 유료 API 호출은 하지 않는다.
|
||||
- coordinator/캐시 테스트: PAPAGO → AWS 순서, 첫 성공 시 후속 호출 없음, 전체 입력 단위 fallback, 부분 번역 폐기, AWS 성공 캐시 귀속, 실제 AWS 캐시 재사용 시 AWS 네트워크 호출 없음.
|
||||
- 기능 회귀 명령은 `./gradlew test --tests 'kr.co.vividnext.sodalive.i18n.translation.*' --tests 'kr.co.vividnext.sodalive.content.LanguageDetectionCacheServiceTest'`이며 community 관련 3개 클래스는 별도 명령으로 검증했다. 산출물 검증은 `./gradlew bootJar`다. 전체 테스트 `./gradlew test`는 사용자가 실행한다.
|
||||
|
||||
## 제외 및 안전 경계
|
||||
|
||||
- IAM 정책/role 변경, 운영 자격 증명 교체, 실제 유료 AWS/Papago 호출.
|
||||
- 공개 API, DB schema, `TranslationProvider` 공개 메서드, 번역 언어 정책 변경.
|
||||
- 새 재시도, 캐시 계층, 품질 임계값, 다중 조각 감지 집계, 관측성 확장.
|
||||
- 원문·인증정보·공급자 원시 본문 또는 오류의 신규 로그 기록.
|
||||
- v1 SDK를 사용하는 기존 서비스의 v2 마이그레이션.
|
||||
|
||||
## Open Questions 및 승인 상태
|
||||
|
||||
| ID | 상태 | 내용 | 영향 |
|
||||
|---|---|---|---|
|
||||
| OQ-001~004 | 해결, DEC-001~003 | 서울 리전/기존 자격 증명 재사용, 짧은 감지 입력, 번역 분할 | 요구사항에 반영됨 |
|
||||
| OQ-005 | 해결, DEC-006 | 새 AWS 모듈에 SDK v2 사용. 기존 SDK v1 유지 | 전체 PRD와 SDK v2 제안 승인 완료 |
|
||||
| OQ-006 | 해결, DEC-005 | 100KB 초과 감지 입력을 UTF-8 코드포인트 경계 prefix로 제한하고 조각별 감지 집계 없음 | 혼합 언어 입력에서는 prefix의 감지 결과가 전체 원문의 dominant language와 다를 수 있음. 구현 코드에 `shortcut: 감지는 앞 100000 UTF-8 바이트만 판정하므로 전체 본문과 결과가 다를 수 있음, 전체 본문 기준 품질이 요구되면 별도 감지 정책 승인 후 업그레이드` 형식의 주석을 둔다. |
|
||||
| OQ-007 | 해결, DEC-004 | 인터페이스 변경 없이 공통 internal 분할 함수와 공급자별 길이 계산 사용 | Papago와 AWS가 공통 분할 로직을 사용함 |
|
||||
|
||||
요구사항 인터뷰 종료 시 가중 모호도는 약 0.03이었으며 열린 제품 질문은 없다. 승인된 전체 설계와 SDK v2 구현의 기능 범위 검증이 완료됐다. IAM의 실제 권한과 외부 API 품질 확인은 별도이며 운영 검증 완료로 간주하지 않는다.
|
||||
|
||||
### 문서 검증 기록
|
||||
|
||||
- 2026-11-09: 독립 builder 검토 결과, 제안 설계 승인 후 계획 수립을 막는 중요한 미결 사항 없음(`nothing important left`). SDK 버전 pin과 클래스 이름은 구현 계획 단계에서 결정한다.
|
||||
- 문서의 결정 상태·수용 기준·공백 및 placeholder 잔존 여부를 대조했다. 문서 전용 변경이므로 Gradle 테스트·빌드와 실제 외부 API 호출은 실행하지 않았다.
|
||||
- 2026-11-10 구현 후 검증: 모든 Task/Gate 완료, 관련 테스트 175건·lint·bootJar 및 실제 SDK localhost QA 통과, Oracle 전체 변경 리뷰 승인. 문서 작성 시점의 위 미실행 기록은 과거 이력이며 실제 실행 결과는 구현 계획을 따른다.
|
||||
- 2026-11-10 후속 회귀: 공용 YAML의 빈 키가 실제 전체 앱 시작을 막는 실패를 재현했다. 테스트 전용 키 두 값과 공유 설정 회귀를 보완한 뒤 부모 fresh 검증 151건(번역 146건, 전체 앱·HTTP 5건)·lint 및 독립 리뷰를 통과했다. 앞선 175건과 다른 검증 범위이며 전체 테스트 성공으로 해석하지 않는다. 운영의 빈 키 거부는 그대로 유지한다.
|
||||
|
||||
## 결정 기록
|
||||
|
||||
| 날짜 | ID | 상태 | 결정 | 근거 |
|
||||
|---|---|---|---|---|
|
||||
| 2026-11-09 | DEC-001 | 확정 | Comprehend·Translate에 기존 자격 증명과 서울 리전 설정을 재사용한다. | 사용자: “기존 인증정보와 서울 리전을 재사용한다.” |
|
||||
| 2026-11-09 | DEC-002 | 확정 | 20자 미만도 AWS 감지를 요청하고 실패·결과 없음은 기존 실패 정책을 따른다. | 사용자 답변: “네” |
|
||||
| 2026-11-09 | DEC-003 | 확정 | 긴 AWS 번역은 Papago와 같은 분할·순차 번역·결합 흐름으로 구현한다. Papago 길이 단위를 공식 가이드와 대조하고 불일치가 확인되면 함께 수정한다. 공통 분할 함수 배치는 조사 후 설계한다. | 사용자: “파파고 번역이 어떻게 되어 있는지 확인하고 동일하게 처리하자”, 공식 가이드와 다르면 변경 요청 |
|
||||
| 2026-11-09 | DEC-004 | 확정 | 공개 인터페이스는 유지한다. 공통 internal splitter와 공급자별 길이 계산을 사용하고 Papago 5000 UTF-16 단위 및 AWS 10000 UTF-8 바이트를 적용한다. | 사용자 답변: “그렇게 진행하자” |
|
||||
| 2026-11-09 | DEC-005 | 확정 | 긴 감지 텍스트는 처음 최대 100KB만 사용한다. UTF-8 prefix를 코드포인트 경계에서 자르고 여러 조각의 언어를 합산하지 않는다. 원문 hash/cache key와 번역 입력은 그대로 유지한다. | 사용자 답변: “확정” |
|
||||
| 2026-11-09 | OQ-005 | 제안 | 신규 AWS 모듈만 SDK v2 사용. 기존 SQS/SES/S3/CloudFront v1은 유지한다. | 기술 제안, 전체 설계 및 SDK 제안 승인 대기 |
|
||||
| 2026-11-09 | DEC-006 | 확정 | 이 PRD의 전체 설계와 신규 AWS Provider의 SDK v2 사용을 승인하고 구현 계획 작성으로 진행한다. 기존 SDK v1 연동은 유지한다. | 최종 PRD·SDK v2 제안 승인 및 구현 계획 작성 질문에 대한 사용자 답변: "진행" |
|
||||
| 2026-11-09 | DEC-007 | 확정 | 구현 계획과 Subagent-driven 실행을 승인한다. | 계획 검토·실행 방식 질문에 대한 사용자 답변: "진행" |
|
||||
| 2026-11-10 | DEC-008 | 회귀 보정 | 공용 테스트 YAML의 빈 AWS 키로 전체 앱 테스트 시작이 실패함을 재현했다. 테스트 전용 합성 값과 공유 설정 로딩 회귀를 추가하며 운영 코드는 변경하지 않는다. | 사용자 오류 보고 및 SpringBootIntegrationSampleTest의 AwsLanguageProviderConfiguration:18 동일 오류 재현 |
|
||||
Reference in New Issue
Block a user