Tech Stack
주요 기능
- 18개 번역 테이블과 필드 계약을 설정 파일로 관리
- 수동 콘솔 - 검색 · 상태 필터 · 서버 페이지네이션 · AI 초안 · 검토 후 UPSERT
- 수동 배치 - 선택한 테이블·언어·건수만 실행, 성공 건만 저장
- 자동 배치 - 실행 주기 · 테이블 우선순위 · 처리 한도 정책
- OpenAI · Gemini allowlist 기반 공급자·모델 선택
- 응답 ID · 필수 필드 검증 후 실패·충돌 건은 수동 처리 큐로 이관
- 읽기 전용 데이터 조회 (SELECT/WITH · 3초 timeout · 200행 제한)
- 작업 이력 · API 오류 기록 (SQLite, 기본 90일 보존)
성과
- 한국어 → pt-BR · ja · zh-CN · zh-TW 4개 언어 번역 파이프라인 구축
- advisory lock · lock_timeout 1.5s · statement_timeout 5s 로 운영 DB 경합 차단
- LLM 응답 대기 중 DB 연결 미점유 - 풀 대기 1초 초과 건은 수동 이관
- API 키 · 요청 헤더 · 전체 프롬프트를 브라우저와 로그에서 완전히 분리
- 읽기 전용 역할 전환 실패 시 쓰기 계정으로 대체 실행하지 않는 안전 실패 확립
상세내용
한국어 원문을 포르투갈어(브라질)·일본어·중국어 간체/번체로 번역해 운영 DB에 반영합니다. 확장성을 고려해 번역 대상 테이블과 필드 계약을 설정파일로 관리할 수 있게 구성했습니다.
핵심 기술적 과제는 `운영 DB의 부담을 최소화한다` 였습니다. 해당 주문에 맟춰 설계 및 구성했습니다.
핵심 전제는 "LLM 번역 결과값을 바로 저장하지 않는다" 였습니다. 응답 ID·필수값 필드를 먼저 검증하고 통과한 건만 검토/UPSERT 로 보냅니다. UNIQUE 충돌·lock 대기·statement timeout·검증 실패는 버리지 않고 수동 처리 큐로 이관해 다시 볼 수 있게 남깁니다. 수동 콘솔은 AI 초안을 자동 저장하지 않고, 검수 담당자가 필드별로 확인·수정해야 (원본 FK, locale) 기준 UPSERT 가 실행됩니다.
운영 중인 서비스 DB에 접근하는 작업이므로 경합 상황에 대한 차단을 먼저 설계했습니다. 번역 Worker 는 PostgreSQL advisory lock 으로 인스턴스 간 중복 실행을 막고, 연결 풀은 최소 1 최대 2 로 묶었습니다. 자동 배치는 사람이 이미 검토한 항목과 이전 실패 항목을 제외하며, 다른 작업이 먼저 needs_translation 을 해제한 행은 덮어쓰지 않습니다.
트러블슈팅
번역 배치 작업이 운영DB 를 오래 붙잡고 있을 위험 확인
- 원인
- LLM 응답은 번역 분량에 따라 수초에서 수십 초가 걸리는데, 저장용 커넥션을 미리 잡고 응답을 기다리면 그 시간만큼 운영 트래픽이 쓸 커넥션이 묶임
- 해결
- LLM 호출 구간과 DB 저장 구간을 분리해 대기 중에는 커넥션을 점유하지 않도록 조치 - 연결 풀은 최소 1 최대 2 로 묶고, lock_timeout 1.5초 · statement_timeout 5초를 걸어 오래 버티는 대신 빨리 포기하도록 설정
여러 인스턴스가 동시에 뜰 경우 같은 행을 중복 번역하는 이슈
- 원인
- 기존 배치 Worker 가 이미 실행 중인지 확인할 방법이 없어, 프로세스가 둘 이상일 경우 같은 대상을 각자 처리했습니다.
- 해결
- PostgreSQL advisory lock 을 통해 Worker 진입을 직렬화해 인스턴스 간 중복 실행을 차단했습니다.
저장 단계에서 실패한 건이 기록 없이 사라지는 현상
- 원인
- UNIQUE 충돌 · lock 대기 · statement timeout · 응답 검증 실패가 모두 예외로 끝나면서, 어떤 항목이 왜 빠졌는지 남지 않았습니다.
- 해결
- 실패 유형을 구분해서 수동 처리 큐로 이관하고 작업 이력에 기록했습니다. 풀 대기가 1초를 넘는 건도 실패로 처리하지 않고 같은 큐로 보내 다시 검토할 수 있게 했습니다.
기여도 · 1인 개발 - CLI 배치 · 웹 콘솔 Front-end · DB 연동 Back-end