Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
145 commits
Select commit Hold shift + click to select a range
a3c9a37
#250 [Fix] 투표 비율 계산 기준을 preVoteOption에서 postVoteOption으로 수정 (#252)
HYH0804 May 27, 2026
a38c141
#254 [Refactor] 관점 등록/수정 시 GPT 검수 코드 제거 (#256)
HYH0804 Jun 3, 2026
cee2c5d
#255 [Refactor] VoteStatsResponse OptionStat에 title 필드 추가 (#257)
HYH0804 Jun 3, 2026
53533b8
#258 [Feat] 출석체크 API 추가
si-zero Jun 3, 2026
77db7a1
#260 [Feat] 스웨거 어드민/유저 분리
si-zero Jun 4, 2026
a9d4293
[Feat] 알림기능 (#263)
HYH0804 Jun 11, 2026
b5a681b
#262 [Fix] APNs 자격증명 S3 다운로드 시 임시파일 충돌 오류 수정
HYH0804 Jun 11, 2026
d281fa3
#264 [Fix] AdMob SSV 포인트 미적립 버그 수정
si-zero Jun 11, 2026
968d6a3
#262 merge (#266)
HYH0804 Jun 14, 2026
d041631
[Chore] adMob 크롤링 파일 설정: adMob 크롤링 파일 설정 #269
si-zero Jun 16, 2026
ec25882
#270 [Feat] 설정 파일 추가
si-zero Jun 16, 2026
4c45999
[Chore] JWT필터 설정 #271
si-zero Jun 16, 2026
e0c9c1c
#275 [Fix] AdMob SSV 콜백 파라미터 optional 처리 및 서명 검증 활성화
si-zero Jun 18, 2026
ab2cb78
#277 [Fix] AdMob SSV 콜백 URL 검증 요청 처리 실패
si-zero Jun 18, 2026
04d947c
#279 [Fix] AdMob SSV 엔드포인트 검증 실패 시 항상 200 반환
si-zero Jun 18, 2026
d9ea3b5
#283 [Fix] /me/content-activities voteSide null 반환 버그
si-zero Jun 19, 2026
ec27b01
#285 [Feat] content-activities 응답에 option_title 필드 추가
si-zero Jun 20, 2026
6663e7a
#287 [Fix] AdMob SSV 서명 검증 오류로 인한 포인트 미지급 버그
si-zero Jun 24, 2026
39aca84
#289 [Fix] 오늘의 배틀 개수 변경
si-zero Jul 5, 2026
11e2da1
#293 [Fix] 사전투표 철학자 아이콘 미노출
si-zero Jul 5, 2026
aa449f0
#297 [Fix] 댓글 작성 시각이 9시간 전으로 표시되는 버그
si-zero Jul 6, 2026
3259a1a
#301 [Fix] robots.txt 파일 부재로 AdMob app-ads.txt 크롤링 차단
si-zero Jul 6, 2026
e91819b
#305 [Fix] S3 오디오 조각 재다운로드 시 FileAlreadyExistsException으로 TTS 파이프라인 실패
si-zero Jul 6, 2026
d64d5ca
#309 [Fix] JwtFilter 자체 화이트리스트에 /robots.txt 누락으로 401 발생
si-zero Jul 6, 2026
ff16d85
#316 [Fix] 포인트 정책표 대비 코드 불일치 4건 수정
si-zero Jul 7, 2026
f50c749
Merge branch 'main' into dev
si-zero Jul 7, 2026
d9e28a1
#321 [Feat] 알림 미읽음 여부 확인 API 추가
si-zero Jul 7, 2026
4279341
#313 [Hotfix] Railway 배포 환경 FFmpeg 자동 설치 적용 (#320)
jucheonsu Jul 7, 2026
f77048c
#327 [Fix] 알림 전체 읽음 처리 후 모두 읽음 신호가 전달되지 않던 문제 수정
si-zero Jul 13, 2026
99886f9
#331 [Docs] 출석체크 API 명세서를 실제 코드에 맞춰 갱신
si-zero Jul 13, 2026
087b8c0
#333 [Fix] app-ads.txt가 text/html로 응답되어 AdMob 크롤러가 무시하는 문제 수정
si-zero Jul 13, 2026
d33ff1f
#337 [Feat] 인앱 알림 테스트용 API 추가
si-zero Jul 14, 2026
17f35a4
#341 [Fix] 미문서화/중복 포인트 지급 로직 정리
si-zero Jul 15, 2026
acbe078
관리자 페이지를 새 admin-web(Next.js) 앱으로 리다이렉트 (#346)
Jul 15, 2026
de75bdf
#349 [Feat] admin.web.url env 주입 + 기본값 picke.up.railway.app (#350)
Jul 15, 2026
9493351
#352 [Fix] JwtFilter 화이트리스트 /api/v1/auth 전체 매칭으로 logout 인증 우회, 500 에러 발생
si-zero Jul 16, 2026
00bfcb3
#356 [Feat] 이용약관/개인정보처리방침 페이지 백엔드 서빙
si-zero Jul 20, 2026
99c936d
#361 [Feat] 관리자용 테스트 계정 로컬 로그인 기능 추가
si-zero Jul 24, 2026
f0a837d
#360 [Refactor] 1인 1관점 제한을 해제하고 1인 다수 관점 등록 허용
si-zero Jul 24, 2026
9fb601f
#366 [Feat] 내 콘텐츠 활동 내역(댓글 탭)에 내가 작성한 관점 포함
si-zero Jul 24, 2026
6a1abde
#370 [Fix] 사전투표만 한 기록도 내 배틀 기록에 노출되는 버그
si-zero Jul 24, 2026
80f5b9c
[Feat] 관점 200자 제한 해제 (#375)
si-zero Aug 2, 2026
f9bc278
#378 [Feat] 관리자 예약 푸시알림(제목/소제목/발송시간) 설정 및 자동발송
si-zero Aug 8, 2026
99f4765
#382 [Fix] 내 콘텐츠 활동 댓글 정보 매핑 오류 수정 (#383)
jucheonsu Aug 9, 2026
79cb355
#387 [Refactor] 철학자 태그 제한 및 가치관 육각형 계산 보정 (#388)
jucheonsu Aug 13, 2026
bdbe3b3
#391 [Remove] 미사용 파일 정리 (비활성 CI 워크플로우 + 레거시 admin 프론트)
si-zero Aug 13, 2026
a82c575
#392 [CI/CD] Java CI 파이프라인 브랜치명 오류 및 지속적 빌드 실패 수정
si-zero Aug 13, 2026
70ccc90
#395 [Feat] 관리자용 푸시 알림 발송 테스트 API 추가
si-zero Aug 16, 2026
2e72bf7
#396 [Fix] Android FCM 푸시에 title/body가 실리지 않아 알림이 안 뜨던 문제 수정
si-zero Aug 16, 2026
1fc8488
#401 [Fix] FCM 만료된 디바이스 토큰이 정리되지 않아 반복 발송 실패 로그가 쌓이는 문제 수정
si-zero Aug 17, 2026
a4d3b31
#405 [Feat] 어드민 예약 알림 On/Off 전환 API 추가 및 관리자 알림 API 문서화
si-zero Aug 26, 2026
0b9a374
#407 [Feat] 어드민 유저 검색 API 추가
si-zero Aug 26, 2026
869de77
#409 [Feat] 어드민 공지사항 수정/삭제 API 추가
si-zero Aug 26, 2026
087fea5
#411 [Feat] 어드민 공지 발송 결과 조회 API 추가
si-zero Aug 26, 2026
4bdbdf3
#413 [Feat] 어드민 공지 발송 대상자 수 미리보기 API 추가
si-zero Aug 26, 2026
76e8097
#414 [Feat] 어드민 공지 작성 옵션(카테고리) 조회 API 추가
si-zero Aug 26, 2026
26116e8
#415 [Feat] 어드민 예약 알림 테스트 발송 API 추가
si-zero Aug 26, 2026
4234c29
#423 [Docs] 누락된 마이그레이션 SQL 파일 보완 (#409, #411)
si-zero Aug 30, 2026
7aaa1f4
#421 [Feat] 유저 일별 활동 트래킹(DAU/MAU 기반) 인프라 구축
si-zero Aug 30, 2026
d3b9343
#425 [Feat] 어드민 대시보드 오늘 요약 API 추가
si-zero Sep 1, 2026
2129d35
#427 [Feat] 어드민 대시보드 DAU/MAU 추이 API 추가
si-zero Sep 1, 2026
d8fe672
#429 [Feat] 어드민 대시보드 신규 가입자 추이 API 추가
si-zero Sep 1, 2026
6eea0d4
#431 [Feat] 어드민 대시보드 배틀 참여율 API 추가
si-zero Sep 1, 2026
1e134bc
#433 [Feat] 어드민 대시보드 출석 체크율 API 추가
si-zero Sep 1, 2026
cba91cb
#436 [Feat] 어드민 대시보드 크레딧 지급 현황 API 추가
si-zero Sep 2, 2026
23496d1
#444 [Refactor] AWS S3를 Railway Bucket으로 마이그레이션 (개발 서버)
si-zero Sep 7, 2026
7b0b68f
🐛 Fix: BattleVoteServiceImplTest 시간대 불일치로 15시(UTC) 이후 CI 실패 (#442)
Roy-wonji Sep 7, 2026
c99065e
✨ Feat: ad.picke.store 제휴 광고(쿠팡 파트너스·애드픽) 연동 (#443)
Roy-wonji Sep 8, 2026
d22f21a
#441 [Fix] 쿠팡 파트너스 ID 환경변수 누락 시 앱 부팅 실패 해소 (#448)
Roy-wonji Sep 8, 2026
9745f2e
#441 [Fix] 광고 스웨거 기본 서버를 문서를 연 주소로 바꿈 (#449)
Roy-wonji Sep 8, 2026
e5a0422
#441 [Fix] 필수 쿼리 파라미터 누락 시 500 대신 400 응답 (#450)
Roy-wonji Sep 8, 2026
c3bd52b
#441 [Feat] 광고 스웨거 탭에 운영 광고 도메인 추가 (#451)
Roy-wonji Sep 8, 2026
476b0dd
#441 [Feat] 애드픽 쇼핑·핫딜 상품을 광고 재고로 편입 (#454)
Roy-wonji Sep 8, 2026
495f772
#441 [Feat] 애드픽 쇼핑 상품에 더 높은 로테이션 가중치 부여 (#457)
Roy-wonji Sep 9, 2026
093278c
AdFit 수익과 비용을 기록해 관리자 ROI를 확인하도록 지원
Roy-wonji Sep 10, 2026
73a4214
test: 사용자 광고 API 조회 계약 검증 (#460)
Roy-wonji Sep 10, 2026
27e7b79
fix: 사용자 광고에서 설치·가입 캠페인 제외 (#463)
Roy-wonji Sep 10, 2026
a612828
feat: AdFit 일별 수익 자동 조회 연결 (#465)
Roy-wonji Sep 10, 2026
6891d33
#455 [Feat] 배틀 시나리오 감정 톤 + 철학자 보이스 매핑 인프라
si-zero Sep 10, 2026
291918c
#467 [Feat] 배틀 대본 붙여넣기 파서 (배틀·시나리오 자동 등록)
si-zero Sep 11, 2026
3ed96b8
#469 [Feat] 배틀 대본 파서 대사를 문장 종결부호 단위로 분리
si-zero Sep 11, 2026
8efa2ad
#471 [Feat] 배틀 대본 파서 summary·description·선택지 title 매핑 수정
si-zero Sep 11, 2026
073dfd5
#473 [Feat] 시나리오 선택지에 선택의 시간 설명 텍스트(title) 추가
si-zero Sep 11, 2026
58ce7ad
#475 [Feat] 철학자 보이스 매핑에 이미지 키(image_key) 추가
si-zero Sep 12, 2026
759f746
#477 [Docs] 철학자 보이스 매핑에 실제 이미지 키 반영
si-zero Sep 12, 2026
7a41a14
#479 [Fix] 철학자 보이스 imageKey 응답을 호출 가능한 경로로 변환
si-zero Sep 12, 2026
4cf5227
#481 [Fix] 배틀 옵션 태그 수정 시 유니크 제약 위반(23505) 발생
si-zero Sep 12, 2026
a7b0c3b
#483 [Fix] 로컬 draft→S3 promote가 DB 트랜잭션과 분리되어 orphan 파일/유실 위험
si-zero Sep 12, 2026
e3e5bd8
feat: 애드픽 쇼핑 재고 확대 + AdFit 세션 갱신 + Mixpanel·Sentry 지표 (#487)
Roy-wonji Sep 14, 2026
d6566c3
개발 서버도 운영과 같은 관리자 지표 계약을 제공하게 한다
Roy-wonji Sep 14, 2026
9ef0aa0
feat: Sentry 전체 관측 데이터와 가입 추이 개발 반영 (#492)
Roy-wonji Sep 14, 2026
df9acca
[Fix] Sentry trace metric 시계열 집계 오류 수정 (#494)
Roy-wonji Sep 14, 2026
88661ac
feat: Sentry 회원가입 지표를 일별 시계열로 제공 (#496)
Roy-wonji Sep 14, 2026
1e01dde
feat: Sentry 사용자 이벤트 전체 집계 (#498)
Roy-wonji Sep 14, 2026
8935a92
fix: Sentry 이벤트 전체 조회 복구 (#501)
Roy-wonji Sep 14, 2026
724c75e
fix: Sentry 회원가입 사용자 결측값 유지 (#503)
Roy-wonji Sep 14, 2026
e1fa37d
fix: Sentry 이벤트 배치 누락 제거 (#505)
Roy-wonji Sep 14, 2026
9d43c11
feat: Mixpanel 이벤트 퍼널 이탈율 조회 (#507)
Roy-wonji Sep 28, 2026
9a298dc
#509 [Fix] 시나리오 병합 오디오 재생성 시 URL 갱신
si-zero Oct 1, 2026
b9ca424
#513 [Fix] 어드민 시나리오 조회 응답에 노드 연결 정보 추가
si-zero Oct 1, 2026
ce2f45e
#517 [Feat] 배틀 썸네일 AI 후보 생성 API
si-zero Oct 4, 2026
4bb85ab
#519 [Fix] 썸네일 후보를 제목 기반 장면으로 생성하고 안전 필터 거절 구분
si-zero Oct 4, 2026
9d1bb90
#521 [Feat] 썸네일 프롬프트 구조화 및 레퍼런스 이미지 확대
si-zero Oct 14, 2026
a2ba1ca
#524 [Feat] 썸네일 디자인 시스템 팔레트 적용 및 레퍼런스 2장으로 축소
si-zero Oct 19, 2026
1faefbc
#523 [Docs] 클래스 기능 ERD 정의 (#527)
HYH0804 Oct 19, 2026
ec60a31
#528 [Feat] 클래스 엔티티 및 스키마 SQL 정의 (#529)
HYH0804 Oct 19, 2026
4b9f0ce
Fix: 이용권·클래스 PRD 정합성 보완 (본인 재등록, 코드 미리보기, 환불 이용권 마감) (#536)
HYH0804 Oct 19, 2026
27eb7fb
#537 [Feat] 클래스 초대코드 참여 및 멤버 관리 API (#538)
HYH0804 Oct 19, 2026
dabc6e1
#539 [Feat] 클래스 내 배틀 진행 class_id 스코핑 및 일반 배틀 격리 (#540)
HYH0804 Oct 19, 2026
36551e4
#541 [Feat] 클래스 결과·AI 리포트 (개인 피드백·클래스 인사이트) (#542)
HYH0804 Oct 19, 2026
c2ec790
#543 [Feat] 어드민 펀딩 명단 가져오기·이용권 코드 발급·재발급·환불 (#544)
HYH0804 Oct 19, 2026
b7e3037
#545 [Feat] 클래스 커스텀 배틀 AI 주제 제안 및 수정 검증 API
si-zero Oct 21, 2026
03933c0
#547 [Feat] 검증된 주제로 커스텀 배틀 클래스 생성
si-zero Oct 21, 2026
fe3f717
#548 [Feat] 커스텀 배틀 AI 철학자 3라운드 토론
si-zero Oct 21, 2026
e0aee2f
#551 [Feat] 클래스 Picke 배틀 추천 API 및 어드민 배틀 클래스 설정
si-zero Oct 21, 2026
bee8cc6
#553 [Feat] 클래스 참여 코드 확인 API 및 삭제된 클래스 구분
si-zero Oct 21, 2026
da247e3
#555 [Docs] 클래스 API 명세서
si-zero Oct 21, 2026
6c2a2b0
#557 [Fix] 클래스 의견·댓글 좋아요 API 클래스 권한 검사
si-zero Oct 21, 2026
50ec87b
#559 [Fix] 클래스 의견·댓글 신고 API 클래스 권한 검사
si-zero Oct 21, 2026
e821c20
#563 [Feat] AI 철학자 토론 반박 입력 차단 (위협·개인정보)
si-zero Oct 22, 2026
c44e672
#565 [Feat] 이용 종료 후 30일 지난 클래스 원문·AI 대화·리포트 파기
si-zero Oct 22, 2026
1683a90
#567 [Feat] AI 철학자 토론에 대상 수준별 반론 난이도 반영
si-zero Oct 22, 2026
b22072b
#569 [Feat] 클래스 기획 확인 반영 (AI 주장·반박 길이·TTS 청취 필수·필수 의견 삭제 차단)
si-zero Oct 23, 2026
c53e30f
#571 [Feat] 어드민 배틀 목록 수준 노출 및 기존 배틀 수준 초급 일괄 설정
si-zero Oct 23, 2026
179f964
#573 [Fix] 클래스 배틀 테스트 날짜를 KST 기준으로 생성
si-zero Oct 23, 2026
1f63e5c
#575 [Feat] 클래스 멤버 초대코드 노출 및 의견·댓글 작성자 클래스 표시 이름 노출 (#579)
HYH0804 Oct 28, 2026
eea7198
#576 [Feat] 클래스 생성 중복 요청 방지 (#580)
HYH0804 Oct 28, 2026
f2134e1
#577 [Feat] 중간투표 있는 기존 콘텐츠의 클래스 중간투표 수집 및 리포트 반영 (#581)
HYH0804 Oct 28, 2026
1dc6db2
#589 [Feat] 미등록 이용권 등록기한 임박 알림 대상 조회·발송 기록 (#590)
HYH0804 Oct 28, 2026
96e3f4a
#561 [Feat] 텀블벅 후원자 엑셀 연동 및 클래스 이용권 운영 기능 확장 (#562)
jucheonsu Oct 28, 2026
8fa5930
#578 [Feat] 관점·댓글 200자 초과 제한 (#591)
jucheonsu Oct 28, 2026
8dcfcdb
#582 [Feat] 클래스 리포트 내 활동 조회 API 추가 (#592)
jucheonsu Oct 28, 2026
d82439e
#583 [Feat] 홈·배틀 카드 응답 필드 보완 (#593)
jucheonsu Oct 28, 2026
965b3e8
#584 [Feat] 회원 탈퇴 시 클래스·좌석·콘텐츠 처리 (#594)
jucheonsu Oct 28, 2026
57142f3
#585 [Feat] 잘못된 커서·DB 제약 오류를 400/409로 정리 (#595)
jucheonsu Oct 28, 2026
1e2d311
#586 [Feat] 관리자 펀딩 주문·이용권 대시보드 API 확장 (#596)
jucheonsu Oct 28, 2026
4612d98
#587 [Feat] 텀블벅 Start·Run 등록 및 전달 흐름 분리
jucheonsu Oct 28, 2026
517791d
#588 [Refactor] com 패키지 타입 참조를 import로 이동 (#598)
jucheonsu Oct 28, 2026
9770918
#603 [Fix] JwtFilter 계정 상태 검사에서 정상 계정이 401로 막히는 문제 수정
si-zero Nov 2, 2026
2414863
#606 [Fix] 회원 탈퇴·펀딩 변경 이후 깨진 기존 테스트 수정
si-zero Nov 2, 2026
0eb3bf4
#602 [Feat] AI 철학자 반박 프롬프트 고도화 (철학자 프로필·수준별 기준·말풍선)
si-zero Nov 7, 2026
e7f5677
#608 [Feat] AI 주제 제안 실패 사유 응답 추가
si-zero Nov 7, 2026
bb309fb
#610 [Feat] 기획 확정 배틀별 수준 일괄 반영 SQL 추가
si-zero Nov 7, 2026
8145e85
#612 [Fix] 펀딩 다중 수량 발급 이후 깨진 펀딩 테스트와 주문 목록 500 수정
si-zero Nov 7, 2026
80514c8
Merge remote-tracking branch 'origin/main' into merge/#614
si-zero Nov 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
868 changes: 868 additions & 0 deletions BACKEND_ARCHITECTURE.md

Large diffs are not rendered by default.

86 changes: 86 additions & 0 deletions FUNDING_API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# 펀딩 API — origin/dev 통합 기준

공통 주문·이용권 처리는 최신 `domain.ticket`과 `domain.admin`을 사용합니다.
`domain.funding`은 텀블벅 XLSX, 원본 행 보관, 상세 검색과 감사 로그를 확장합니다.
모든 아래 경로의 접두사는 `/api/v1`입니다.

| 기능 | Method / 경로 |
| --- | --- |
| CSV 주문 등록·갱신 | `POST /admin/funding/imports` |
| 주문·이용권 목록 및 텀블벅 원본 정보 | `GET /admin/funding/orders` |
| 캠페인별 후원자 목록 | `GET /admin/funding/orders?campaignId=...` |
| 텀블벅 캠페인 대시보드 요약 | `GET /admin/funding/orders/tumblbug/dashboard?campaignId=...` |
| 펀딩 현황 | `GET /admin/funding/summary` |
| 코드 발급 | `POST /admin/funding/tickets/issue` |
| 관리자 코드 조회·복사 | `GET /admin/funding/tickets/{ticketId}/code` |
| 전달 기록 | `POST /admin/funding/tickets/{ticketId}/deliveries` |
| 미등록 코드 재발급 | `POST /admin/funding/tickets/{ticketId}/reissue` |
| 주문 환불·이용권 취소 | `POST /admin/funding/refunds` |
| 사용자 코드 확인 | `GET /class-tickets/preview?code=...` |
| 사용자 코드 등록 | `POST /class-tickets/register` |
| 내 이용권 | `GET /class-tickets/me` |
| XLSX 시트·열·샘플 검사 | `POST /admin/funding-orders/tumblbug/inspect` |
| 선택 시트 검토 | `POST /admin/funding-orders/tumblbug/preview` |
| Start·Run 공통 엑셀 등록 및 발급 | `POST /admin/funding-orders/tumblbug/import` |
| Start·Run 공통 구매자 수동 등록 | `POST /admin/funding-orders/tumblbug/manual` |
| 주문 저장·발급·디지털 선물 XLSX 생성 | `POST /admin/funding-orders/tumblbug/digital-gifts` |
| 텀블벅 전달 결과 기록 | `PATCH /admin/funding-orders/tumblbug/digital-gifts/delivery` |
| 이용권·등록자·등록일 검색 | `GET /admin/tickets` |

## 텀블벅 XLSX

관리자 API는 `ROLE_ADMIN`이 필요합니다. 검사는 multipart `file`, 미리보기와 발급은 `file`과 JSON `options` 파트를 사용합니다.
파일은 XLSX 10MB 이하, 최대 5,000개 데이터 행입니다. 선물 수량은 1~7이며 코드도 수량만큼 발급합니다.

```json
{
"campaignId": "picke-class-2026",
"campaignName": "픽케 클래스 펀딩",
"sheetName": "15인 이용권",
"rewardLineId": "class-ticket-15",
"capacity": 15,
"sourceVersion": "export-20261021",
"plan": "START"
}
```

`campaignId`는 50자 이하이며 `rewardLineId`를 생략하면 시트명을 사용합니다. `plan`은 `START` 또는 `RUN`이며 생략 시 기존 API와의 호환을 위해 `RUN`으로 처리합니다. 캠페인을 처음 등록할 때 선택한 요금제는 고정됩니다.
필수 열은 후원번호, 이름, 선물, 추가 후원금, 총 후원 금액, 후원 일시, 알림 신청, 결제 상태, 선물 전달입니다.
미리보기는 저장하지 않습니다. 중복 또는 잘못된 행이 있으면 발급 요청 전체를 거부합니다.

**결제 완료·후원일시 존재**인 주문은 구매 수량만큼 코드를 발급합니다.
결제 예약 상태는 저장만 하고 코드를 발급하지 않습니다. `codeEligibleRows`는 결제 완료된 행 수입니다.
등록기한은 결제일 + 1년, 이용기간은 등록일 + 6개월입니다.
재발급은 기존 이용권을 무효화하고 같은 등록기한으로 새 행을 생성합니다.
코드 형식은 `XXXXXX-XXXXX-XXXXX-XXXXX-XXXXX`입니다. SHA-256 해시로 코드를 검증하고 AES-GCM 암호문으로 관리자 코드 보기를 지원합니다.

발급 주문은 최신 `FundingOrder`에 저장하고 `AdminFundingService`로 `ClassTicket`을 발급합니다.
후원번호·리워드 키·금액·알림·원본 전달 상태·원본 행 JSON은 `TumblbugImportRecord`에 보관합니다.
내부 주문번호는 캠페인·후원번호·리워드 키의 SHA-256으로 만든 50자 식별자 `TB-...`입니다.
기존 CSV에 동일 후원번호의 주문이 있는 경우에도 중복으로 취급합니다.

전달 결과 요청 필드는 `campaignId`, `rewardLineId`, `supporterNumbers`, `status`(`SENT`/`FAILED`), `failedReason`입니다.
실패에는 사유가 필요합니다. 공통 이력에는 `TUMBLBUG_DIGITAL_GIFT` 채널 및 `SUCCESS`/`FAILED` 상태로 기록합니다.
이미 등록·취소되었거나 결과를 기록한 코드는 건너뛰고, 재발급 코드는 새 이용권 ID로 구분합니다.
Start는 공통 `import` 또는 `manual` 경로로 등록하고 1:1 메시지로 직접 전달합니다. Run은 같은 경로에 더해 `digital-gifts` XLSX 경로를 쓸 수 있습니다. 실제 텀블벅 전달은 관리자가 수행합니다.

## 검색과 클래스 연동

주문 검색은 기존 `/admin/funding/orders` 한 곳에서 `campaignId`, `keyword`, `capacity`, `paymentStatus`, `deliveryStatus`, `ticketStatus`, `codeStatus`, `page`, `size`를 지원합니다. 캠페인 대시보드는 후원 주문 수·결제 완료·전달 완료·미전달 수를 캠페인 단위로 집계합니다.
주문의 `deliveryStatus`는 살아 있는 이용권의 마지막 전달 기록 기준입니다. 모두 전달 완료면 `SENT`, 하나라도 실패면 `FAILED`, 그 밖에는 `PENDING`이며 같은 값으로 필터합니다.
기존 주문 응답 필드를 유지하고 `tumblbug`에 요금제·후원일시·상품·금액·후원번호 등을, `tickets`에 발급된 티켓 목록과 전달 상태를 추가합니다. 대시보드는 관리자 전용 `GET /admin/funding/tickets/{ticketId}/code`를 코드 전체 보기·복사 시 호출합니다. 코드 조회는 감사 로그에 기록되고 응답은 캐시되지 않습니다.
코드 암호화를 위해 `TICKET_CODE_ENCRYPTION_KEY`에 Base64 인코딩한 32바이트 키를 설정해야 합니다. 기존 코드 행은 해시만 저장되어 있어 코드 원문을 복구할 수 없습니다. 미등록 기존 코드는 재발급 후 새 코드 조회가 가능합니다.
이용권 검색은 `keyword`, `capacity`, `status`, `registeredFrom`, `registeredTo`, `page`, `size`를 지원합니다.
이용권 검색 응답의 연락처·코드를 마스킹하며 전체 코드 검색은 해시로 비교합니다.
끝 4자리 검색은 통합 이후 발급·재발급한 코드에서 지원합니다. 기존 해시로 접미사를 복원할 수는 없습니다.

클래스는 기존 `class_tickets`와 기존 이용권 확인 로직을 계속 사용합니다.
스테이징된 `FundingTicketAccess`, `FundingTicketPolicy`는 계약 파일로만 유지합니다.
현재 호출자가 없는 별도 정책 구현은 제공하지 않습니다.

## 추가 스키마

`V20261021_02__tumblbug_import_extensions.sql`과 `V20261025_01__funding_plan_and_ticket_code_vault.sql`을 기존 클래스 스키마 이후 적용합니다.
`funding_campaigns`, `tumblbug_import_records`, `funding_admin_audit_logs`, 코드 접미사,
전달 채널 길이 확장, 요금제, 암호화 코드 보관, 주문 수량당 복수 코드 제약 변경을 포함합니다. 별도 Funding 주문·이용권·코드·전달 테이블은 생성하지 않습니다.
이 저장소에는 Flyway 의존성이 없으므로 기존 DB 반영 절차에서 SQL을 적용해야 합니다.
4 changes: 3 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ dependencies {

// JPA
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// Tumblbug supporter and digital-gift XLSX processing
implementation 'org.apache.poi:poi-ooxml:5.4.1'

// Security
implementation 'org.springframework.boot:spring-boot-starter-security'
Expand Down Expand Up @@ -90,4 +92,4 @@ dependencies {

tasks.named('test') {
useJUnitPlatform()
}
}
2 changes: 2 additions & 0 deletions docs/api-specs/battle-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@
- `page` (기본값: `1`)
- `size` (기본값: `10`)
- `status` (선택)
- 항목(`BattleSimpleResponse`): `battleId`, `title`, `thumbnailUrl`, `status`, `publishAt`, `createdAt`, `difficulty`
- `difficulty`: 대상 수준 (`BEGINNER` 초급 / `INTERMEDIATE` 중급 / `ADVANCED` 고급). 새로 만든 배틀은 초급으로 저장되고, [클래스 설정 수정](./class-api.md#91-배틀-클래스-설정-수정)으로 바꾼다.

### 2.4 배틀 상세
- `GET /api/v1/admin/battles/{battleId}`
Expand Down
Loading
Loading