알려진 이슈¶
인수인계 시점(2026-05-11)에 존재하는 알려진 이슈·한계의 통합 목록.
각 기능 페이지(03-features/*.md)의 "알려진 이슈" 섹션을 카테고리별로 재정렬하고, 운영·인프라 한계와 인수인계 결정 미정 항목을 합쳤다.
각 항목 형식: 이슈 / 코드 위치 / 영향도 / 해결 방안 / 담당 PR·Issue.
1. 보안 우려¶
| # | 이슈 | 위치 | 영향도 | 해결 방안 | 담당 |
|---|---|---|---|---|---|
| S1 | RDS Security Group sg-09b20a06663fcfa01이 0.0.0.0/0:3306 인터넷 노출 |
AWS SG | HIGH (prod DB가 노출됨) | Hard cutover 후 잠금 — MyIP/32 + Lightsail VPC peer CIDR만 허용 |
Issue #151 (cutover 후) |
| S2 | /auth/test profile-gate 미적용 |
AuthController.kt /auth/test |
MED (운영 노출 시 임의 번호 SMS 발송 가능) | @Profile("local") 또는 SecurityConfig 단에서 prod 차단 |
별도 PR (#170은 /accounts/test/**만 처리) |
| S3 | 카드사 심사 백도어 (01099999999 → 999999) |
AuthService.issuePhoneAuthentication() //TODO - 카드사 심사 통과시 제거 |
MED (PG 심사 완료 후 제거 예정) | TODO 주석대로 코드 삭제 | PG 심사 후 |
| S4 | 시크릿이 일부 yaml에 하드코딩 (Langfuse local, RDS password 등) | application-prod.yml, application.yml |
사용자 수락됨 (CLAUDE.md feedback_accepted_repo_secrets) |
별도 rotation 예정 — hard cutover 시점 | hard cutover 시 |
| S5 | Toss webhook signature 검증 부재 | TossWebhookController |
LOW (DoS 가능성) | Toss V2는 서명 미지원 — paymentKey re-fetch로 차단 중. 추가 대책 미정 |
— |
| S6 | 인증코드 무제한 재시도 (rate limit 부재) | PhoneAuthentication.verify() |
LOW (코드 6자리 → 시도 100만 회 brute force 가능) | rate limit 미구현 | 추후 |
| S7 | 어드민 작업 audit log 부재 (회원 권한/상태 변경, 쿠폰 발급, 결제 승인) | AdminService 전반 |
MED (사후 추적 불가) | AdminAuditLogController 확장 |
추후 |
2. 백엔드 코드 이슈 (기능 페이지에서 발견된 TODO 집약)¶
인증 / 회원¶
- OAuth2 도메인 코드 존재하나 미사용:
OAuth2Account,OAuth2Provider등. 카카오/네이버 로그인 도입 시 활용 예정.
멤버십 / 결제¶
- 만료 후 grace period 없음: 자동 갱신 실패 시 즉시
isSubscriptionPaused=true. 사용자 재시도 안내·재충전 유예 미구현 (SubscriptionRenewalScheduler.processRenewals()). - 취소 시 잔여 일수 비례 환불 미구현:
cancelTossPayment는 전액 취소만. 부분 환불 없음. - 결제
WAITING_DEPOSIT정리 cron 부재: 가상계좌 미입금 PENDING이 누적 가능. - 단일 활성 결제수단 가정:
paymentMethodRepository.findActivatedAndDeactivatedByAccountId(accountId)가 single-row 반환 가정. 멀티 카드 시 비정상. - PortOne V1 잔재:
PaymentStatus에PRE_VERIFICATION,POST_VERIFICATION,ADDITIONAL_VERIFICATION등 미사용 가능성 있는 상태값. 정리 필요 (Issue #109 카리오버). registerPaymentrecommender 검증 없음: 추천인 코드가 free-form. 실재/중복 검증 없음.- 테스트 전용 메서드가 production 서비스 클래스에 혼재 (
switchTierForTest,injectCycleUsageForTest,grantTokenPackForTest): profile gate 검증 필요.
쿠폰¶
- 5자리 PK birthday collision (가장 시급):
Coupon.createRandom()UUID hex 앞 5자리만 사용 →16^5 ≈ 1M공간. ~1200건 발급 시 birthday paradox 임계 도달.couponRepository.saveAll()단일 트랜잭션이라 1건 충돌 시 전체 rollback. 6-8자리 확장 또는 retry 로직 필요. - TOKEN_PACK 쿠폰 런타임 깨짐:
Coupon.productType=TOKEN_PACK일 때Membership.byCoupon이MembershipType.valueOf("TOKEN_PACK")시도 → enum에 없어IllegalArgumentException. 어드민 발급 폼에는 선택지로 노출됨. - 만료일 부재: 발급 쿠폰은 영구 유효. 캠페인 종료 후 차단 메커니즘 없음.
- 할인율·금액쿠폰 미지원: 1쿠폰 = 1개월 멤버십 발급만 지원.
- 응답이 enum (OK/USED/INVALID)인데 status는 200: 클라이언트가 body 파싱해야 분기. RESTful하게 4xx로 변경 여지.
RAG / 카테고리 / 리포트¶
TaxCategoryInferenceService가 Langfusetemperature/maxTokens무시:KeywordExtractionService는 fix됐으나analyzeQuestionWithLlm()은 여전히 ChatCompletionRequest에 전달 안 함 (Issue #148 carryover).- 백필 API 동기 처리 → ALB 60s timeout 위험:
POST /admin/conversations/backfill-keywordsLLM 1건당 ~500ms.limit=500이면 ~4분 — ALB/Cloudflare 기본 timeout 60s 초과 시 클라이언트가 응답 못 받음 (백엔드는 계속 실행). prod에서는limit=100으로 chunk 또는 비동기 job 전환 권장 (Issue #148 미해결). - HyDE prod 설정 미명시:
application.yml에true로 활성화돼 있으나application-prod.yml에 override 없음. prod에서 끄려면 명시 필요. intent-router.unified.enabledprod 미설정: prod yaml에 명시 없음 — 기본 false(Phase 0, LLM 3회) 동작. Phase 1(단일 호출) 원하면 prod에서 명시 true 필요.- SSE 3분 hardcoded:
SSE_TIMEOUT = 180_000L. 매우 긴 답변 잘릴 수 있음. - Citation tag 누락 시: LLM이
<citations>...</citations>를 안 붙이면parseCitedIds()가 빈 리스트 → 필터링 비활성. 프롬프트 변경 시 회귀 주의. - Migration 미적용 환경의
isArchiveEligible=null: Issue #148 이전 세션은 NULL.infra/sql/...V20260430_1...을 수동 적용해야 게시판에 노출됨. COMMERCIAL_LAW/ACCOUNTING카테고리 검증 필요:LawCategory.values()동적 노출. 클라이언트 의도와 일치 여부 별도 확인.- Keyword 재추출 트리거 부재:
keywords != null가드로 추가 turn 와도 재추출 안 됨. 강제 갱신은 백필 endpoint만. - Legacy
Report도메인 미사용:Report/ReferenceData/SimilarData테이블은 admin 조회 +ReportCleanercron만 남음. 신규 코드는 안 씀 — schema cleanup 후보.
관리자 콘솔¶
- 감사 로그 보존 정책 미정:
elasticsearch_audit_log만료/삭제 cron 없음 → 무기한 누적. /admin/paymentsv1 //admin/payments/v2병행: Issue #109 잔재. Toss V2 안정화 후 v1 정리 필요.- 소프트 삭제만:
AdminService.deleteReport()는 entitydelete()호출 — 물리 삭제 아님. 조회 쿼리에서 deleted flag 필터링 필요.
팝업 / 공지¶
- 기능 자체가 미구현: 사용자 공지 채널 + 점검 모드 toggle 모두 부재. 점검은 현재 시스템 다운으로 처리.
3. 인프라 한계¶
| # | 이슈 | 영향도 | 해결 방안 |
|---|---|---|---|
| I1 | Flyway 미사용 | HIGH (마이그레이션 수동 적용 — 누락 위험) | 마이그레이션 파일을 infra/sql/2026-05-11-prod-init.sql 패턴으로 수동 적용. Flyway 도입은 별도 이슈 |
| I2 | 백엔드 Sentry 미설치 | MED (런타임 예외 추적이 journalctl만) |
sentry-spring-boot-starter 도입 별도 이슈 |
| I3 | prod Toss live keys 사용자 제공 대기 | HIGH (Issue #151 blocker) | user 제공 후 prod env-var 주입 |
| I4 | PR 미리보기 (Cloudflare Pages) — Phase 3 발견 | LOW | 다음 PR부터 정상 동작 예상. 현재까지는 Cloudflare Pages 프로젝트 생성 후에 만들어진 PR만 preview 가능 ⚠️ (검증 필요) |
| I5 | 외부 reachability pinger 부재 | MED (사용자 보고가 1차 채널) | UptimeRobot 등 SaaS 연동 별도 이슈 |
| I6 | CloudWatch 알람 미설정 (RDS FreeStorageSpace, ALB 5xx 등) | MED | CloudWatch Alarm + SNS → Slack 연동 별도 이슈 |
| I7 | Prod Lightsail에 disk-alarm/health-monitor 미배포 | MED | semugpt-prod box 생성 시 dev와 동일 패턴 복제 (Issue #151 Phase 5) |
| I8 | RDS storage 17 GB free / autoscaling to 1000 GB | LOW (당장 여유) | 모니터링만 |
| I9 | RDS max_connections=60 (현재 13 사용) | LOW | 신규 backend Hikari maximum-pool-size: 10 권장 |
| I10 | Lightsail 8 GB RAM 충분한지 미검증 | LOW | 모니터링 후 부족 시 xlarge_3_0 (16 GB, $84/mo) 승급 |
4. 인수인계 결정 미정¶
cutover 전·후로 stakeholder 결정이 필요한 항목.
| # | 항목 | 현재 상태 | 결정 시점 |
|---|---|---|---|
| D1 | 사용자 재가입 안내 | Soft launch라 무관 (legacy 사용자는 계속 legacy 사용) | Hard cutover 시점 |
| D2 | Backend secret rotation | 현재 legacy + 신규 app이 같은 secret 공유 | Hard cutover 시점 |
| D3 | 백필 endpoint 비동기 전환 | 동기 처리 (60s timeout 위험) | Issue #148 후속 |
| D4 | Hard cutover 시점 (apex/www/api/pro → 새 인프라) | 무기한 연기 | 클라이언트 의사결정 대기 |
| D5 | Legacy EC2 decommission | hard cutover 1주 후 terminate 예정 | hard cutover 후 |
| D6 | Toss webhook URL prod 등록 | 미등록 — Toss 콘솔에서 https://api-new.semugpt.co.kr/webhooks/tosspayments 추가 필요 |
Phase 5 deploy 시 |
5. 위키 자체의 한계¶
- Phase 3 fact-check audit에서 18개 사실 오류 catch — 8개 기능 페이지 작성 시 SMS 구현체 오인용(AWS SNS → 실제는 Naver Cloud SENS), Toss webhook path, coupon delete 정책,
LawCategory갯수, 존재하지 않는application-dev.yml참조 등. 자세한 prior incidents는docs/wiki/CLAUDE.mdChapter 10 참조. - 코드 변경 시 wiki와 drift 가능 — 정기적 audit 권장. wiki는 진실의 소스가 아니라 스냅샷 — 의심스러우면 코드를 1차 출처로 확인.
- 일부 ⚠️ Uncertain 항목 남아있음 — Phase 3 PR description의 "남은 ⚠️ Uncertain" 섹션 참조. 본 페이지의 표에도
⚠️ (검증 필요)마킹으로 표시. - OpenAPI 페이지의 schema anchor 링크 불안정 — 직접 anchor 링크 사용 금지, endpoint별 검색 유도 (
CLAUDE.mdChapter 6).