Skip to content

Latest commit

ย 

History

History
85 lines (71 loc) ยท 6.87 KB

FUNDING_API.md

File metadata and controls

85 lines (71 loc) ยท 6.87 KB

ํŽ€๋”ฉ 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์ด๋ฉฐ ์ฝ”๋“œ๋„ ์ˆ˜๋Ÿ‰๋งŒํผ ๋ฐœ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.

{
  "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๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์บ ํŽ˜์ธ ๋Œ€์‹œ๋ณด๋“œ๋Š” ํ›„์› ์ฃผ๋ฌธ ์ˆ˜ยท๊ฒฐ์ œ ์™„๋ฃŒยท์ „๋‹ฌ ์™„๋ฃŒยท๋ฏธ์ „๋‹ฌ ์ˆ˜๋ฅผ ์บ ํŽ˜์ธ ๋‹จ์œ„๋กœ ์ง‘๊ณ„ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด ์ฃผ๋ฌธ ์‘๋‹ต ํ•„๋“œ๋ฅผ ์œ ์ง€ํ•˜๊ณ  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์„ ์ ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.