Skip to content

Latest commit

ย 

History

History
868 lines (660 loc) ยท 62.4 KB

BACKEND_ARCHITECTURE.md

File metadata and controls

868 lines (660 loc) ยท 62.4 KB

ํ”ฝ์ผ€ ํด๋ž˜์Šค ๊ธฐ๋Šฅ ๋ฐฑ์—”๋“œ ์•„ํ‚คํ…์ฒ˜ (Funding ๊ตฌํ˜„ ๋ฒ”์œ„)

2026-10-21 origin/dev ํ†ตํ•ฉ ์•ˆ๋‚ด: ํ˜„์žฌ APIยท์Šคํ‚ค๋งˆยท๋ฐœ๊ธ‰ ์ •์ฑ…์€ FUNDING_API.md๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜ ๋ณธ๋ฌธ์€ ๊ธฐ์กด PRD ๋ถ„์„๊ณผ ์ตœ์ดˆ ์„ค๊ณ„๋ฅผ ๋ณด์กดํ•œ ์ž๋ฃŒ์ด๋ฉฐ, [๊ตฌํ˜„ ์™„๋ฃŒ] ๋“ฑ ๋‹น์‹œ ํ‘œ๊ธฐ๊ฐ€ ํ˜„์žฌ ์ฝ”๋“œ์™€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ณตํ†ต ์ฃผ๋ฌธยท์ด์šฉ๊ถŒยท๋ฐœ๊ธ‰ยท๋“ฑ๋กยทํ™˜๋ถˆ์€ ์ตœ์‹  domain.ticket/domain.admin์œผ๋กœ ํ†ตํ•ฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด /tickets/me, /ticket-codes/*, ๋ณ„๋„ Funding ์ด์šฉ๊ถŒ ํ…Œ์ด๋ธ”๊ณผ V20261015_01 ์„ค๊ณ„๋Š” ๋Œ€์ฒด๋˜์—ˆ์Šต๋‹ˆ๋‹ค. FundingTicketAccess, FundingTicketPolicy๋Š” ์œ ์ง€ํ•˜๋ฉฐ ๊ธฐ์กด ํด๋ž˜์Šค ๊ตฌํ˜„์€ ClassTicket์„ ๊ณ„์† ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค.

๋ถ„์„ ๊ธฐ์ค€: ํ”ฝ์ผ€ ํด๋ž˜์Šค ๊ธฐ๋Šฅ PRD v1.2(37์ชฝ), 2026-10-14 ํ˜„์žฌ UI ํด๋”์˜ PNG 12์žฅ, ํ˜„์žฌ Server ์†Œ์Šค
๊ฒฐ๊ณผ๋ฌผ: ํ™”๋ฉด๊ณผ ์š”๊ตฌ์‚ฌํ•ญ์— ๋Œ€์‘ํ•˜๋Š” Spring Boot ๋ฐฑ์—”๋“œ ์„ค๊ณ„ ๋ฐ ํ˜„์žฌ API ๊ตฌํ˜„ ์—ฌ๋ถ€
ํ‘œ๊ธฐ: [์กด์žฌ] ํ˜„์žฌ ์ฝ”๋“œ์— ๊ฒฝ๋กœ/๊ธฐ๋Šฅ ํ™•์ธ, [๋ถ€๋ถ„ ์กด์žฌ] ์ผ๋ฐ˜ ์ฝ˜ํ…์ธ  ๊ธฐ๋Šฅ์€ ์žˆ์œผ๋‚˜ ํด๋ž˜์Šค ๋ฒ”์œ„ ๊ธฐ๋Šฅ์€ ์—†์Œ, [์‹ ๊ทœ ์ œ์•ˆ] ํ˜„์žฌ ์ฝ”๋“œ์—์„œ ํ™•์ธ๋˜์ง€ ์•Š์Œ
์š”๊ตฌ ์ƒํƒœ: ํ™•์ •์€ PRD์˜ ํ™•์ • ์š”๊ตฌ, ๊ตฌํ˜„ ๊ธฐ๋ณธ์•ˆ์€ PRD๊ฐ€ ์ œ์•ˆํ•œ ์ •์ฑ…, ํ™•์ธ ํ•„์š”๋Š” ์ถœ์‹œ ์ „ ํ•ฉ์˜ ํ•ญ๋ชฉ


0. ์ „์ฒด ์‹œ์Šคํ…œ ์š”์•ฝ

์ „์ฒด ํ๋ฆ„

Mobile App
  โ”œโ”€ ๊ธฐ์กด ๋กœ๊ทธ์ธ/JWT
  โ””โ”€ ์ด์šฉ๊ถŒ ์ฝ”๋“œ ๋“ฑ๋ก ๋ฐ ์ด์šฉ๊ถŒ ์ƒํƒœ ํ™•์ธ (์ด๋ฒˆ ๊ตฌํ˜„ ๋ฒ”์œ„)
       โ†“
User REST API (/api/v1/**)
       โ†“
Controller โ†’ Service โ†’ Repository โ†’ PostgreSQL

Admin Dashboard (ํ˜„์žฌ ๋ณ„๋„ Next.js ์•ฑ)
  โ”œโ”€ ํŽ€๋”ฉ ๊ตฌ๋งค์žยท์ด์šฉ๊ถŒ ์ฝ”๋“œ ์šด์˜
  โ””โ”€ ํด๋ž˜์Šคยท๋ฉค๋ฒ„ยท๊ฒฐ๊ณผยท๋ณ€๊ฒฝ ์ด๋ ฅ ์กฐํšŒ/๋‚ด๋ณด๋‚ด๊ธฐ (์ด๋ฒˆ ๊ตฌํ˜„์€ ๋ณ„๋„ Classroom ๋ฒ”์œ„)
       โ†“
Admin REST API (/api/v1/admin/**, ROLE_ADMIN)
       โ†“
Admin Controller โ†’ ๋„๋ฉ”์ธ Service โ†’ Repository โ†’ PostgreSQL

Funding Domain
  โ”œโ”€ ๊ตฌ๋งค์ž/์ฃผ๋ฌธ ๋“ฑ๋กยท๊ฒฐ์ œ ํ™•์ธ
  โ”œโ”€ ์ด์šฉ๊ถŒ/๋“ฑ๋ก ์ฝ”๋“œ ๋ฐœ๊ธ‰ยท์ „๋‹ฌยท๋“ฑ๋ก
  โ””โ”€ Classroom ์ƒ์„ฑ ์‹œ ์ด์šฉ๊ถŒ ์œ ํšจ์„ฑ ์กฐํšŒ ๊ณ„์•ฝ ์ œ๊ณต

Classroom Domain (์ตœ์†Œ ์—ฐ๋™๋งŒ)
  โ””โ”€ ํด๋ž˜์Šค ๋‹ด๋‹น์ž๊ฐ€ ์†Œ์œ ๊ถŒ์„ ์œ ์ง€ํ•˜๋ฉฐ ticket ์ฐธ์กฐ์™€ funding ์œ ํšจ์„ฑ ํ™•์ธ๋งŒ ์—ฐ๊ฒฐ

ํ•ต์‹ฌ ๋„๋ฉ”์ธ

๋„๋ฉ”์ธ ์—ญํ•  ํ˜„์žฌ ์ƒํƒœ
User/Auth ๋กœ๊ทธ์ธํ•œ ์ด์šฉ๊ถŒ ์†Œ์œ ์žยท์šด์˜์ž ๊ณ„์ • ๋ฐ JWT ๊ธฐ์กด ๊ตฌํ˜„
Funding ํŽ€๋”ฉ ์ฃผ๋ฌธ, ํด๋ž˜์Šค ์ด์šฉ๊ถŒ, ๋“ฑ๋ก ์ฝ”๋“œ, ์ „๋‹ฌ ์ƒํƒœ ์ด๋ฒˆ ๊ตฌํ˜„ ๋Œ€์ƒ
Classroom ์ด์šฉ๊ถŒ ์—ฐ๊ฒฐ๊ณผ ์ƒ์„ฑ ์‹œ ์œ ํšจ์„ฑ ํ™•์ธ๋งŒ ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž ์†Œ์œ , ์ตœ์†Œ ์—ฐ๋™๋งŒ
Participation ํˆฌํ‘œยท๋…ผ์Ÿยท๋Œ“๊ธ€ยท์™„๋ฃŒ ์ƒํƒœ ์ด๋ฒˆ ๋ฒ”์œ„ ์ œ์™ธ
AI AI ์ฃผ์ œยท๋…ผ์Ÿยท๋ฆฌํฌํŠธ ๊ธฐ๋Šฅ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์Œ
Admin Operations Funding ๊ตฌ๋งค์žยท์ฝ”๋“œ ์šด์˜ ๊ธฐ์กด ์ผ๋ฐ˜ ๊ด€๋ฆฌ์ž API ์ผ๋ถ€๋งŒ ์กด์žฌ; ํด๋ž˜์Šค ์šด์˜์€ ๋ณ„๋„ ๋ฒ”์œ„

ํ˜„์žฌ ๊ณตํ†ต ๊ธฐ๋ฐ˜์—๋Š” BaseEntity, ApiResponse, PageResponse, GlobalExceptionHandler, PostgreSQL, JWT ์ธ์ฆ๊ณผ ADMIN ๊ถŒํ•œ ๊ฒฝ๋กœ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ด€๋ฆฌ์ž ํ™”๋ฉด์€ ๋ณ„๋„ Next.js ์•ฑ์œผ๋กœ ์ด๊ด€๋œ ๊ฒƒ์œผ๋กœ ์†Œ์Šค ์ฃผ์„์—์„œ ํ™•์ธ๋ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ UserRole์—๋Š” ADMIN์ด ์žˆ๊ณ  SecurityConfig๊ฐ€ /api/v1/admin/**๋ฅผ ADMIN ์ „์šฉ์œผ๋กœ ๋ณดํ˜ธํ•ฉ๋‹ˆ๋‹ค.

์ผ๋ฐ˜ ๋ฐฐํ‹€ยทํˆฌํ‘œยท๊ด€์ ยท๋Œ“๊ธ€ API๋Š” ๊ธฐ์กด ์ž์‚ฐ์œผ๋กœ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฒˆ Funding ๊ตฌํ˜„์€ ์ด๋ฅผ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ํด๋ž˜์Šค ํ™œ๋™ ๋ฐ์ดํ„ฐ๋กœ ํ™•์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ธ์ฆ๊ณผ ๊ณ„์ • ๊ฒฝ๊ณ„

  • Funding ์‚ฌ์šฉ์ž: ๊ธฐ์กด Bearer Access Token์œผ๋กœ ์ด์šฉ๊ถŒ ์กฐํšŒยท๋“ฑ๋ก์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • Funding ๊ด€๋ฆฌ์ž: ๊ธฐ์กด ADMIN ๊ถŒํ•œ์œผ๋กœ ๊ตฌ๋งค์ž/์ฃผ๋ฌธ ๋“ฑ๋ก๊ณผ ์ฝ”๋“œ ๋ฐœ๊ธ‰ยท์ „๋‹ฌ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ํด๋ž˜์Šค ๊ฒŒ์ŠคํŠธ/๋ฉค๋ฒ„ ์ธ์ฆ ๋ฐ ํด๋ž˜์Šค ์šด์˜์ž ๊ถŒํ•œ์€ ๋ณ„๋„ Classroom ๊ตฌํ˜„ ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค. ์ด๋ฒˆ์—๋Š” ํ•ด๋‹น ์ธ์ฆ ๊ตฌ์กฐ๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ํ…€๋ธ”๋ฒ… ๊ฒฐ์ œ๋Š” ์•ฑ์—์„œ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŽ€๋”ฉ ๊ฒฐ์ œ ํ™•์ธ๊ณผ ๋ฆฌ์›Œ๋“œ ์ฝ”๋“œ๋Š” ๊ด€๋ฆฌ์ž ์šด์˜ ํ๋ฆ„์œผ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

1. Spring Boot ํŒจํ‚ค์ง€ ๊ตฌ์กฐ

ํ˜„์žฌ ํ”„๋กœ์ ํŠธ์˜ domain๋ณ„ ํŒจํ‚ค์ง€ ๊ตฌ์กฐ์™€ Controller / Service / Repository / Entity / DTO ๋ถ„๋ฆฌ๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์ด๋ฒˆ ๋ฌธ์„œ์˜ ๊ตฌํ˜„ ๋ฒ”์œ„๋Š” Funding ๋„๋ฉ”์ธ๊ณผ Classroom ์ตœ์†Œ ์—ฐ๋™ ๊ณ„์•ฝ์ž…๋‹ˆ๋‹ค.

ํŽ€๋”ฉ ์ฃผ๋ฌธ์—์„œ ํด๋ž˜์Šค ์ด์šฉ๊ถŒ(Ticket)๊ณผ ๋“ฑ๋ก ์ฝ”๋“œ(TicketCode)๋ฅผ ๋ฐœ๊ธ‰ํ•˜๋ฏ€๋กœ ์ฃผ ๋„๋ฉ”์ธ ํŒจํ‚ค์ง€๋Š” domain.funding๋กœ ๋‘ก๋‹ˆ๋‹ค. ํด๋ž˜์Šค ์ชฝ์—๋Š” Funding ์—ฐ๋™ ๊ณ„์•ฝ๋งŒ domain.classroom์— ๋‘ก๋‹ˆ๋‹ค. API์™€ DB๋„ /tickets, /ticket-codes, funding_tickets, funding_ticket_codes๋กœ ๋ช…์นญ์„ ๋งž์ถฅ๋‹ˆ๋‹ค.

domain/
 โ”œโ”€ funding/                    # ์ด๋ฒˆ ๊ตฌํ˜„ ๋Œ€์ƒ: ์ฃผ๋ฌธ, ์ด์šฉ๊ถŒ, ์ฝ”๋“œ, ์ „๋‹ฌ ์ด๋ ฅ
 โ”‚   โ”œโ”€ controller/
 โ”‚   โ”œโ”€ service/
 โ”‚   โ”œโ”€ repository/
 โ”‚   โ”œโ”€ entity/
 โ”‚   โ”œโ”€ dto/request/
 โ”‚   โ”œโ”€ dto/response/
 โ”‚   โ””โ”€ enums/
 โ”‚
 โ”œโ”€ classroom/                  # ๋ณ„๋„ ๊ฐœ๋ฐœ ์˜์—ญ; Funding ์œ ํšจ์„ฑ ๊ณ„์•ฝ๋งŒ ์ถ”๊ฐ€
 โ”‚   โ”œโ”€ FundingTicketPolicy.java
 โ”‚   โ””โ”€ FundingTicketAccess.java
 โ”‚
 โ”œโ”€ user/                        # ๊ธฐ์กด User, ํ”„๋กœํ•„, ์‚ฌ์šฉ์ž ๊ธฐ๋ก
 โ”œโ”€ oauth/                       # ๊ธฐ์กด ๋กœ๊ทธ์ธ/JWT
 โ”œโ”€ battle/                      # ๊ธฐ์กด ๋ฐฐํ‹€ ์ฝ˜ํ…์ธ , ํด๋ž˜์Šค์—์„œ๋Š” ์ฝ๊ธฐ ์ „์šฉ ์ฐธ์กฐ
 โ”œโ”€ vote/                        # ๊ธฐ์กด ์ผ๋ฐ˜ ๋ฐฐํ‹€ ํˆฌํ‘œ, ํด๋ž˜์Šค ํˆฌํ‘œ๋Š” ๋ถ„๋ฆฌ
 โ”œโ”€ perspective/                 # ๊ธฐ์กด ์ผ๋ฐ˜ ๊ด€์ /๋Œ“๊ธ€, ํด๋ž˜์Šค ๋Œ“๊ธ€์€ ๋ถ„๋ฆฌ
 โ””โ”€ admin/                       # ๊ธฐ์กด ์‚ฌ์šฉ์žยท๋Œ€์‹œ๋ณด๋“œ ๋“ฑ ์ผ๋ฐ˜ ๊ด€๋ฆฌ์ž API

global/
 โ”œโ”€ common/BaseEntity.java        # ๊ธฐ์กด ๊ณตํ†ต ํ•„๋“œ ์‚ฌ์šฉ
 โ”œโ”€ common/response/              # ๊ธฐ์กด ApiResponse, PageResponse ์‚ฌ์šฉ
 โ”œโ”€ common/exception/              # ๊ณตํ†ต ์˜ˆ์™ธ ๊ตฌ์กฐ ์žฌ์‚ฌ์šฉ
 โ””โ”€ config/SecurityConfig.java     # /api/v1/admin/** ๊ธฐ์กด ADMIN ๋ณดํ˜ธ ๊ทœ์น™ ์‚ฌ์šฉ

๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž์™€์˜ ์ฝ”๋“œ ์†Œ์œ  ๊ฒฝ๊ณ„

  • Funding ๊ตฌํ˜„์€ domain/funding/**์˜ ์ฃผ๋ฌธยท์ด์šฉ๊ถŒยท๋“ฑ๋ก ์ฝ”๋“œ ํŒŒ์ผ์„ ์†Œ์œ ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด ์‚ฌ์šฉ์ž/auth์™€ battle ๋“ฑ ํƒ€ ๋„๋ฉ”์ธ ํŒŒ์ผ์€ ํ•„์š”ํ•œ ๋ณ€๊ฒฝ ์—†์ด ์กฐํšŒ/์ฐธ์กฐ๋งŒ ํ•ฉ๋‹ˆ๋‹ค.
  • Classroom ๋‹ด๋‹น์ž๋Š” ํด๋ž˜์Šคยท๋ฉค๋ฒ„์‹ญยทํ™œ๋™ยท๊ด€๋ฆฌ์ž ํ™”๋ฉด์„ ์†Œ์œ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฒˆ ๋ณ€๊ฒฝ์€ domain/classroom์— Funding ์ •์ฑ… interface์™€ ๋ฐ˜ํ™˜ record๋งŒ ๋‘ก๋‹ˆ๋‹ค. Classroom Entity/Controller/Repository๋Š” ๊ตฌํ˜„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • Classroom์˜ ์ตœ์†Œ ์—ฐ๋™์€ Classroom.ticketId ์ฐธ์กฐ(๊ธฐ์กด ํ•„๋“œ๊ฐ€ ์—†๋‹ค๋ฉด FK๋งŒ ์ถ”๊ฐ€)์™€ ํด๋ž˜์Šค ์ƒ์„ฑ ์‹œ Funding์˜ FundingTicketPolicy.requireUsableBy(userId, ticketId) ํ˜ธ์ถœ์ž…๋‹ˆ๋‹ค. Funding์€ ์†Œ์œ ์žยทACTIVE ์ƒํƒœยท๋งŒ๋ฃŒ ์‹œ๊ฐ์„ ๊ฒ€์ฆํ•˜๊ณ  capacity, expiresAt์„ ํฌํ•จํ•œ ์–‡์€ FundingTicketAccess ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ Spring ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด๋ถ€ ์„œ๋น„์Šค ๊ณ„์•ฝ์ด๋ฉฐ ๋ณ„๋„ HTTP API๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • AI ๋„๋ฉ”์ธ/๊ธฐ๋Šฅ์€ ์ด๋ฒˆ ๊ตฌํ˜„์—์„œ ์ œ์™ธํ•ฉ๋‹ˆ๋‹ค. AI Controller, Entity, Repository, Client, Worker, API๋ฅผ ๋งŒ๋“ค๊ฑฐ๋‚˜ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๊ณตํ†ต ErrorCode ์ถ”๊ฐ€๊ฐ€ ํ•„์š”ํ•˜๋ฉด Funding ์ ‘๋‘์–ด ์˜ค๋ฅ˜๋งŒ ํ†ตํ•ฉ ๋‹ด๋‹น์ž๊ฐ€ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. SecurityConfig์˜ /api/v1/admin/** ADMIN ๊ทœ์น™์€ ๊ธฐ์กด ๊ฒƒ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฒˆ ์ฝ”๋“œ ๋ฐ˜์˜ ๋ฒ”์œ„

  • funding: FundingCampaign, FundingOrder, Ticket, TicketCode, DeliveryAttempt, AdminAuditLog Entity์™€ Repository, Service/ServiceImpl, ์„ค๋ช…์ด ํฌํ•จ๋œ Enum, record DTO, ์‚ฌ์šฉ์ž/๊ด€๋ฆฌ์ž Controller๋ฅผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.
  • classroom: Funding ticket ๊ฒ€์‚ฌ interface์™€ FundingTicketAccess record๋งŒ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ํด๋ž˜์Šค ๊ธฐ๋Šฅ Entity/API๋Š” ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž ์ž‘์—… ์˜์—ญ์œผ๋กœ ๋‚จ๊น๋‹ˆ๋‹ค.
  • ๊ตฌ๋งค์ž ์—ฐ๋ฝ์ฒ˜๋Š” FUNDING_CONTACT_ENCRYPTION_KEY ํ™˜๊ฒฝ ๋ณ€์ˆ˜(Base64 ์ธ์ฝ”๋”ฉ 32๋ฐ”์ดํŠธ)๋กœ AES-256-GCM ์•”ํ˜ธํ™”ํ•ฉ๋‹ˆ๋‹ค. ๊ด€๋ฆฌ์ž ๋ชฉ๋ก์€ ๋งˆ์Šคํ‚น ์—ฐ๋ฝ์ฒ˜๋งŒ ๋ฐ˜ํ™˜ํ•˜๊ณ  ๊ฒ€์ƒ‰์€ ์—ฐ๋ฝ์ฒ˜ ์ „์ฒด ๊ฐ’์˜ HMAC ์ผ์น˜ ๊ฒ€์ƒ‰์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.
  • Funding ํ…Œ์ด๋ธ” DDL์€ src/main/resources/db/migration/V20261015_01__create_fundings_domain.sql์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ์˜ ๊ธฐ์กด DB ๋ฐ˜์˜ ์ ˆ์ฐจ์—์„œ ์ ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์šด์˜์ž๋Š” ํ…€๋ธ”๋ฒ… ๋ช…๋‹จ Excel์„ ์ง์ ‘ ๋‚ด๋ ค๋ฐ›๊ณ  ์„œ๋ฒ„์— ์—…๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„๋Š” ์„ ํƒ ์‹œํŠธ์—์„œ ํ™”๋ฉด์˜ 9๊ฐœ ์—ด์„ ์ž๋™ ํŒ๋ณ„ํ•˜๊ณ  ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋กœ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ํ™•์ • ์‹œ ์œ ํšจํ•œ ํ›„์› ํ–‰ ์ „์ฒด๋ฅผ ์ €์žฅํ•˜๊ณ  ๊ฒฐ์ œ ์™„๋ฃŒ ํ–‰์—๋งŒ ์ฝ”๋“œ๋ฅผ ๋ฐœ๊ธ‰ํ•ด ํ…€๋ธ”๋ฒ… ์—…๋กœ๋“œ์šฉ Excel์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ํ…€๋ธ”๋ฒ… ์—…๋กœ๋“œ์™€ ์™„๋ฃŒ ํ™•์ธ์€ ๊ด€๋ฆฌ์ž๊ฐ€ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์ด ๊ฒฝ๊ณ„์—์„œ๋Š” Funding์ด ๊ตฌํ˜„ ๋Œ€์ƒ์ด๊ณ  Classroom์€ ์ด์šฉ๊ถŒ ์ฐธ์กฐ์™€ ์ƒ์„ฑ ์ „ ๊ฒ€์ฆ๋งŒ ์—ฐ๋™ํ•ฉ๋‹ˆ๋‹ค. Classroom ํŒŒ์ผ์„ ์ˆ˜์ •ํ•ด์•ผ ํ•œ๋‹ค๋ฉด ticketId์™€ ๋‹จ์ผ ์œ ํšจ์„ฑ ํ˜ธ์ถœ๋งŒ ํด๋ž˜์Šค ๋‹ด๋‹น์ž๊ฐ€ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. AI ๊ธฐ๋Šฅ์€ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


2. ํ™”๋ฉด๋ณ„ ์„ค๊ณ„

UI ํด๋”์—๋Š” ์ด 12์žฅ์˜ ํ™”๋ฉด ์ด๋ฏธ์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์•ฑ ํ™”๋ฉด์€ 8๊ฐœ ์ด๋ฏธ์ง€/์ƒํƒœ ๋ฌถ์Œ, ๊ด€๋ฆฌ์ž ํ™”๋ฉด์€ 4๊ฐœ ํ™”๋ฉด์œผ๋กœ ๋ถ„์„ํ–ˆ์Šต๋‹ˆ๋‹ค. PRD์˜ S01~S22 ํด๋ž˜์Šค ์ฐธ์—ฌยท์ƒ์„ฑ ํ™”๋ฉด์€ ์ด ํด๋”์— ์‹œ๊ฐ ์‹œ์•ˆ์ด ์—†์œผ๋ฏ€๋กœ, ์•„๋ž˜์—์„œ PRD ์ „์šฉ ํ™”๋ฉด ํ๋ฆ„์œผ๋กœ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค.

์ด ์ ˆ์€ ์ „์ฒด ์ž๋ฃŒ์—์„œ ํ™•์ธํ•œ ํ™”๋ฉด๊ณผ ๋ฐ์ดํ„ฐ ์š”๊ตฌ๋ฅผ ๋ณด์กดํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์ด๋ฒˆ ๊ตฌํ˜„์€ Funding ํ™”๋ฉด/๊ธฐ๋Šฅ์— ํ•œ์ •ํ•ฉ๋‹ˆ๋‹ค. Classroom ํ™”๋ฉด ์ค‘ ์ด์šฉ๊ถŒ ์œ ํšจ์„ฑ ์—ฐ๊ฒฐ ์™ธ ๊ธฐ๋Šฅ๊ณผ AI ๊ด€๋ จ ํ™”๋ฉดยท๊ธฐ๋Šฅ์€ ๊ฐ๊ฐ ๋‹ค๋ฅธ ๊ฐœ๋ฐœ ๋ฒ”์œ„์ด๋ฉฐ, ์—ฌ๊ธฐ์„œ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ์•ฑ

1) ๋งˆ์ดํŽ˜์ด์ง€์˜ ํด๋ž˜์Šค ์ด์šฉ๊ถŒ ์ง„์ž… ํ™”๋ฉด

์ด๋ฏธ์ง€: 2026-10-14 232458

  • ๋ชฉ์ : ์‚ฌ์šฉ์ž๊ฐ€ ํด๋ž˜์Šค ์ด์šฉ๊ถŒ ๋ฉ”๋‰ด๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.
  • ์•ก์…˜: ํด๋ž˜์Šค ์ด์šฉ๊ถŒ ๋ฉ”๋‰ด ํƒญ.
  • ๋ฐ์ดํ„ฐ: ๊ธฐ์กด ์‚ฌ์šฉ์ž ํ”„๋กœํ•„์€ ๊ธฐ์กด ๋งˆ์ดํŽ˜์ด์ง€ API์—์„œ ๋ฐ›๊ณ , ์ด์šฉ๊ถŒ ์กด์žฌ/์ƒํƒœ ํ‘œ์‹œ๋Š” ๋ณ„๋„ ์ด์šฉ๊ถŒ API์—์„œ ๋ฐ›์Šต๋‹ˆ๋‹ค.
  • ํ”„๋ก ํŠธ ์ฒ˜๋ฆฌ: ๋ฉ”๋‰ด๋ช…ยท์•„์ด์ฝ˜ยท๊ณ ์ • ๋ฌธ๊ตฌ.
  • ๋ฐฑ์—”๋“œ ์ฒ˜๋ฆฌ: ์ด์šฉ๊ถŒ ์ƒํƒœ์™€ ํ‘œ์‹œํ•  ์ •์›ยท๊ธฐ๊ฐ„.
  • API: [์กด์žฌ] GET /api/v1/me/mypage, [๊ตฌํ˜„ ์™„๋ฃŒ] GET /api/v1/tickets/me.
  • ์ธ์ฆ: ๋กœ๊ทธ์ธ ํ•„์š”.
  • ์˜ˆ์™ธ/์ด๋™: ๋ฏธ๋ณด์œ ๋ฉด ์ฝ”๋“œ ๋“ฑ๋ก ์•ˆ๋‚ด, ๋ณด์œ ๋ฉด ์ด์šฉ๊ถŒ ์ƒ์„ธ. ๋กœ๋”ฉยท๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜๋Š” ์•ฑ ์ƒํƒœ.
  • ๋…ผ์˜: ๊ธฐ์กด mypage ์‘๋‹ต์— ์ด์šฉ๊ถŒ ํ•„๋“œ๋ฅผ ํ•ฉ์น ์ง€ ๋ณ„๋„ endpoint๋กœ ์กฐํšŒํ• ์ง€. ๋ณธ ์„ค๊ณ„๋Š” ๋ณ„๋„ endpoint๋ฅผ ๊ถŒ์žฅํ•ด User ๋„๋ฉ”์ธ ๋ณ€๊ฒฝ์„ ํ”ผํ•ฉ๋‹ˆ๋‹ค.

2) ์ด์šฉ๊ถŒ ๋“ฑ๋ก ์ฝ”๋“œ ์ž…๋ ฅ ํ™”๋ฉด

์ด๋ฏธ์ง€: 2026-10-14 232009, 232203

  • ๋ชฉ์ : ํŽ€๋”ฉ ๋ฆฌ์›Œ๋“œ๋กœ ๋ฐ›์€ ์ด์šฉ๊ถŒ ๋“ฑ๋ก ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  • ์•ก์…˜: ์ฝ”๋“œ ์ž…๋ ฅ, ์ฝ”๋“œ ํ™•์ธ, FAQ ์—ด๊ธฐ.
  • ํ‘œ์‹œ ๋ฐ์ดํ„ฐ: ์ฝ”๋“œ ์ž…๋ ฅ๊ฐ’์€ ์•ฑ ์ƒํƒœ. ์ด์šฉ๊ถŒ ์ •์›๊ณผ ๋“ฑ๋ก๊ธฐํ•œ์€ ๊ฒ€์ฆ ํ›„ ๋ฐฑ์—”๋“œ ์‘๋‹ต.
  • ํ”„๋ก ํŠธ ์ฒ˜๋ฆฌ: ๋ผ๋ฒจยท๊ณ ์ • ์•ˆ๋‚ดยท์ž…๋ ฅ ํ˜•์‹ยท๋ฒ„ํŠผ ํ™œ์„ฑ ์กฐ๊ฑด.
  • ๋ฐฑ์—”๋“œ ์ฒ˜๋ฆฌ: ์ฝ”๋“œ ์กด์žฌ/์ƒํƒœ/๋“ฑ๋ก๊ธฐํ•œ/๋‹ค๋ฅธ ์ฝ”๋“œ ์œ ํ˜• ์—ฌ๋ถ€.
  • API: [๊ตฌํ˜„ ์™„๋ฃŒ] POST /api/v1/ticket-codes/preview.
  • ์ธ์ฆ: ๋กœ๊ทธ์ธ ํ•„์š”, ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋Š” ์ฝ”๋“œ๋ฅผ ์†Œ๋น„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์˜ˆ์™ธ/์ด๋™: ์ž˜๋ชป๋œ ์ฝ”๋“œ๋ฉด ์ž…๋ ฅ์„ ๋ณด์กดํ•˜๊ณ  ์˜ค๋ฅ˜ ์•ˆ๋‚ด, ์œ ํšจํ•˜๋ฉด ๋“ฑ๋ก ํ™•์ธ ํ™”๋ฉด.
  • ๋…ผ์˜: ์ฝ”๋“œ ์ž…๋ ฅ์˜ ํ•˜์ดํ”ˆยท๊ณต๋ฐฑ ์ •๊ทœํ™” ๋ฐ ๋ณต์‚ฌ/๋ถ™์—ฌ๋„ฃ๊ธฐ ๋™์ž‘.

3) ์ด์šฉ๊ถŒ FAQ ํŽผ์นจ ํ™”๋ฉด

์ด๋ฏธ์ง€: 2026-10-14 232243

  • ๋ชฉ์ : ์ฝ”๋“œ๋ฅผ ์–ด๋””์„œ ๋ฐ›๋Š”์ง€์™€ ํด๋ž˜์Šค ์ฐธ์—ฌ ์ฝ”๋“œ์™€์˜ ์ฐจ์ด๋ฅผ ์•ˆ๋‚ดํ•ฉ๋‹ˆ๋‹ค.
  • ํ‘œ์‹œ ๋ฐ์ดํ„ฐ: โ€œํŽ€๋”ฉ ๋ฆฌ์›Œ๋“œ ์•ˆ๋‚ด์—์„œ ํ™•์ธโ€, โ€œ์ฐธ์—ฌ ์ฝ”๋“œ๋Š” ๋ชจ์ž„ ์ž…์žฅ์— ์‚ฌ์šฉํ•˜๋Š” ๋ณ„๋„ ์ฝ”๋“œโ€ ๋ฌธ๊ตฌ.
  • ํ”„๋ก ํŠธ ์ฒ˜๋ฆฌ ๊ถŒ์žฅ: FAQ ๋ฌธ๊ตฌ๋Š” ๊ณ ์ • ์•ˆ๋‚ด์ด๋ฏ€๋กœ App์—์„œ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐฑ์—”๋“œ: ๋ถˆํ•„์š”.
  • ๋…ผ์˜: ์šด์˜ ์ค‘ ํ™˜๋ถˆ/์ „๋‹ฌ ๊ฒฝ๋กœ๊ฐ€ ๋ฐ”๋€Œ๋ฉด ๋ฌธ๊ตฌ ๋ฐฐํฌ๋ฅผ ๋ˆ„๊ฐ€ ๋‹ด๋‹นํ• ์ง€ ์ •ํ•ฉ๋‹ˆ๋‹ค.

4) ์ฝ”๋“œ ํ™•์ธ ๊ฒฐ๊ณผ ๋ฐ ์˜ค๋ฅ˜ ๋ชจ๋‹ฌ

์ด๋ฏธ์ง€: 2026-10-14 232144

  • ๋ชฉ์ : ์ด๋ฏธ ๋“ฑ๋ก๋œ ์ด์šฉ๊ถŒ, ์ž˜๋ชป๋œ ์ฝ”๋“œ, ๋„คํŠธ์›Œํฌ ๋ฌธ์ œ, ๋งŒ๋ฃŒ ์ฝ”๋“œ๋ฅผ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐฑ์—”๋“œ ๊ตฌ๋ถ„: CODE_INVALID, CODE_ALREADY_CLAIMED, CODE_EXPIRED, CODE_REVOKED, NETWORK_ERROR.
  • ํ”„๋ก ํŠธ ์ฒ˜๋ฆฌ: ์˜ค๋ฅ˜ ์•„์ด์ฝ˜, ์žฌ์‹œ๋„ ๋ฒ„ํŠผ, ์ž…๋ ฅ ๋ณด์กด, ํ™•์ธ/๋’ค๋กœ๊ฐ€๊ธฐ.
  • ์ธ์ฆ: ์ฝ”๋“œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋Š” ๋กœ๊ทธ์ธ ํ•„์š”.
  • ์˜ˆ์™ธ ๋ฌธ๊ตฌ: ์ฝ”๋“œ ์˜ค๋ฅ˜๋Š” ๋‹ค์Œ ๋ฌธ๊ตฌ๋กœ ํ†ต์ผํ•ฉ๋‹ˆ๋‹ค. โ€œ์ฝ”๋“œ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์•„์š”. ์ž…๋ ฅํ•œ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ํ™•์ธํ•ด ์ฃผ์„ธ์š”.โ€
  • ์ฃผ์˜: ๋„คํŠธ์›Œํฌ ์‹คํŒจ๋Š” ์„œ๋ฒ„ ErrorCode๋กœ ๊ฐ€์žฅํ•˜์ง€ ์•Š๊ณ  ์•ฑ ๋„คํŠธ์›Œํฌ ์ƒํƒœ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

5) ์ด์šฉ๊ถŒ ๋“ฑ๋ก ํ™•์ธ ํ™”๋ฉด

์ด๋ฏธ์ง€: 2026-10-14 232220

  • ๋ชฉ์ : ์ƒํ’ˆ ์ •์›, ๊ธฐ๊ฐ„, ๋“ฑ๋ก ์‹œ ์‹œ์ž‘๋˜๋Š” ์ด์šฉ ์กฐ๊ฑด์„ ํ™•์ธํ•œ ๋’ค ์‚ฌ์šฉ์ž๊ฐ€ ๋“ฑ๋ก์„ ํ™•์ •ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐฑ์—”๋“œ ๋ฐ์ดํ„ฐ: ์ƒํ’ˆ๋ช…/์ •์›, ๋“ฑ๋ก๊ธฐํ•œ, ๋“ฑ๋ก ์ฆ‰์‹œ ์‹œ์ž‘๋  ํ™œ์„ฑํ™”ยท์ข…๋ฃŒ ์‹œ๊ฐ, ํด๋ž˜์Šค ์ƒ์„ฑ ์ œํ•œ ์—†์Œ.
  • ํ”„๋ก ํŠธ ์ฒ˜๋ฆฌ: ํ™•์ธ ๋ฌธ๊ตฌยท๋ฒ„ํŠผยท๋“ฑ๋ก ํ›„ ๊ธฐ๊ฐ„์ด ๋˜๋Œ๋ฆด ์ˆ˜ ์—†๋‹ค๋Š” ์„ค๋ช….
  • API: [๊ตฌํ˜„ ์™„๋ฃŒ] POST /api/v1/ticket-codes/claim.
  • ์ธ์ฆ: ๋กœ๊ทธ์ธ ํ•„์š”. Idempotency-Key ํ—ค๋” ๊ถŒ์žฅ.
  • ์ด๋™: ์„ฑ๊ณต ์‹œ ๋“ฑ๋ก ์™„๋ฃŒ, ์ค‘๋ณต ํƒญ์€ ์ฒซ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜.
  • PRD/UI ์ฐจ์ด: UI ์˜ˆ์‹œ๋Š” 30์ธ ์ƒํ’ˆ ํ•˜๋‚˜์ง€๋งŒ PRD๋Š” 5/15/30์ธ 3์ข…์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

6) ์ด์šฉ๊ถŒ ๋“ฑ๋ก ์™„๋ฃŒ ํ™”๋ฉด

์ด๋ฏธ์ง€: 2026-10-14 232308

  • ๋ชฉ์ : ํ™œ์„ฑํ™” ๊ฒฐ๊ณผ์™€ ๊ณตํ†ต ์ด์šฉ ์ข…๋ฃŒ์ผ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ: ์ •์›, activatedAt, expiresAt, ์ด์šฉ๊ถŒ ์ƒํƒœ.
  • ํ”„๋ก ํŠธ: โ€œ์ด์šฉ๊ถŒ์ด ๋“ฑ๋ก๋์–ด์š”โ€ ๋“ฑ ๊ณ ์ • ๋ฌธ๊ตฌ์™€ ๋ฒ„ํŠผ.
  • ๋ฐฑ์—”๋“œ: ๋‚ ์งœ ๊ณ„์‚ฐ๊ณผ ์ด์šฉ๊ถŒ ํ™œ์„ฑ ์ƒํƒœ.
  • ์ด๋™: ์ด์šฉ๊ถŒ ํ™•์ธํ•˜๊ธฐ ๋˜๋Š” ๋งˆ์ดํŽ˜์ด์ง€.
  • ์˜ˆ์™ธ: ์žฌ์š”์ฒญ ์‹œ ์ข…๋ฃŒ์ผ์„ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜๊ฑฐ๋‚˜ ์—ฐ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

7) ํด๋ž˜์Šค ์ด์šฉ๊ถŒ ํ™•์ธ ํ™”๋ฉด

์ด๋ฏธ์ง€: 2026-10-14 232329

  • ๋ชฉ์ : ํ˜„์žฌ ํ™œ์„ฑ ์ด์šฉ๊ถŒ์˜ ์ƒํ’ˆยท๊ธฐ๊ฐ„ยท์ •์›์„ ํ™•์ธํ•˜๊ณ  ์ถ”๊ฐ€ ๋“ฑ๋ก ํ๋ฆ„์„ ์—ฝ๋‹ˆ๋‹ค.
  • API: [๊ตฌํ˜„ ์™„๋ฃŒ] GET /api/v1/tickets/me.
  • ์ธ์ฆ: ๋กœ๊ทธ์ธ ํ•„์š”.
  • ํ‘œ์‹œ ๋ฐ์ดํ„ฐ: ์ƒํƒœ, ์ •์›, ์‚ฌ์šฉ ๊ฐ€๋Šฅ ๊ธฐ๊ฐ„, ํด๋ž˜์Šค ์ƒ์„ฑ ๊ฐ€๋Šฅ ์—ฌ๋ถ€.
  • PRD/UI ์ฐจ์ด: PRD์˜ ๊ธฐ๋ณธ์•ˆ์€ ํŽ€๋”ฉ ์บ ํŽ˜์ธ ๊ธฐ์ค€ 1์ธ 1๊ฐœ์ง€๋งŒ UI์—๋Š” โ€œ์ด์šฉ๊ถŒ ์ถ”๊ฐ€๋“ฑ๋กํ•˜๊ธฐโ€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ถ”๊ฐ€ ์บ ํŽ˜์ธ/๋ณต์ˆ˜ ๋ณด์œ  ์˜๋ฏธ์ธ์ง€ ์ถœ์‹œ ์ „ ํ™•์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. UI๊ฐ€ ๋ณด์œ ํ•˜์ง€ ์•Š์€ ๋“ฑ๋ก ์ฝ”๋“œ๋ฅผ ํ™•์ธํ•ด ์ฃผ๋Š”์ง€ ์—ญ์‹œ ํ˜„์žฌ ๊ณ„์•ฝ์— ์—†์Šต๋‹ˆ๋‹ค.

8) ์•ฑ ์ง„์ž… ๋ฐ ์ด์šฉ๊ถŒ ์ƒํƒœ๋ณ„ ๋ถ„๊ธฐ

์ด๋ฏธ์ง€: 2026-10-14 232458 ๋ฐ ์ด์šฉ๊ถŒ ํ™”๋ฉด 3์ข…

  • ๋ฉ”๋‰ด๋Š” ์„œ๋ฒ„ ์ƒํƒœ๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋“ฑ๋ก ์•ˆ๋‚ด/ํ™œ์„ฑ ์ด์šฉ๊ถŒ/๊ธฐ๊ฐ„ ์ข…๋ฃŒ ์ƒํƒœ๋กœ ๋ถ„๊ธฐํ•ฉ๋‹ˆ๋‹ค.
  • โ€œํ˜„์žฌ ์ด์šฉ๊ถŒ ์—†์Œโ€์€ ์„œ๋ฒ„์—์„œ NONE์œผ๋กœ ๋‚ด๋ ค์ฃผ๋ฉฐ, Loading/Network Error๋Š” ์•ฑ์ด ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • UI์— ๋ฏธ๋“ฑ๋กยท์ด์šฉ ์ค‘ยท๋“ฑ๋ก๋งŒ๋ฃŒยท์ด์šฉ์ข…๋ฃŒ๊ฐ€ ํ‘œ์‹œ๋˜์ง€๋งŒ, PRD์˜ ๊ตฌ๋งค์ž ์ •๋ณด๋Š” ์ฝ”๋“œ ๋“ฑ๋ก ์ „ ์•ฑ ๊ณ„์ •๊ณผ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋“ฑ๋ก ์ „ ์ด์šฉ๊ถŒ ์ƒํƒœ๋ฅผ ํŠน์ • ์‚ฌ์šฉ์ž์˜ P03 ํ™”๋ฉด์—์„œ ๋ณด์—ฌ์ฃผ๋Š” ๋ฐฉ๋ฒ•์€ ์ •์ฑ… ํ™•์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๊ด€๋ฆฌ์ž ๋Œ€์‹œ๋ณด๋“œ

ํ˜„์žฌ ๊ด€๋ฆฌ์ž UI๋Š” ๋ณ„๋„ Next.js ์•ฑ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ์ฒจ๋ถ€ ์ด๋ฏธ์ง€์—์„œ ํ™•์ธ๋œ ํด๋ž˜์Šค ๊ด€๋ฆฌ ํ™”๋ฉด 4์ข…์ž…๋‹ˆ๋‹ค.

1) ํด๋ž˜์Šค ๊ด€๋ฆฌ ๋ชฉ๋ก

์ด๋ฏธ์ง€: 2026-10-14 233753

  • ๋ชฉ์ : ์ „์ฒด ํด๋ž˜์Šค์™€ ์ •์›ยท์ธ์›ยท์„ ํƒ ์ฝ˜ํ…์ธ ยท์šด์˜ ์ƒํƒœ๋ฅผ ๊ฒ€์ƒ‰ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ: ์ „์ฒด/์ง„ํ–‰ ์ค‘/๋ฉค๋ฒ„ ์ˆ˜/๋งŒ๋ฃŒ ์ž„๋ฐ• ์ง‘๊ณ„ ์นด๋“œ, ํด๋ž˜์Šค๋ช…ยท์ƒ์„ฑ์žยท์ด์šฉ๊ถŒยท์ธ์›ยท์„ ํƒ ์ฝ˜ํ…์ธ ยท์ƒํƒœ.
  • ๊ฒ€์ƒ‰/ํ•„ํ„ฐ: ํด๋ž˜์Šค๋ช… ๋˜๋Š” ์ƒ์„ฑ์ž, ์ƒํƒœ, ์ด์šฉ๊ถŒ ์ •์›, ๋ฐฐํ‹€ ์œ ํ˜•.
  • ์ •๋ ฌ/ํŽ˜์ด์ง€: ํŽ˜์ด์ง€ ๋ฒˆํ˜ธ UI ํ™•์ธ, ์ •๋ ฌ ์กฐ๊ฑด์€ ์‹œ์•ˆ์— ์—†์Œ. ์„œ๋ฒ„ pagination์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
  • ์•ก์…˜: ์กฐํšŒ, CSV ๋‚ด๋ณด๋‚ด๊ธฐ, ํ–‰์„ ๋ˆŒ๋Ÿฌ ์ƒ์„ธ.
  • API: [๋ณ„๋„ Classroom ๊ตฌํ˜„ ๋ฒ”์œ„] GET /api/v1/admin/classes, GET /api/v1/admin/classes/export.csv. ์ด๋ฒˆ Funding ๊ตฌํ˜„์—์„œ๋Š” ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๊ถŒํ•œ: ADMIN.
  • ๋…ผ์˜: ํ•„ํ„ฐ ๋ณ€๊ฒฝ ์‹œ ์„œ๋ฒ„ ์กฐํšŒ, ๊ธฐ๋ณธ ์ •๋ ฌ(createdAt desc), CSV ๋‚ด๋ณด๋‚ด๊ธฐ ์ ์šฉ ํ•„ํ„ฐ.

2) ์ด์šฉ๊ถŒยท๋“ฑ๋ก์ž ๋ชฉ๋ก

์ด๋ฏธ์ง€: 2026-10-14 233819

  • ๋ชฉ์ : ๋ฐœ๊ธ‰๋œ ์ฝ”๋“œ, ์ƒํ’ˆ ์ •์›, ๋“ฑ๋ก ์‚ฌ์šฉ์ž, ์ด์šฉ ๊ธฐ๊ฐ„, ์—ฐ๊ฒฐ ํด๋ž˜์Šค ์ˆ˜๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ: ์ „์ฒด ์ด์šฉ๊ถŒ/์ด์šฉ ์ค‘/๋ฏธ๋“ฑ๋ก/๋งŒ๋ฃŒ ์ž„๋ฐ• ์นด๋“œ, ์ฝ”๋“œ, ๊ตฌ๋งค์ž ์ •๋ณด, ์ด์šฉ๊ถŒยท๋“ฑ๋ก์ž, ๊ตฌ๋ถ„, ๊ธฐ๊ฐ„, ์ƒ์„ฑ ํด๋ž˜์Šค ์ˆ˜.
  • ๊ฒ€์ƒ‰/ํ•„ํ„ฐ: ์ฝ”๋“œยท๊ตฌ๋งค์žยท๋“ฑ๋ก์ž ํ‚ค์›Œ๋“œ, ์ƒํ’ˆ ์ •์›(5/15/30), ์ƒํƒœ, ๋“ฑ๋ก ๊ธฐ๊ฐ„.
  • ์•ก์…˜: ์ด์šฉ๊ถŒ ์ฝ”๋“œ ๋ฐœ๊ธ‰, ์กฐํšŒ, ํŽ˜์ด์ง€ ์ด๋™.
  • API: [๊ตฌํ˜„ ์™„๋ฃŒ] GET /api/v1/admin/tickets, POST /api/v1/admin/tickets/{ticketId}/codes.
  • ๊ถŒํ•œ: ADMIN.
  • ๊ฐœ์ธ์ •๋ณด: ์ด๋ฉ”์ผ ๋“ฑ์€ ๊ธฐ๋ณธ ๋งˆ์Šคํ‚น. ๋ฐœ๊ธ‰ ์™„๋ฃŒ ์งํ›„ ์ฝ”๋“œ ์›๋ฌธ์€ ์ œํ•œ๋œ ์ผํšŒ ๋…ธ์ถœ๋กœ ์ „๋‹ฌํ•˜๋Š” ์•ˆ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
  • ๋…ผ์˜: UI ํ‘œ์— ํ‘œ์‹œ๋œ ์ „์ฒด ์ฝ”๋“œ ๋…ธ์ถœ๊ณผ ์ฝ”๋“œ ์›๋ฌธ ๋น„์ €์žฅ ์›์น™ ๊ฐ„ ์กฐ์ •.

3) ํŽ€๋”ฉ ๊ตฌ๋งค์ž ๋ชฉ๋ก

์ด๋ฏธ์ง€: 2026-10-14 233945

  • ๋ชฉ์ : ์™ธ๋ถ€ ๊ตฌ๋งค์ž, ๋ฆฌ์›Œ๋“œ, ์ฝ”๋“œ ๋ฐœ๊ธ‰ยท์ „๋‹ฌยท์•ฑ ๋“ฑ๋ก ์ƒํƒœ๋ฅผ ์šด์˜ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ: ๊ตฌ๋งค์ž ์ˆ˜/์ฝ”๋“œ ๋ฐœ๊ธ‰/์ „๋‹ฌ ์™„๋ฃŒ/๋ฏธ์ „๋‹ฌ, ๊ตฌ๋งค์ž, ์—ฐ๋ฝ์ฒ˜, ํŽ€๋”ฉ ์ฃผ๋ฌธ, ๊ตฌ๋งค ์ƒํ’ˆ, ์ „๋‹ฌ ์ƒํƒœ, ๋“ฑ๋ก ์ƒํƒœ.
  • ๊ฒ€์ƒ‰/ํ•„ํ„ฐ: ์ด๋ฆ„ยท์ด๋ฉ”์ผยท์ „ํ™”๋ฒˆํ˜ธ, ์ƒํ’ˆ ์ •์›, ์ „๋‹ฌ ์ƒํƒœ, ๋“ฑ๋ก ์ƒํƒœ.
  • ์•ก์…˜: ๊ตฌ๋งค์ž ๋“ฑ๋ก, ์กฐํšŒ, ์ „๋‹ฌ ๊ฒฐ๊ณผ ๊ฐฑ์‹ .
  • API: [๊ตฌํ˜„ ์™„๋ฃŒ] GET /api/v1/admin/funding-orders, POST /api/v1/admin/funding-orders, ํ…€๋ธ”๋ฒ… ๋ช…๋‹จ ์‹œํŠธ ํ™•์ธ/๋ฏธ๋ฆฌ๋ณด๊ธฐ/์ฝ”๋“œ ํŒŒ์ผ ์ƒ์„ฑ, PATCH ์ „๋‹ฌ ๊ฒฐ๊ณผ.
  • ๊ถŒํ•œ: ADMIN.
  • ๊ฐœ์ธ์ •๋ณด: ๊ตฌ๋งค์ž ์—ฐ๋ฝ์ฒ˜๋Š” ์•”ํ˜ธํ™” ์ €์žฅยท์‘๋‹ต ๋งˆ์Šคํ‚น, ์—ด๋žŒ์€ ๊ด€๋ฆฌ์ž ๊ถŒํ•œ ๋ฐ ๊ฐ์‚ฌ ๋กœ๊ทธ ๋Œ€์ƒ.
  • UI ์ฐจ์ด: ์ฒจ๋ถ€ ์ด๋ฏธ์ง€๋Š” ๊ฐœ๋ณ„ ๋“ฑ๋ก ๋ฒ„ํŠผ๊ณผ ๋ชฉ๋ก๋งŒ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ์—‘์…€ ๋งคํ•‘ยท๋ฏธ๋ฆฌ๋ณด๊ธฐยท๋””์ง€ํ„ธ ์„ ๋ฌผ ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ ํ™”๋ฉด์€ ๋ณ„๋„ ๊ด€๋ฆฌ์ž ํ”„๋ก ํŠธ์—”๋“œ ๊ตฌํ˜„์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

4) ํด๋ž˜์Šค ์ƒ์„ธ์™€ ํƒญ

์ด๋ฏธ์ง€: 2026-10-14 234004

  • ๋ชฉ์ : ์„ ํƒํ•œ ํด๋ž˜์Šค์˜ ์ด์šฉ๊ถŒ ์—ฐ๊ฒฐ, ์šด์˜ ์„ค์ •, ์ฐธ์—ฌ ํ˜„ํ™ฉ, ๊ฒฐ๊ณผ์™€ ๋ณ€๊ฒฝ ์ด๋ ฅ์„ ๋ด…๋‹ˆ๋‹ค.
  • ๊ธฐ๋ณธ ์ •๋ณด: ํด๋ž˜์Šค ID/์ƒ์„ฑ์ž/์ƒ์„ฑ ์‹œ๊ฐ, ์ด์šฉ๊ถŒ ์—ฐ๊ฒฐ๊ณผ ์œ ํšจ๊ธฐ๊ฐ„, ์„ ํƒ ์ฝ˜ํ…์ธ , ์ •์›/ํ˜„์žฌ ์ธ์›, ์ฐธ์—ฌ ๋งˆ๊ฐ, ๋Œ“๊ธ€ ํ•„์ˆ˜, ์šด์˜์ž ์ฐธ์—ฌ.
  • ํƒญ: ๊ธฐ๋ณธ ์ •๋ณด, ๋ฉค๋ฒ„ยท์ฐธ์—ฌ, ๊ฒฐ๊ณผยทAI, ๋ณ€๊ฒฝ ์ด๋ ฅ.
  • ์•ก์…˜: CSV ๋‚ด๋ณด๋‚ด๊ธฐ, ๋ชฉ๋ก ๋ณต๊ท€. ์‹œ์•ˆ์—์„œ ํŽธ์ง‘/์‚ญ์ œ ๋ฒ„ํŠผ์€ ํ™•์ธ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • API: [๋ณ„๋„ Classroom ๊ตฌํ˜„ ๋ฒ”์œ„] GET /api/v1/admin/classes/{id}, GET /members, GET /results, GET /history, CSV export. ์ด๋ฒˆ Funding ๊ตฌํ˜„์—์„œ๋Š” ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๊ถŒํ•œ: ADMIN.
  • ๋…ผ์˜: ๊ด€๋ฆฌ์ž ์ˆ˜์ •/์‚ญ์ œ UI๋Š” ์ด๋ฏธ์ง€์— ์—†์–ด ๊ธฐ๋ณธ ๊ธฐ๋Šฅ์œผ๋กœ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์šด์˜์ƒ ํ•„์š”ํ•˜๋ฉด ๋ณ„๋„ ํ‹ฐ์ผ“์œผ๋กœ ์ •ํ•ฉ๋‹ˆ๋‹ค.

PRD์—์„œ๋งŒ ํ™•์ธ๋˜๋Š” ์•ฑ ํ™”๋ฉด ํ๋ฆ„ (์ฒจ๋ถ€ UI ์ด๋ฏธ์ง€ ์—†์Œ)

PRD ํ™”๋ฉด ID ์ •์˜๋œ ํ™”๋ฉด/ํ๋ฆ„ ๋ฐฑ์—”๋“œ ํ•ต์‹ฌ
S01 ํด๋ž˜์Šค ํ™ˆ ์ด์šฉ๊ถŒ/๋‚ด ํด๋ž˜์Šค ์š”์•ฝ, ์ƒ์„ฑยท์ฝ”๋“œ ์ž…์žฅ ์ง„์ž…
S02~03 ๋ฐฉ์‹ ์„ ํƒยท์ฃผ์ œ ์กฐ๊ฑด LIBRARY/CUSTOM, ํ‚ค์›Œ๋“œยท์ˆ˜์ค€ยท์นดํ…Œ๊ณ ๋ฆฌ
S04 ๊ธฐ์กด ์ฝ˜ํ…์ธ  ๋ชฉ๋ก ๋ฐฐํ‹€ ์นดํƒˆ๋กœ๊ทธ ๊ฒ€์ƒ‰, ๋ฏธ๋ฆฌ๋“ฃ๊ธฐ ์ •๋ณด
S05 AI ์ฃผ์ œ ์ œ์•ˆ ํ›„๋ณด 8๊ฐœ ๊ธฐ๋ณธ ๊ณ„์•ฝ, ์ง์ ‘ ์ˆ˜์ • ๊ฒ€์ฆ
S06~07 ํด๋ž˜์Šค ์„ค์ •ยท๊ณต์œ  ์™„๋ฃŒ ์ƒ์„ฑ, ์ •์›ยท๋งˆ๊ฐยท์˜ต์…˜, ์ฐธ์—ฌ ์ฝ”๋“œ
S08~09 ์ฝ”๋“œ ์ž…์žฅยท์ด๋ฆ„ ์ž…๋ ฅ ์ฝ”๋“œ ๋ฏธ๋ฆฌ๊ฒ€์ฆ, ์ •์› ๊ฒฝ์Ÿ ์ œ์–ด, ๊ฒŒ์ŠคํŠธ ์„ธ์…˜
S10~11 ๋‚ด ํด๋ž˜์Šคยท์ƒ์„ธ ์ง„ํ–‰/์ข…๋ฃŒ ๋ชฉ๋ก, ๊ตฌ์„ฑ์› ๊ถŒํ•œ๋ณ„ ์ƒ์„ธ
S12 ๋ฉค๋ฒ„ ๋ชฉ๋กยท์ด๋ฆ„ ์ˆ˜์ • ๋ช…๋‹จ, ๋ณธ์ธ ์ด๋ฆ„ ๋ณ€๊ฒฝ, ์šด์˜์ž ๋‚ด๋ณด๋‚ด๊ธฐ
S13 ํด๋ž˜์Šค ๊ด€๋ฆฌ ์šด์˜์ž ์ˆ˜์ •/๊ณต์œ /์‚ญ์ œ, ์ฐธ๊ฐ€์ž ๊ณต์œ /๋‚˜๊ฐ€๊ธฐ
S14 ํด๋ž˜์Šค ์š”์•ฝ ์šด์˜์ž ํ†ต๊ณ„์™€ ๊ณต๊ฐœ ์˜๊ฒฌ, AI ์ธ์‚ฌ์ดํŠธ
S15 ๋‚ด ๋ฆฌํฌํŠธ ์ฐธ์—ฌ์ž ๋ณธ์ธ ๋ฆฌํฌํŠธ๋งŒ ์กฐํšŒ
S16~20 ๊ธฐ์กด ์ฝ˜ํ…์ธ  ๋ฐฐํ‹€ ํด๋ž˜์Šค ๊ฒฉ๋ฆฌ ํˆฌํ‘œยท๋Œ“๊ธ€ยท์™„๋ฃŒ
S21~22 ์ปค์Šคํ…€ AI ๋…ผ์Ÿ 3๋ผ์šด๋“œ, AI Job, ๋ณธ์ธ ๋ฐ˜๋ฐ• ์ €์žฅ

๊ธฐ๋ณธ ์ •์ฑ…์€ PRD์˜ ๊ถŒํ•œ/์—ญํ• ๊ณผ ๋ฐ์ดํ„ฐ ๋ฒ”์œ„๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ๋ณ„๋„ ๊ด€๋ฆฌ์ž ์›น UI๊ฐ€ ์—†๋Š” S01~S22 ํ๋ฆ„์„ ๊ด€๋ฆฌ์ž ํ™”๋ฉด์œผ๋กœ ๊ฐ€์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


3. ํ•„์š”ํ•œ ๋ฐฑ์—”๋“œ ๊ตฌ์„ฑ์š”์†Œ

๊ตฌ์„ฑ์š”์†Œ ์ฑ…์ž„
FundingAccessController ๋‚ด ์ด์šฉ๊ถŒ ์กฐํšŒ, ์ฝ”๋“œ ๋ฏธ๋ฆฌ ํ™•์ธยท๋“ฑ๋ก
FundingTicketService ์ฝ”๋“œ ์ƒํƒœ/๊ธฐํ•œ/์†Œ์œ ์ž ๊ฒ€์ฆ, ์›์ž์  ํ™œ์„ฑํ™”
FundingAdminController ๊ตฌ๋งค์žยท์ฃผ๋ฌธ ์ˆ˜๋™ ๋“ฑ๋ก, ์ฝ”๋“œ ๋ฐœ๊ธ‰, ์ „๋‹ฌ ์ƒํƒœ ๊ด€๋ฆฌ
FundingAdminService PAID ํ™•์ธ, ์ƒํ’ˆ ์ •์› ๋งคํ•‘, ์žฌ๋ฐœ๊ธ‰ยทํ™˜๋ถˆ ์ƒํƒœ ์ฒ˜๋ฆฌ, ๊ฐ์‚ฌ ๊ธฐ๋ก
FundingTicketPolicy ํด๋ž˜์Šค ๋‹ด๋‹น์ž๊ฐ€ ํด๋ž˜์Šค ์ƒ์„ฑ ์ „์— ํ˜ธ์ถœํ•˜๋Š” ๋‚ด๋ถ€ ์„œ๋น„์Šค ๊ณ„์•ฝ. ์†Œ์œ ์žยทACTIVEยท๊ธฐ๊ฐ„ ๊ฒ€์ฆ ํ›„ ์ •์›/๋งŒ๋ฃŒ ์ •๋ณด๋ฅผ ๋ฐ˜ํ™˜
Funding repositories/entities ์บ ํŽ˜์ธยท์ฃผ๋ฌธยท์ด์šฉ๊ถŒยท์ฝ”๋“œยท์ „๋‹ฌ ์ด๋ ฅ ์˜์†ํ™”์™€ ๋™์‹œ์„ฑ ์ œ์–ด
Existing User/Auth ๊ธฐ์กด ์‚ฌ์šฉ์ž์™€ JWT ๊ถŒํ•œ ์žฌ์‚ฌ์šฉ; User ๋„๋ฉ”์ธ์€ Funding ๋ชฉ์ ์œผ๋กœ ํ™•์žฅํ•˜์ง€ ์•Š์Œ
Classroom domain ๋ณ„๋„ ๋‹ด๋‹น์ž ์†Œ์œ . ์ด๋ฒˆ ๋ฒ”์œ„์—์„œ ํด๋ž˜์Šค ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์—†์ด ์œ„ ์ •์ฑ… ํ˜ธ์ถœ ๋ฐ ticketId ์—ฐ๊ฒฐ๋งŒ ํ†ตํ•ฉ

Funding ์‚ฌ์šฉ์ž Controller์™€ Admin Controller๋Š” ์ธ์ฆยท์‘๋‹ต DTO๋ฅผ ๋ถ„๋ฆฌํ•˜๊ณ , ์—…๋ฌด ๋ถˆ๋ณ€์‹์€ Funding Service์—์„œ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๊ด€๋ฆฌ์ž ์•ก์…˜์€ ๊ฐ™์€ ํ•ต์‹ฌ Service์˜ ์ƒํƒœ ๋ณ€๊ฒฝ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋˜, ์ผ๋ฐ˜ ์‚ฌ์šฉ์ž๊ฐ€ ์ž„์˜์˜ userId๋ฅผ ์ „๋‹ฌํ•ด ์‹คํ–‰ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. Classroom/AI Controller์™€ Service๋Š” ์ด๋ฒˆ ๊ตฌํ˜„ ๋Œ€์ƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.


4. API ๋ช…์„ธ

๊ณตํ†ต ๊ณ„์•ฝ

ํ”„๋กœ์ ํŠธ์—๋Š” ๊ณตํ†ต ์‘๋‹ต์ด ์ด๋ฏธ ์žˆ์Šต๋‹ˆ๋‹ค.

{
  "statusCode": 200,
  "data": {},
  "error": null
}
  • ์„ฑ๊ณต ๋ž˜ํผ: ๊ธฐ์กด ApiResponse๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ onSuccess๋Š” statusCode 200์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ API์˜ HTTP status์™€ body statusCode๋ฅผ ์ผ์น˜์‹œํ‚ค๋ ค๋ฉด ์ž‘์€ overload๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
  • ์‹คํŒจ ๋ž˜ํผ: ๊ธฐ์กด ํ˜•์‹์€ {statusCode, data:null, error:{code,message}}์ž…๋‹ˆ๋‹ค. HTTP status๋Š” ์˜๋ฏธ๋ฅผ ํ‘œํ˜„ํ•˜๊ณ  ErrorCode๋Š” ํ™”๋ฉด ๋ถ„๊ธฐ์šฉ ์•ˆ์ • ํ‚ค๋กœ ์”๋‹ˆ๋‹ค.
  • ๋ชฉ๋ก: ๊ธฐ์กด PageResponse๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์š”์ฒญ page๋Š” 0๋ถ€ํ„ฐ, ์‘๋‹ต page๋Š” ํ˜„์žฌ ๊ตฌํ˜„์ฒ˜๋Ÿผ 1๋ถ€ํ„ฐ ๋งž์ถ”๊ฑฐ๋‚˜ ๊ธฐ์กด AdminUserSearchResponse์ฒ˜๋Ÿผ hasNext ๊ณ„์•ฝ์„ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์—์„œ๋Š” PageResponse๋กœ ํ†ต์ผ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
  • ์ธ์ฆ: ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž API๋Š” Authorization: Bearer {accessToken}. Refresh๋Š” ํ˜„์žฌ X-Refresh-Token์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฒŒ์ŠคํŠธ API๋Š” ๋ณ„๋„ signed guest token์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ์“ฐ๊ธฐ ์ค‘๋ณต ๋ฐฉ์ง€: Funding ์ฝ”๋“œ claim๊ณผ ๊ตฌ๋งค์ž/์ฃผ๋ฌธ ๋“ฑ๋ก์€ Idempotency-Key ๋˜๋Š” Funding ๊ณ ์œ  ํ‚ค๋กœ ์ค‘๋ณต ์ฒ˜๋ฆฌ๋ฅผ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. Classroom ์“ฐ๊ธฐ์™€ AI turn์€ ํ•ด๋‹น ๋‹ด๋‹น ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค.

๊ธฐ์กด API ๋ฐ Funding ์‚ฌ์šฉ์ž API

์ƒํƒœ Method / URL ๋ชฉ์  ๋ฐ ์ž…๋ ฅ ์‘๋‹ต Auth HTTP / ์ฃผ์š” ์˜ค๋ฅ˜
[์กด์žฌ] POST /api/v1/auth/login/{provider} ๊ธฐ์กด ์†Œ์…œ ๋กœ๊ทธ์ธ ๊ธฐ์กด LoginResponse ์—†์Œ 200, AUTH_*
[์กด์žฌ] POST /api/v1/auth/refresh X-Refresh-Token ๊ฐฑ์‹  ๊ธฐ์กด LoginResponse Refresh Token 200, AUTH_REFRESH_TOKEN_EXPIRED
[์กด์žฌ] POST /api/v1/auth/logout ๋กœ๊ทธ์•„์›ƒ {success:true} USER 200
[์กด์žฌ] GET /api/v1/me/mypage ๊ธฐ์กด ๋งˆ์ดํŽ˜์ด์ง€ ๊ธฐ์กด MypageResponse USER 200
[๋ถ€๋ถ„ ์กด์žฌ] GET /api/v1/battles?page=1&size=10 ๊ณต๊ฐœ ๋ฐฐํ‹€ ์นดํƒˆ๋กœ๊ทธ ๊ธฐ๋ณธ ๋ชฉ๋ก ๊ธฐ์กด BattleListResponse ๊ธฐ์กด ์ •์ฑ… 200
[๋ถ€๋ถ„ ์กด์žฌ] GET /api/v1/battles/{battleId} ๋ฐฐํ‹€ ์ƒ์„ธ/์ฝ˜ํ…์ธ  ์กฐํšŒ ๊ธฐ์กด ์ƒ์„ธ ์‘๋‹ต ๊ธฐ์กด ์ •์ฑ… 200, BATTLE_NOT_FOUND
[๊ตฌํ˜„ ์™„๋ฃŒ] GET /api/v1/tickets/me ๋‚ด ์ด์šฉ๊ถŒ ์ƒํƒœ ์กฐํšŒ NONE/ACTIVE/EXPIRED/REVOKED์™€ ๊ธฐ๊ฐ„ USER 200, 401
[๊ตฌํ˜„ ์™„๋ฃŒ] POST /api/v1/ticket-codes/preview {code}; ์ฝ”๋“œ๋ฅผ ์†Œ๋น„ํ•˜์ง€ ์•Š๋Š” ๊ฒ€์ฆ ์ƒํ’ˆยท์ •์›ยทregisterByยท๋“ฑ๋ก ์‹œ ์ข…๋ฃŒ ์˜ˆ์ •์ผ USER 200, 422 TICKET_CODE_INVALID, 410 TICKET_CODE_EXPIRED, 409 TICKET_CODE_UNAVAILABLE
[๊ตฌํ˜„ ์™„๋ฃŒ] POST /api/v1/ticket-codes/claim {code}; ๊ฐ™์€ ์ฝ”๋“œ์˜ ๊ฐ™์€ ์‚ฌ์šฉ์ž ์žฌ์š”์ฒญ์€ ์ตœ์ดˆ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜ ticketIdยทcapacityยทactivatedAtยทexpiresAt USER 200, 409 TICKET_ALREADY_ACTIVE, 409 TICKET_CODE_UNAVAILABLE

Classroom ์ƒ์„ฑ ์‹œ ๋‚ด๋ถ€ ์—ฐ๋™ ๊ณ„์•ฝ์€ FundingTicketPolicy.requireUsableBy(userId, ticketId)์ด๋ฉฐ, capacity์™€ expiresAt์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ณ„๋„ HTTP endpoint๋Š” ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šค ์ƒ์„ฑยท์ž…์žฅยทํ™œ๋™ ๋ฐ AI API๋Š” ๋‹ค๋ฅธ ๊ตฌํ˜„ ๋ฒ”์œ„์ด๋ฉฐ ์ด๋ฒˆ Funding API ๋ชฉ๋ก์—๋Š” ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด battle API๋Š” ๊ทธ๋Œ€๋กœ ๋‘ก๋‹ˆ๋‹ค.

๊ด€๋ฆฌ์ž API

์ƒํƒœ Method / URL ์ž…๋ ฅ/์กฐํšŒ ์‘๋‹ต Auth HTTP / ์ฃผ์š” ์˜ค๋ฅ˜
[์กด์žฌ] GET /api/v1/admin/users/search?keyword=&page=0&size=20 ๊ธฐ์กด ์•ฑ ์‚ฌ์šฉ์ž ๊ฒ€์ƒ‰ itemsยทhasNext ADMIN 200
[์กด์žฌ] GET /api/v1/admin/dashboard/summary ๊ธฐ์กด ์ผ๋ฐ˜ ๋Œ€์‹œ๋ณด๋“œ ์š”์•ฝ ๊ธฐ์กด ํ†ต๊ณ„ DTO ADMIN 200
[๊ตฌํ˜„ ์™„๋ฃŒ] GET /api/v1/admin/tickets?keyword=&capacity=&status=&registeredFrom=&registeredTo=&page=0&size=20 ์ฝ”๋“œ/๋“ฑ๋ก์ž ๋ชฉ๋ก PageResponse ADMIN 200
[๊ตฌํ˜„ ์™„๋ฃŒ] POST /api/v1/admin/funding-orders ๋‹จ๊ฑด ๊ตฌ๋งค์žยท์ฃผ๋ฌธยท์ƒํ’ˆยท๊ฒฐ์ œํ™•์ธ ์ˆ˜๋™ ๋“ฑ๋ก fundingOrderId, ticketIds ADMIN 201, 409 FUNDING_ORDER_DUPLICATE
[๊ตฌํ˜„ ์™„๋ฃŒ] POST /api/v1/admin/funding-orders/tumblbug/inspect ํ›„์›์ž XLSX์˜ ์ „์ฒด ์‹œํŠธ์—์„œ ํ—ค๋” ์ž๋™ ํŒ๋ณ„ ๋ฐ ์ƒ˜ํ”Œ ํ–‰ ํ™•์ธ ์‹œํŠธ๋ณ„ ์ธ์‹/๋ˆ„๋ฝ ์—ด, ์ƒ˜ํ”Œ ํ–‰ ADMIN 200, 400 ํ˜•์‹ ์˜ค๋ฅ˜, 413 10MB ์ดˆ๊ณผ
[๊ตฌํ˜„ ์™„๋ฃŒ] POST /api/v1/admin/funding-orders/tumblbug/preview ์„ ํƒ ์‹œํŠธ์—์„œ 9๊ฐœ ์—ด ์ž๋™ ํŒ๋ณ„, ๊ฒฐ์ œยท์ค‘๋ณตยท์ˆ˜๋Ÿ‰ ๊ฒ€ํ†  ํ–‰๋ณ„ ์ €์žฅ/์ฝ”๋“œ ๋ฐœ๊ธ‰ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ ADMIN 200, 400 ์˜ต์…˜ ์˜ค๋ฅ˜, 422 ํ•„์ˆ˜ ์—ด ๋ˆ„๋ฝ
[๊ตฌํ˜„ ์™„๋ฃŒ] POST /api/v1/admin/funding-orders/tumblbug/digital-gifts ์œ ํšจํ•œ ํ–‰ ์ €์žฅ, ๊ฒฐ์ œ ์™„๋ฃŒ ํ–‰์— ์ฝ”๋“œ ๋ฐœ๊ธ‰, ์—…๋กœ๋“œ์šฉ XLSX ๋ฐ˜ํ™˜ (์ตœ๋Œ€ 5,000ํ–‰) ํ›„์›๋ฒˆํ˜ธ์™€ ์ฝ”๋“œ ํ…์ŠคํŠธ ํŒŒ์ผ ADMIN 200, 409 ์ค‘๋ณต, 413 ํŒŒ์ผ/ํ–‰ ์ œํ•œ, 422 ํ•„์ˆ˜ ์—ด/ํ–‰ ์˜ค๋ฅ˜
[๊ตฌํ˜„ ์™„๋ฃŒ] PATCH /api/v1/admin/funding-orders/tumblbug/digital-gifts/delivery ํ…€๋ธ”๋ฒ… ์—…๋กœ๋“œ ๊ฒฐ๊ณผ๋ฅผ ํ›„์›๋ฒˆํ˜ธ ๋ชฉ๋ก์œผ๋กœ ๊ธฐ๋ก ๋ฐ˜์˜/๋ฏธ๋งค์นญ ๊ฑด์ˆ˜ ADMIN 200, 400 ์ƒํƒœ ์˜ค๋ฅ˜
[๊ตฌํ˜„ ์™„๋ฃŒ] GET /api/v1/admin/funding-orders?keyword=&capacity=&deliveryStatus=&claimStatus=&page=0&size=20 ๊ตฌ๋งค์ž ๋ชฉ๋ก ๋งˆ์Šคํ‚น ์—ฐ๋ฝ์ฒ˜ยท์ƒํ’ˆยท์ „๋‹ฌ/๋“ฑ๋ก ์ƒํƒœ ADMIN 200
[๊ตฌํ˜„ ์™„๋ฃŒ] POST /api/v1/admin/tickets/{ticketId}/codes ๋“ฑ๋ก ์ฝ”๋“œ ๋ฐœ๊ธ‰ 1ํšŒ ๋…ธ์ถœ codeยท๋ฐœ๊ธ‰ ์ƒํƒœ ADMIN 201, 409 TICKET_CODE_ALREADY_ISSUED
[๊ตฌํ˜„ ์™„๋ฃŒ] PATCH /api/v1/admin/deliveries/{id} {channel,status,failedReason} ์ „๋‹ฌ ๊ฒฐ๊ณผ ๊ธฐ๋ก ์ „๋‹ฌ ์ƒํƒœยท์‹œ๊ฐ ADMIN 200
[๊ตฌํ˜„ ์™„๋ฃŒ] POST /api/v1/admin/tickets/{ticketId}/reissue ๋ฏธ๋“ฑ๋ก ์ฝ”๋“œ ํ๊ธฐ ํ›„ ์žฌ๋ฐœ๊ธ‰ ์ƒˆ ์ฝ”๋“œยท๊ธฐ์กด registerBy ADMIN 201, 409 FUNDING_REISSUE_NOT_ALLOWED
[๊ตฌํ˜„ ์™„๋ฃŒ] POST /api/v1/admin/tickets/{ticketId}/refund ์‹ค์ œ ์™ธ๋ถ€ ํ™˜๋ถˆ์„ ํ™•์ธํ•œ ํ›„ ์ฃผ๋ฌธยท์—ฐ๊ฒฐ ์ด์šฉ๊ถŒ ์ทจ์†Œ FundingOrder REFUNDED, Ticket/TicketCode REVOKED ADMIN 200, 409 FUNDING_REFUND_NOT_CONFIRMED

์ฃผ์š” JSON ์˜ˆ์‹œ

์ฝ”๋“œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ:

{
  "code": "PICKE-3E8T-U3AB-C5D6-F7GH-JKLM-NPQR-STUV"
}
{
  "statusCode": 200,
  "data": {
    "codeStatus": "VALID",
    "capacity": 30,
    "registerBy": "2027-10-10T05:00:00Z",
    "activatedAtIfClaimed": "2026-10-15T03:00:00Z",
    "expiresAtIfClaimed": "2027-04-15T03:00:00Z"
  }
}

์ฝ”๋“œ ๋“ฑ๋ก:

{
  "statusCode": 200,
  "data": {
    "ticketId": 4102,
    "status": "ACTIVE",
    "capacity": 30,
    "activatedAt": "2026-10-15T03:00:00Z",
    "expiresAt": "2027-04-15T03:00:00Z"
  }
}

ํด๋ž˜์Šค ์ƒ์„ฑ API request/response๋Š” ์ด๋ฒˆ Funding ์„ค๊ณ„์—์„œ ์ •์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Classroom ๋‹ด๋‹น์ž๊ฐ€ ์œ„ ๋‚ด๋ถ€ FundingTicketPolicy ๊ณ„์•ฝ๊ณผ ticketId๋งŒ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

๊ณตํ†ต ์˜ค๋ฅ˜ ์˜ˆ์‹œ:

{
  "statusCode": 422,
  "data": null,
  "error": {
    "code": "TICKET_CODE_INVALID",
    "message": "์ฝ”๋“œ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์•„์š”. ์ž…๋ ฅํ•œ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ํ™•์ธํ•ด ์ฃผ์„ธ์š”."
  }
}

๊ถŒ์žฅ: ErrorCode๋งŒ ์ „๋‹ฌํ•˜๊ณ  ์•ฑ์ด ํ‘œ์‹œ ๋ฌธ๊ตฌ๋ฅผ ๋งคํ•‘ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด GlobalExceptionHandler๋Š” ErrorCode์˜ message๋„ ์‘๋‹ตํ•˜๋ฏ€๋กœ, ์œ„ ๋ฌธ๊ตฌ๋ฅผ ์„œ๋ฒ„์—์„œ ์ œ๊ณตํ• ์ง€ ์•ฑ ์ƒ์ˆ˜๋กœ ๊ด€๋ฆฌํ• ์ง€๋Š” ์•ฑ ๊ฐœ๋ฐœ์ž์™€ ํ•ฉ์˜ํ•ฉ๋‹ˆ๋‹ค.


5. DB / Entity ์„ค๊ณ„

๋ชจ๋“  ์ฃผ์š” Entity๋Š” ๊ธฐ์กด BaseEntity๋ฅผ ์ƒ์†ํ•ด id, createdAt, updatedAt์„ ์žฌ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ํ•„๋“œ๋“ค์„ ๋„๋ฉ”์ธ๋ณ„๋กœ ๋‹ค์‹œ ์ •์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” PostgreSQL์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ application.yml์€ hibernate ddl-auto: update๋ฅผ ์„ค์ •ํ•˜๊ณ  SQL migration ํŒŒ์ผ๋„ ์ €์žฅ์†Œ์— ์žˆ์œผ๋ฏ€๋กœ, ์‹ค์ œ ๋ฐฐํฌ์šฉ ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ ์ ˆ์ฐจ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ธฐ์กด ๋ฐฐํฌ ๊ทœ์น™์„ ํ™•์ธํ•œ ํ›„ ํ•œ ๋ฐฉ์‹์œผ๋กœ ์ ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Entity ํ•ต์‹ฌ ํ•„๋“œ ๊ด€๊ณ„/์ œ์•ฝ
User (๊ธฐ์กด) ๊ธฐ์กด userTag, role, status ๊ธฐ์กด ์—”ํ‹ฐํ‹ฐ ์ˆ˜์ • ์ตœ์†Œํ™”. owner/claim ์—ฐ๊ฒฐ FK
FundingCampaign platform, externalCampaignId, name, status, registerPolicyVersion platform+externalCampaignId UNIQUE
FundingOrder campaign, externalOrderId, rewardLineId, rewardType, quantity, capacity, paymentStatus, paidAt, buyerName, buyerContactEncrypted, buyerContactSearchHash, sourceVersion campaign+externalOrder+rewardLine UNIQUE; paidAt ํ•„์ˆ˜ ๋ฐœ๊ธ‰ ์กฐ๊ฑด
Ticket fundingOrder, ownerUser, capacity, registerBy, activatedAt, expiresAt, status fundingOrder+unitIndex UNIQUE; ownerUser nullable until claim; ํ•œ ์‚ฌ์šฉ์ž ํ™œ์„ฑ/๋ฏธ๋“ฑ๋ก ๊ถŒํ•œ ์ œํ•œ
TicketCode ticket, codeHash, status, issuedAt, deliveredAt, claimedAt, revokedAt codeHash UNIQUE; ์›๋ฌธ ์ฝ”๋“œ ์ €์žฅ ๊ธˆ์ง€
DeliveryAttempt ticketCode, channel, status, maskedDestination, failedReason, attemptedAt, completedAt ํ˜„์žฌ๋Š” ์ฝ”๋“œ ๋ฐœ๊ธ‰ ์‹œ ์ „๋‹ฌ ๋Œ€๊ธฐ ํ–‰์„ ๋งŒ๋“ค๊ณ  ๊ด€๋ฆฌ์ž๊ฐ€ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ก; ์ฝ”๋“œ ์›๋ฌธ/์ „์ฒด ์—ฐ๋ฝ์ฒ˜ ๋กœ๊ทธ ๊ธˆ์ง€
Classroom (๋ณ„๋„ ๋‹ด๋‹น) ticketId Funding ์—ฐ๋™์— ํ•„์š”ํ•œ ๋น„๊ณ ์œ  FK๋งŒ ํ•ฉ์˜ยท์—ฐ๊ฒฐ. ํด๋ž˜์Šค Entity/๊ธฐ๋Šฅ ๊ตฌํ˜„์€ ์ด๋ฒˆ ๋ฒ”์œ„ ์•„๋‹˜
AdminAuditLog adminUser, action, targetType, targetId, reason, metadata ๊ฐœ์ธ์ •๋ณด ์ตœ์†Œํ™”, ๊ด€๋ฆฌ์ž ์ƒ์„ธ ์ด๋ ฅ์— ์‚ฌ์šฉ

๊ด€๊ณ„ ์š”์•ฝ

FundingCampaign 1 โ”€โ”€ N FundingOrder 1 โ”€โ”€ N Ticket
                                             โ”œโ”€โ”€ 0..1 User (claim ์ „์—๋Š” ๋ฏธ์—ฐ๊ฒฐ)
                                             โ”œโ”€โ”€ N TicketCode
                                             โ””โ”€โ”€ 0..N Classroom (๋ณ„๋„ Classroom ๋‹ด๋‹น์ด ticketId๋กœ ์ฐธ์กฐ)

Membership, Participation, TopicVersion, ClassVote, Report, AIJob ๋“ฑ์€ ์ด๋ฒˆ Funding ๋ฒ”์œ„์—์„œ Entity/ํ…Œ์ด๋ธ”๋กœ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Enum ํ›„๋ณด

  • FundingPaymentStatus: RESERVED, PAYMENT_PENDING, PAID_CONFIRMED, PAYMENT_FAILED, CANCELED, REFUNDED
  • TicketStatus: UNREGISTERED, ACTIVE, EXPIRED, REGISTER_EXPIRED, REVOKED
  • TicketCodeStatus: ISSUED, DELIVERED, CLAIMED, REVOKED

์ˆ˜๋™ ์šด์˜ ๊ธฐ์ค€ ์—”ํ‹ฐํ‹ฐ ๊ฒ€ํ† 

์šด์˜์ž๊ฐ€ ๋ช…๋‹จ Excel์„ ๋‚ด๋ ค๋ฐ›์•„ ์„œ๋ฒ„์—์„œ ๋ฏธ๋ฆฌ๋ณด๊ธฐยท๊ฒ€ํ† ํ•œ ๋’ค ๋ฐœ๊ธ‰์„ ํ™•์ •ํ•˜๋Š” MVP์—๋Š” ํ˜„์žฌ ์—ฌ์„ฏ ์—”ํ‹ฐํ‹ฐ๋งŒ์œผ๋กœ ํ•ต์‹ฌ ์—…๋ฌด๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Excel ์ˆ˜์ง‘ ๋ฐฐ์น˜์šฉ Entity๋Š” ์ด๋ฒˆ ๋ฒ”์œ„์— ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹ค๋งŒ ์šด์˜ ์ „ ๋‹ค์Œ ์ •์˜๋ฅผ ํ™•์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ํ…€๋ธ”๋ฒ… ๊ฐ€์ ธ์˜ค๊ธฐ๋Š” externalSupporterNumber์™€ rewardLineId ์กฐํ•ฉ์„ ํ›„์›์žยท๋ฆฌ์›Œ๋“œ์˜ ์ค‘๋ณต ๋ฐฉ์ง€ ํ‚ค๋กœ ์‚ฌ์šฉํ•˜๊ณ , ์ผ๋ฐ˜ ์ˆ˜๋™ ๋“ฑ๋ก์€ externalOrderId์™€ rewardLineId๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ ํ…€๋ธ”๋ฒ… Excel ์ƒ˜ํ”Œ๋กœ ์ž๋™ ํŒ๋ณ„ ๋ณ„์นญ์„ ๊ฒ€์ฆํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ํ™˜๋ถˆ์€ ํ•ด๋‹น Ticket์ด ์†ํ•œ FundingOrder์˜ Ticket ์ „์ฒด๋ฅผ ์ทจ์†Œํ•˜๋ฉฐ, ๊ฐ™์€ ์™ธ๋ถ€ ํ›„์›๋ฒˆํ˜ธ์˜ ๋‹ค๋ฅธ rewardLine๊นŒ์ง€ ์ทจ์†Œํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.
  • FundingCampaign.registerPolicyVersion์€ ํ˜„์žฌ ๋ฐœ๊ธ‰ ์ •์ฑ… ์„ ํƒ์— ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ •์ฑ… ๋ฒ„์ „์„ ๋ณด์กดํ•˜์ง€ ์•Š์„ ๊ณ„ํš์ด๋ฉด ์ œ๊ฑฐํ•˜๊ณ , ์œ ์ง€ํ•œ๋‹ค๋ฉด ๋ฒ„์ „๋ณ„๋กœ ๊ณ ์ •ํ•  ์ •์ฑ… ๊ฐ’์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์บ ํŽ˜์ธ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์šด์˜ ๊ฒฝ๋กœ๋„ ํ•„์š”ํ•œ์ง€ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.
  • ํ˜„์žฌ DeliveryAttempt๋Š” ์ฝ”๋“œ ๋ฐœ๊ธ‰ ์‹œ ์ „๋‹ฌ ์ฑ„๋„(MANUAL ๋˜๋Š” TUMBLBUG_DIGITAL_GIFT)๊ณผ PENDING์œผ๋กœ ์ƒ์„ฑ๋˜๊ณ  ๊ด€๋ฆฌ์ž๊ฐ€ ๊ฒฐ๊ณผ๋ฅผ ํ•œ ๋ฒˆ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ ๋ฐœ์†ก ์‹œ๋„ยท์žฌ์‹œ๋„ ์ด๋ ฅ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ˆ˜๋™ MVP์—์„œ๋Š” ์ „๋‹ฌ ๊ฒฐ๊ณผ ๊ธฐ๋ก์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ , ์žฌ์‹œ๋„๋งˆ๋‹ค ์ด๋ ฅ์ด ํ•„์š”ํ•ด์งˆ ๋•Œ ์‹œ๋„ ๋‹จ์œ„๋กœ ํ™•์žฅํ•ฉ๋‹ˆ๋‹ค.
  • AdminAuditLog๋Š” ์ฃผ๋ฌธ ๋“ฑ๋กยท์ฝ”๋“œ ๋ฐœ๊ธ‰ยท์ „๋‹ฌ ๊ฒฐ๊ณผยทํ™˜๋ถˆ ๋ณ€๊ฒฝ์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ๊ตฌ๋งค์ž ์ •๋ณด ์กฐํšŒยท๋‚ด๋ณด๋‚ด๊ธฐ๋„ ๊ฐ์‚ฌ ๋Œ€์ƒ์œผ๋กœ ํฌํ•จํ• ์ง€ ์ •ํ•˜๊ณ , metadata์—๋Š” ์—ฐ๋ฝ์ฒ˜ ์›๋ฌธ์ด๋‚˜ ์ฝ”๋“œ ์›๋ฌธ์„ ์ €์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ด ํ•ญ๋ชฉ๋“ค์€ ์ถ”๊ฐ€ Excel ๋ฐฐ์น˜ Entity๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋Š” ๋œป์ด ์•„๋‹ˆ๋ผ, ์ˆ˜๋™ ์šด์˜์—์„œ๋„ ์™ธ๋ถ€ ID ๋งคํ•‘ยทํ™˜๋ถˆ ๋ฒ”์œ„ยท์ •์ฑ…ยท์ „๋‹ฌ ๊ธฐ๋กยท๊ฐ์‚ฌ ๋ฒ”์œ„๋ฅผ ํ™•์ •ํ•ด์•ผ ํ•œ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค.

์ œ์•ฝ๊ณผ JPA ์ฃผ์˜์ 

  • UNIQUE: ์™ธ๋ถ€ ์ฃผ๋ฌธ ๋ผ์ธ, ํ›„์›๋ฒˆํ˜ธยท๋ฆฌ์›Œ๋“œ ๋ผ์ธ, TicketCode.codeHash. Classroom.ticketId์—๋Š” UNIQUE๋ฅผ ๋‘์ง€ ์•Š์•„ ํ•˜๋‚˜์˜ ์ด์šฉ๊ถŒ์„ ์—ฌ๋Ÿฌ ํด๋ž˜์Šค์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • INDEX: Funding ์ƒํƒœ/์ƒ์„ฑ์ผ, ticket owner/status, funding order paidAt/status. ๊ฒ€์ƒ‰ ํ‚ค์›Œ๋“œ์™€ ๋งˆ์Šคํ‚น ์—ฐ๋ฝ์ฒ˜๋Š” ์›๋ฌธ ์ „์ฒด ์ธ๋ฑ์Šค๋ฅผ ํ”ผํ•˜๊ณ  ํ•„์š”ํ•œ ๊ฒ€์ƒ‰ ํ•ด์‹œ/์ •๊ทœํ™” ํ‚ค๋ฅผ ๋ณ„๋„ ๊ฒ€ํ† ํ•ฉ๋‹ˆ๋‹ค.
  • Nullable: Ticket.ownerUser๋Š” ์ฝ”๋“œ ๋“ฑ๋ก ์ „ null์ž…๋‹ˆ๋‹ค. Classroom FK์˜ ํ•„์ˆ˜ ์—ฌ๋ถ€์™€ ์‚ญ์ œ/ํ™˜๋ถˆ ์‹œ ๋™์ž‘์€ Classroom ๋‹ด๋‹น์ž์™€ ํ•ฉ์˜ํ•ฉ๋‹ˆ๋‹ค.
  • Cascade: User ์‚ญ์ œ์— funding ๊ธฐ๋ก์„ ๊ด‘๋ฒ”์œ„ Cascadeํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์„œ๋น„์Šค์—์„œ ๋น„๊ณต๊ฐœ ์ฒ˜๋ฆฌยทํŒŒ๊ธฐ ํ๋ฅผ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค.
  • Fetch: ๋ชจ๋“  ์—ฐ๊ด€์€ ๊ธฐ๋ณธ LAZY. ๋ชฉ๋ก API๋Š” projection/DTO query๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  Entity๋ฅผ ์ง์ ‘ JSON ์ง๋ ฌํ™”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์ด์šฉ๊ถŒ ์ฝ”๋“œ๋Š” PICKE- ๋’ค์— O ์ œ์™ธ A-Z์™€ 1-9๋กœ ๋งŒ๋“  ๋‚œ์ˆ˜ 28์ž๋ฅผ 4์ž์”ฉ ๊ณ ์ • ๊ทธ๋ฃน์œผ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค(์•ฝ 142๋น„ํŠธ). ์„œ๋ฒ„์—๋Š” SHA-256 ํ•ด์‹œ๋งŒ ์ €์žฅํ•˜๊ณ , ๊ตฌ PK ํ˜•์‹๋„ ๊ธฐ์กด ์ฝ”๋“œ ํ˜ธํ™˜์„ ์œ„ํ•ด ๋“ฑ๋ก์„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. Classroom ์ฐธ์—ฌ ์ฝ”๋“œ ์„ค๊ณ„๋Š” ๋ณ„๋„ Classroom ๋‹ด๋‹น ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค.
  • code ์›๋ฌธ์€ ๊ด€๋ฆฌ์ž ๋ฐœ๊ธ‰ ์งํ›„ ํ•œ ๋ฒˆ๋งŒ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ถ„์‹ค ์‹œ ๊ธฐ์กด ๋ฏธ๋“ฑ๋ก ์ฝ”๋“œ๋ฅผ ํ๊ธฐํ•˜๊ณ  ๊ฐ™์€ ์ด์šฉ๊ถŒยท๋“ฑ๋ก๊ธฐํ•œ์œผ๋กœ ์žฌ๋ฐœ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.

6. ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง

ํŽ€๋”ฉ ์ฃผ๋ฌธ์—์„œ ์ด์šฉ๊ถŒ ๋ฐœ๊ธ‰

  1. ADMIN์ด ๊ตฌ๋งค์ž/์ฃผ๋ฌธ/์ƒํ’ˆ/๊ฒฐ์ œ ์™„๋ฃŒ ์ƒํƒœ๋ฅผ ์ˆ˜๋™ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค. ๋ชจ์ง‘ ์ข…๋ฃŒ๋‚˜ ๋ชฉํ‘œ ๋‹ฌ์„ฑ๋งŒ์œผ๋กœ ๊ฒฐ์ œ์™„๋ฃŒ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  2. ํ”Œ๋žซํผยท์บ ํŽ˜์ธยท์ฃผ๋ฌธยท๋ฆฌ์›Œ๋“œ ํ–‰ ๊ณ ์œ  ํ‚ค๋กœ ์ค‘๋ณต ์ฃผ๋ฌธ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  3. ๋ฆฌ์›Œ๋“œ ID๋ฅผ 5/15/30์ธ capacity๋กœ ๋งคํ•‘ํ•ฉ๋‹ˆ๋‹ค. ๋ถˆ๋ช…ํ™•ํ•œ ๋ฆฌ์›Œ๋“œ๋Š” ๋ณด๋ฅ˜ํ•ฉ๋‹ˆ๋‹ค.
  4. ํ™•์ธ๋œ ๊ฒฐ์ œ์™„๋ฃŒ ํ–‰์—๋งŒ Ticket์™€ TicketCode๋ฅผ ๋ฐœ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.
  5. registerBy๋Š” ์ตœ์ข… ๊ฒฐ์ œ ํ™•์ธ์ผ + ๋‹ฌ๋ ฅ ๊ธฐ์ค€ 1๋…„์ž…๋‹ˆ๋‹ค.
  6. ์ „๋‹ฌ ์ƒํƒœ๋Š” ๋ฐœ๊ธ‰๊ณผ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ด€๋ฆฌ์ž ์•ก์…˜/์ „๋‹ฌ ์‹œ๋„ ๊ธฐ๋ก์œผ๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

์ฝ”๋“œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ/๋“ฑ๋ก

  1. ๋กœ๊ทธ์ธ๊ณผ ์ž…๋ ฅ ํ˜•์‹์„ ํ™•์ธํ•˜๊ณ  ์ฝ”๋“œ ์ •๊ทœํ™” ํ›„ codeHash๋กœ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.
  2. Preview๋Š” ๋“ฑ๋ก๊ธฐํ•œ, ๊ฒฐ์ œ ์ƒํƒœ, ์ฝ”๋“œ ์ƒํƒœ, ์†Œ์œ  ์ƒํƒœ๋งŒ ๊ฒ€์‚ฌํ•˜๊ณ  ์ฝ”๋“œ๋ฅผ ์†Œ๋น„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  3. Claim ํŠธ๋žœ์žญ์…˜์€ TicketCode ํ–‰์„ PESSIMISTIC_WRITE๋กœ ์ž ๊ธ‰๋‹ˆ๋‹ค.
  4. User ํ–‰๋„ ์ž ๊ทธ๊ณ  ๋ณด์œ  ์ œํ•œยท๊ธฐ์กด ๋™์ผ ์š”์ฒญ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  5. ์กฐ๊ฑด ํ†ต๊ณผ ์‹œ Ticket.ownerUser๋ฅผ ํ˜„์žฌ ์‚ฌ์šฉ์ž๋กœ ์—ฐ๊ฒฐํ•˜๊ณ  activatedAt/ expiresAt์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. expiresAt์€ activatedAt + ๋‹ฌ๋ ฅ ๊ธฐ์ค€ 6๊ฐœ์›”์ž…๋‹ˆ๋‹ค.
  6. TicketCode๋Š” CLAIMED๋กœ ์ „์ดํ•ฉ๋‹ˆ๋‹ค. codeยท์†Œ์œ ์žยทํ™œ์„ฑยท์ข…๋ฃŒ ์‹œ๊ฐ์€ ํ•œ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์ปค๋ฐ‹ํ•ฉ๋‹ˆ๋‹ค.
  7. ๊ฐ™์€ ์‚ฌ์šฉ์ž์˜ ์žฌ์‹œ๋„๋Š” ๊ธฐ์กด ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜. ํƒ€ ๊ณ„์ • ๊ฒฝ์Ÿ์€ ํ•œ ์š”์ฒญ๋งŒ ์„ฑ๊ณต.
  8. ํ™˜๋ถˆ ํ™•์ •์€ Funding์—์„œ REVOKED ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. Classroom ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์ด๋‚˜ ํ™œ๋™ ์ฐจ๋‹จ ๊ตฌํ˜„์€ ๋ณ„๋„ ์†Œ์œ  ๋ฒ”์œ„์ด๋ฉฐ, ํด๋ž˜์Šค ์ƒ์„ฑ ์‹œ Funding ์œ ํšจ์„ฑ ํ™•์ธ์œผ๋กœ ์‹ ๊ทœ ์—ฐ๊ฒฐ์„ ๋ง‰์Šต๋‹ˆ๋‹ค. ์˜ค๋ž˜๋œ ๊ฒฐ์ œ ์—…๋กœ๋“œ๊ฐ€ ํ™˜๋ถˆ์„ ๋˜๋Œ๋ฆฌ์ง€ ์•Š๋„๋ก ์ƒํƒœ ์ „์ด ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋‘ก๋‹ˆ๋‹ค.

Classroom ์ตœ์†Œ ์—ฐ๋™

  1. Funding์€ ์ฝ”๋“œ ๋“ฑ๋ก ํ›„ Ticket.ownerUser, capacity, activatedAt, expiresAt, status๋ฅผ ๋ณด์œ ํ•ฉ๋‹ˆ๋‹ค.
  2. Classroom ๋‹ด๋‹น์ž๋Š” ํด๋ž˜์Šค ์ƒ์„ฑ ์‹œ ๊ฐ™์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ FundingTicketPolicy.requireUsableBy(userId, ticketId)๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
  3. ์ •์ฑ…์€ ์†Œ์œ ์ž ์ผ์น˜, ACTIVE, ํ˜„์žฌ ์‹œ๊ฐ์ด expiresAt ์ด์ „์ธ์ง€ ๊ฒ€์‚ฌํ•˜๊ณ  FundingTicketAccess(capacity, expiresAt)์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
  4. Classroom์€ ์ž์ฒด Entity์— ticketId๋ฅผ ๋น„๊ณ ์œ  FK๋กœ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์ด์šฉ๊ถŒ ํ•˜๋‚˜๋กœ ๋ณต์ˆ˜ ํด๋ž˜์Šค๋ฅผ ํ—ˆ์šฉํ•˜๋ฏ€๋กœ unique ์ œ์•ฝ์€ ๋‘์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  5. Funding์€ Classroom์˜ ํ…Œ์ด๋ธ”/์ƒํƒœ/๋ฉค๋ฒ„์‹ญ์„ ์ง์ ‘ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ™˜๋ถˆ ์ดํ›„ ๊ธฐ์กด ํด๋ž˜์Šค์—์„œ ์“ฐ๊ธฐ๋ฅผ ๋ง‰๋Š” ๋™์ž‘์€ ๋ณ„๋„ Class ๋‹ด๋‹น์ž๊ฐ€ Funding ์ƒํƒœ๋ฅผ ์žฌ๊ฒ€์ฆํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฒˆ ๋ฒ”์œ„์—์„œ ํด๋ž˜์Šค ์ƒ์„ฑ API, ํด๋ž˜์Šค CRUD, ์ž…์žฅ/๋ฉค๋ฒ„/ํˆฌํ‘œ/๋Œ“๊ธ€, ๋ฐฐํ‹€ ์นดํƒˆ๋กœ๊ทธ, ์š”์•ฝยท๋ฆฌํฌํŠธ API์™€ ๊ด€๋ จ Entity/Service/Repository๋ฅผ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. AI ๊ธฐ๋Šฅ, AI API, AI ํ…Œ์ด๋ธ”, Provider Client์™€ Worker๋„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


7. ์˜ˆ์™ธ ์ฒ˜๋ฆฌ

์กฐ๊ฑด HTTP ErrorCode ์ œ์•ˆ ํ™”๋ฉด/์ฒ˜๋ฆฌ
์ฝ”๋“œ ๋ฌธ์ž์—ด ๋ˆ„๋ฝ, ํ˜•์‹ ์˜ค๋ฅ˜, ๋ฏธ๋ฐœ๊ธ‰ ์ฝ”๋“œ 422 TICKET_CODE_INVALID โ€œ์ฝ”๋“œ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์•„์š”. ์ž…๋ ฅํ•œ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ํ™•์ธํ•ด ์ฃผ์„ธ์š”.โ€, ์ž…๋ ฅ ์œ ์ง€
์ฝ”๋“œ ๋“ฑ๋ก๊ธฐํ•œ ๊ฒฝ๊ณผ 410 TICKET_CODE_EXPIRED ๋“ฑ๋ก ๊ธฐํ•œ ์•ˆ๋‚ด
๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๊ฐ€ ๋จผ์ € ๋“ฑ๋กํ–ˆ๊ฑฐ๋‚˜ ์‚ฌ์šฉ ๋ถˆ๊ฐ€ 409 TICKET_CODE_UNAVAILABLE ๊ณ„์ •/์†Œ์œ ์ž ์ •๋ณด ๋ฏธ๋…ธ์ถœ
์ฝ”๋“œ๊ฐ€ ์šด์˜์ž์— ์˜ํ•ด ์ทจ์†Œ๋จ 409 TICKET_CODE_REVOKED ๊ด€๋ฆฌ์ž ๋ฌธ์˜ ์•ˆ๋‚ด
์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฏธ ํ™œ์„ฑ ์ด์šฉ๊ถŒ์„ ๋ณด์œ  409 FUNDING_TICKET_ALREADY_ACTIVE ๊ธฐ์กด ์ด์šฉ๊ถŒ ์•ˆ๋‚ด
๊ฒฐ์ œ ๋ฏธํ™•์ •ยท์ทจ์†Œยทํ™˜๋ถˆ 409 FUNDING_NOT_PAYABLE ๊ด€๋ฆฌ์ž ํ™•์ธ ์•ˆ๋‚ด
์ทจ์†Œ๋œ ์ด์šฉ๊ถŒ์„ Classroom์—์„œ ์‚ฌ์šฉ 409 FUNDING_TICKET_REVOKED ํด๋ž˜์Šค ์ƒ์„ฑ ๋ถˆ๊ฐ€ ์•ˆ๋‚ด
๋งŒ๋ฃŒ/๋ฏธ๋“ฑ๋ก/๋‹ค๋ฅธ ์‚ฌ๋žŒ ์†Œ์œ  ์ด์šฉ๊ถŒ์„ Classroom์—์„œ ์‚ฌ์šฉ 403/409 FUNDING_TICKET_FORBIDDEN / FUNDING_TICKET_NOT_ACTIVE ์†Œ์œ ์žยท์ด์šฉ ๊ธฐ๊ฐ„์„ ํ™•์ธ
์ค‘๋ณต ์ฃผ๋ฌธ ๋˜๋Š” ์ค‘๋ณต ์บ ํŽ˜์ธ 409 FUNDING_ORDER_DUPLICATE / FUNDING_CAMPAIGN_DUPLICATE ์ฃผ๋ฌธ ํ‚ค ํ™•์ธ ํ›„ ๊ธฐ์กด ์ฃผ๋ฌธ ์กฐํšŒ
ํ•„์ˆ˜ ํ•„๋“œ ๋ˆ„๋ฝ/ํ˜•์‹ ์˜ค๋ฅ˜, ์ง€์›ํ•˜์ง€ ์•Š๋Š” ์ •์›ยท์ˆ˜๋Ÿ‰ยท์—ฐ๋ฝ์ฒ˜ 400 FUNDING_INVALID_REQUEST / FUNDING_REWARD_UNSUPPORTED / FUNDING_QUANTITY_INVALID / FUNDING_CONTACT_INVALID ๊ด€๋ฆฌ์ž ์ž…๋ ฅ๊ฐ’ ๊ต์ •
์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ฃผ๋ฌธ, ์ด์šฉ๊ถŒ, ์ „๋‹ฌ ๊ธฐ๋ก 404 FUNDING_ORDER_NOT_FOUND / FUNDING_TICKET_NOT_FOUND / FUNDING_DELIVERY_NOT_FOUND ์šด์˜์ž ๊ฒ€์ƒ‰ ์กฐ๊ฑด ํ™•์ธ
์ด๋ฏธ ์ฝ”๋“œ๊ฐ€ ๋ฐœ๊ธ‰๋˜์—ˆ๊ฑฐ๋‚˜ ์žฌ๋ฐœ๊ธ‰ ์กฐ๊ฑด ์œ„๋ฐ˜ 409 TICKET_CODE_ALREADY_ISSUED / FUNDING_REISSUE_NOT_ALLOWED ๊ธฐ์กด ์ฝ”๋“œ ์ƒํƒœ ํ™•์ธ
ํ™˜๋ถˆ ์™ธ๋ถ€ ํ™•์ธ ๋ˆ„๋ฝ ๋˜๋Š” ์ฃผ๋ฌธ ํ™˜๋ถˆ ๋ถˆ๊ฐ€ 409 FUNDING_REFUND_NOT_CONFIRMED ์™ธ๋ถ€ ํ”Œ๋žซํผ ํ™˜๋ถˆ ์ฆ๋น™ ํ™•์ธ
์ „๋‹ฌ ์ƒํƒœ๊ฐ€ ์ž˜๋ชป๋˜์—ˆ๊ฑฐ๋‚˜ ์‹คํŒจ ์‚ฌ์œ  ๋ˆ„๋ฝ 400 FUNDING_INVALID_DELIVERY_STATUS / COMMON_400 ์ „๋‹ฌ ๊ฒฐ๊ณผ์™€ ์‹คํŒจ ์‚ฌ์œ  ์ž…๋ ฅ
๋“ฑ๋ก/๊ฒ€์ƒ‰ ๋‚ ์งœ ๋ฒ”์œ„๊ฐ€ ์—ญ์ „๋จ 400 FUNDING_INVALID_DATE_RANGE ์‹œ์ž‘์ผยท์ข…๋ฃŒ์ผ ์ˆ˜์ •
๊ด€๋ฆฌ์ž API ์ธ์ฆ/๊ถŒํ•œ ์‹คํŒจ 401/403 AUTH_UNAUTHORIZED / AUTH_FORBIDDEN ๋กœ๊ทธ์ธ ๋˜๋Š” ๊ด€๋ฆฌ์ž ๊ถŒํ•œ ํ™•์ธ
์—ฐ๋ฝ์ฒ˜ ์•”ํ˜ธํ™” ํ‚ค ์„ค์ • ๋ˆ„๋ฝ/์˜ค๋ฅ˜ 500 FUNDING_ENCRYPTION_NOT_CONFIGURED / FUNDING_ENCRYPTION_FAILED ์šด์˜ ์„ค์ • ์ ๊ฒ€, ์‘๋‹ต์—์„œ ํ‚ค/์›๋ฌธ ๋ฏธ๋…ธ์ถœ
๋„คํŠธ์›Œํฌ ๋Š๊น€ ์„œ๋ฒ„ ์‘๋‹ต ์—†์Œ ์•ฑ ๋กœ์ปฌ NETWORK_ERROR ์ž…๋ ฅ ๋ณด์กด, ์žฌ์กฐํšŒ ํ›„ ์žฌ์‹œ๋„

Funding ์—…๋ฌด ์˜ˆ์™ธ๋Š” ErrorCode์— ๊ฐ๊ฐ ์ถ”๊ฐ€ํ•˜๋ฉฐ, ๊ณตํ†ต Bean Validation ์‹คํŒจ๋Š” ๊ธฐ์กด COMMON_INVALID_PARAMETER ํ˜•์‹์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์ค‘๋ณต ์ฃผ๋ฌธ/์บ ํŽ˜์ธ DB ์ œ์•ฝ์€ GlobalExceptionHandler์—์„œ Funding ์ถฉ๋Œ ์ฝ”๋“œ๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค. Classroom ๊ณ„์•ฝ์€ Funding์˜ ticket ์˜ค๋ฅ˜๋ฅผ ๊ทธ๋Œ€๋กœ ์ „๋‹ฌํ•˜๋ฉฐ ์ž์ฒด ErrorCode๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. AI ์˜ค๋ฅ˜๋Š” ๊ตฌํ˜„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. HTTP status๋Š” ์ „์†ก ์ˆ˜์ค€, ErrorCode๋Š” ์•ฑ/๊ด€๋ฆฌ์ž ํ™”๋ฉด ๋ถ„๊ธฐ ์ˆ˜์ค€์ž…๋‹ˆ๋‹ค.


8. ์ด์šฉ๊ถŒ ๊ธฐ๋Šฅ ์ƒ์„ธ ์„ค๊ณ„

์ƒํ’ˆ/๊ธฐ๊ฐ„

์ƒํ’ˆ ๊ฐ€๊ฒฉ ํด๋ž˜์Šค๋ณ„ ์ •์›
5์ธ 9,900์› ์ตœ๋Œ€ 5๋ช…
15์ธ 19,900์› ์ตœ๋Œ€ 15๋ช…
30์ธ 29,900์› ์ตœ๋Œ€ 30๋ช…
  • ํŽ€๋”ฉ ๊ฒฐ์ œ ํ™•์ • ํ›„ 1๋…„ ์ด๋‚ด ์ฝ”๋“œ ๋“ฑ๋ก.
  • ๋“ฑ๋ก ํ™•์ธ ์„ฑ๊ณต ์‹œ 6๊ฐœ์›” ํ™œ์„ฑํ™”.
  • ํ™œ์„ฑ ์ด์šฉ๊ถŒ ํ•˜๋‚˜๋กœ ํด๋ž˜์Šค ์ˆ˜ ์ œํ•œ ์—†์ด ์ƒ์„ฑ.
  • ์ƒํ’ˆ ์ •์›์€ ํด๋ž˜์Šค๋ณ„๋กœ ์žฌ์ ์šฉ๋˜๋ฉฐ ์ขŒ์„์€ ์ด์šฉ๊ถŒ ์ „์ฒด์—์„œ ์ฐจ๊ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์ธ์•ฑ๊ฒฐ์ œ, ๊ตฌ๋งค ๋ณต์›, ์•ฑ ๊ฒฐ์ œ SDK๋Š” ๊ตฌํ˜„ ๋ฒ”์œ„๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.
  • ์›”/์ฃผ๋ณ„ ์ƒ์„ฑ ์ œํ•œ์„ ๋‘์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์ฝ”๋“œ ์ „๋‹ฌ๊ณผ ์ฝ”๋“œ ๋“ฑ๋ก์€ ๋ณ„๋„ ์ƒํƒœ์ž…๋‹ˆ๋‹ค.

์ฝ”๋“œ ์ข…๋ฅ˜

์ข…๋ฅ˜ ์šฉ๋„ ์ •์ฑ…
TicketCode ์œ ๋ฃŒ ํŽ€๋”ฉ ๋ฆฌ์›Œ๋“œ๋ฅผ ๊ณ„์ • ์ด์šฉ๊ถŒ์œผ๋กœ ์—ฐ๊ฒฐ ์ถฉ๋ถ„ํ•œ ๋‚œ์ˆ˜, ํ•ด์‹œ ์ €์žฅ, ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž๋งŒ ๋“ฑ๋ก
ํด๋ž˜์Šค ์ฐธ์—ฌ ์ฝ”๋“œ(ParticipationCode)๋Š” ๋ณ„๋„ Classroom ๋‹ด๋‹น ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค. Funding์€ TicketCode๋งŒ ๋ฐœ๊ธ‰ยท์กฐํšŒยท๋“ฑ๋กํ•˜๋ฉฐ ์ฐธ์—ฌ ์ฝ”๋“œ API/Entity๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ด€๋ฆฌ์ž ์ˆ˜๋™ ๋ฐœ๊ธ‰ MVP

  1. ๊ด€๋ฆฌ์ž๊ฐ€ ๊ณต์‹ ํŽ€๋”ฉ ๋ช…๋‹จ์„ ๋Œ€์กฐํ•ด ๊ตฌ๋งค ์ฃผ๋ฌธ๊ณผ ๊ฒฐ์ œ ํ™•์ • ์—ฌ๋ถ€๋ฅผ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.
  2. ์ƒํ’ˆ ๋ฆฌ์›Œ๋“œ ID๋ฅผ ์ •์› 5/15/30์œผ๋กœ ๋งคํ•‘ํ•ฉ๋‹ˆ๋‹ค.
  3. ADMIN์ด ์ด์šฉ๊ถŒ๊ณผ ๋“ฑ๋ก ์ฝ”๋“œ๋ฅผ ๋ฐœ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.
  4. ๊ด€๋ฆฌ์ž ํ™”๋ฉด์—์„œ ๋ฐœ๊ธ‰ ์ฝ”๋“œ๋ฅผ ์ผํšŒ ํ™•์ธํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ์ˆ˜๋™ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜, ์ „๋‹ฌ ์ฑ„๋„/์™„๋ฃŒ ์ƒํƒœ๋งŒ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.
  5. ๊ฒฐ์ œ ์‹คํŒจยท์ทจ์†Œยทํ™˜๋ถˆ์€ ๋ฐœ๊ธ‰ ๋ณด๋ฅ˜ ๋˜๋Š” ํ๊ธฐํ•ฉ๋‹ˆ๋‹ค.
  6. ๋ฏธ์‚ฌ์šฉ ์ฝ”๋“œ ์žฌ๋ฐœ๊ธ‰์€ ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ํ๊ธฐํ•˜๊ณ  registerBy๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฏธ ๋“ฑ๋ก๋œ ์ด์šฉ๊ถŒ์€ ์ฝ”๋“œ ์žฌ๋ฐœ๊ธ‰ ๋Œ€์‹  ๊ณ„์ • ๋ณต๊ตฌ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

์ƒํƒœ

  • FundingOrder: RESERVED โ†’ PAYMENT_PENDING โ†’ PAID_CONFIRMED ๋˜๋Š” PAYMENT_FAILED/CANCELED/REFUNDED
  • Ticket: UNREGISTERED โ†’ ACTIVE โ†’ EXPIRED, ๋ณ„๋„ REGISTER_EXPIRED/REVOKED
  • TicketCode: ISSUED โ†’ DELIVERED โ†’ CLAIMED, ๋ณ„๋„ REVOKED
  • ์ฝ”๋“œ ๋ฐœ๊ธ‰ ๋˜๋Š” ์ „๋‹ฌ๋งŒ์œผ๋กœ ์ด์šฉ ๊ธฐ๊ฐ„์„ ์‹œ์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ํ™˜๋ถˆ ์š”์ฒญ๊ณผ ํ™˜๋ถˆ ํ™•์ •์„ ๊ตฌ๋ถ„ํ•˜๊ณ  ํ™•์ •๋œ ํ™˜๋ถˆ๋งŒ REVOKED ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ๋งŒ๋ฃŒ ํ›„ 30์ผ ๊ฒฐ๊ณผ ์ฝ๊ธฐ ์œ ์˜ˆ์™€ ์ดํ›„ ์‚ญ์ œ๋Š” PRD ๊ตฌํ˜„ ๊ธฐ๋ณธ์•ˆ์ด๋ฉฐ ๋ณด๊ด€ ์ •์ฑ… ์Šน์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

9. ์ด์šฉ๊ถŒ ํ™”๋ฉด ๋ถ„๊ธฐ

GET /api/v1/tickets/me ์‘๋‹ต ์˜ˆ์‹œ:

{
  "statusCode": 200,
  "data": {
    "state": "ACTIVE",
    "ticketId": 4102,
    "capacity": 30,
    "activatedAt": "2026-10-15T03:00:00Z",
    "expiresAt": "2027-04-15T03:00:00Z",
  }
}
์‘๋‹ต ์ƒํƒœ ์•ฑ ํ™”๋ฉด
NONE ์ด์šฉ๊ถŒ ์ฝ”๋“œ ๋“ฑ๋ก ์•ˆ๋‚ด
ACTIVE ํด๋ž˜์Šค ์ด์šฉ๊ถŒ ์ƒ์„ธ, ํด๋ž˜์Šค ์ƒ์„ฑ ์ง„์ž…
EXPIRED ์ข…๋ฃŒ์ผยท์ฝ๊ธฐ ์œ ์˜ˆ ์ •์ฑ… ํ‘œ์‹œ, ์‹ ๊ทœ ์ƒ์„ฑ/ํ™œ๋™ ์ž ๊ธˆ
REVOKED ํ™˜๋ถˆ/์ทจ์†Œ ๊ด€๋ จ ๋ฌธ์˜ ์•ˆ๋‚ด, ์‹ ๊ทœ ํ™œ๋™ ์ž ๊ธˆ

UNREGISTERED๋Š” ์•„์ง ๊ณ„์ •์— claim๋˜์ง€ ์•Š์€ ํŽ€๋”ฉ ์ฃผ๋ฌธ ์ƒํƒœ์ด๋ฏ€๋กœ ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ด€๋ฆฌ์ž ํ™”๋ฉด์—๋งŒ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ๋“ฑ๋ก ์ฝ”๋“œ๊ฐ€ ๊ณ„์ •์— ์‚ฌ์ „ ์—ฐ๊ฒฐ๋˜๋Š” ์ •์ฑ…์„ ์ฑ„ํƒํ•˜๋ฉด ์ด ๋ถ„๊ธฐ๋ฅผ ํ™•์žฅํ•ฉ๋‹ˆ๋‹ค. โ€œ์ด์šฉ๊ถŒ ์ถ”๊ฐ€๋“ฑ๋กํ•˜๊ธฐโ€ UI์™€ PRD์˜ ์บ ํŽ˜์ธ๋ณ„ 1์ธ 1๊ฐœ ์ œํ•œ ๊ฐ„ ์˜๋ฏธ๋Š” ์•ฑ/๊ธฐํš ํ™•์ธ ํ•ญ๋ชฉ์ž…๋‹ˆ๋‹ค.


10. ํ…€๋ธ”๋ฒ… ์—ฐ๋™ ๋ฐฉ์•ˆ ์กฐ์‚ฌ

ํ™•์ธ์ผ์€ 2026-10-15์ž…๋‹ˆ๋‹ค. ํ…€๋ธ”๋ฒ… ๊ณต์‹ ๋„์›€๋ง์—์„œ ์ฐฝ์ž‘์ž๋Š” ํ›„์›์ž ๊ด€๋ฆฌ์˜ ๋ฐ์ดํ„ฐ๋ฅผ Excel๋กœ ๋ฉ”์ผ ๋ฐœ์†ก ๋ฐ›์„ ์ˆ˜ ์žˆ๊ณ , ๋””์ง€ํ„ธ ์„ ๋ฌผ ์ „๋‹ฌ์—์„œ๋Š” ํ…œํ”Œ๋ฆฟ์— ํ›„์›๋ฒˆํ˜ธ๋ฅผ ์ ์€ xlsx ์—…๋กœ๋“œ๊ฐ€ ๊ฐ€๋Šฅํ•œ ๊ฒƒ์„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ณต์‹ ๊ณต๊ฐœ ์ž๋ฃŒ์—์„œ ์ฐฝ์ž‘์ž์šฉ ํ›„์›์ž/๊ฒฐ์ œ ์กฐํšŒ API์˜ endpoint, ์ธ์ฆ ๋ฐฉ์‹, webhook, rate limit์€ ํ™•์ธ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ API ์ œ๊ณต์„ ๋‹จ์ •ํ•˜์ง€ ์•Š๊ณ , ํ…€๋ธ”๋ฒ… ์ง€์›/๊ณ„์•ฝ์„ ํ†ตํ•ด API ์ด์šฉ ๊ฐ€๋Šฅ์„ฑ๊ณผ ๋ฒ”์œ„๋ฅผ ๋ณ„๋„ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฐฉ์‹ ํ˜„์žฌ ๊ฒฐ์ • ์šด์˜ ๋ฐฉ์‹
ํ…€๋ธ”๋ฒ… API ๋ณด๋ฅ˜ ๊ณต์‹ ๊ณต๊ฐœ ์ž๋ฃŒ์—์„œ ์ฐฝ์ž‘์ž ํ›„์›ยท๊ฒฐ์ œ ์กฐํšŒ API๋ฅผ ํ™•์ธํ•˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ์ ‘๊ทผ ๊ถŒํ•œ๊ณผ ๋ฐ์ดํ„ฐ ๋ฒ”์œ„๋ฅผ ๊ณต์‹ ์ œํœด ๋ฌธ์˜๋กœ ํ™•์ธํ•˜๊ธฐ ์ „์—๋Š” ์—ฐ๋™์„ ์ „์ œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๋ช…๋‹จ Excel ์‚ฌ๋žŒ ๊ฒ€ํ†  + ์„œ๋ฒ„ ํŒŒ์‹ฑ ์šด์˜์ž๊ฐ€ ํ…€๋ธ”๋ฒ…์—์„œ ์ง์ ‘ ์š”์ฒญยท๋‹ค์šด๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. ๊ด€๋ฆฌ์ž๋Š” ๋ฆฌ์›Œ๋“œ ์‹œํŠธ๋งŒ ์„ ํƒํ•˜๊ณ  ์„œ๋ฒ„๊ฐ€ ํ—ค๋” ํ–‰๊ณผ ํ™”๋ฉด์˜ 9๊ฐœ ์—ด์„ ์ž๋™ ํŒ๋ณ„ํ•ฉ๋‹ˆ๋‹ค. ๋ฏธ๋ฆฌ๋ณด๊ธฐ์—์„œ ๊ฒฐ์ œ ์ƒํƒœยท์ค‘๋ณตยท์ˆ˜๋Ÿ‰์„ ๊ฒ€ํ† ํ•ฉ๋‹ˆ๋‹ค.
ํ”ฝ์ผ€ ์ฃผ๋ฌธ ๋“ฑ๋กยท๋ฐœ๊ธ‰ ์„œ๋ฒ„ ์ฒ˜๋ฆฌ, ๊ด€๋ฆฌ์ž ์Šน์ธ ํ™•์ • ์ž‘์—…์—์„œ ์œ ํšจ ํ–‰๋งŒ ์ฃผ๋ฌธยทํ‹ฐ์ผ“ยท์ฝ”๋“œ๋กœ ์ƒ์„ฑํ•˜๊ณ , ํ›„์›๋ฒˆํ˜ธ์™€ ์ฝ”๋“œ ํ…์ŠคํŠธ๋ฅผ ์—ฐ๊ฒฐํ•œ XLSX๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์›๋ฌธ ์ฝ”๋“œ๋Š” DB์— ์ €์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
ํ…€๋ธ”๋ฒ… ์ „๋‹ฌยท์ƒํƒœ ๋™๊ธฐํ™” ์‚ฌ๋žŒ ์ฒ˜๋ฆฌ ์šด์˜์ž๊ฐ€ ํ…€๋ธ”๋ฒ… ๋””์ง€ํ„ธ ์„ ๋ฌผ ๊ด€๋ฆฌ์— ํ…์ŠคํŠธ ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•˜๊ณ , ์—…๋กœ๋“œ ๊ฒฐ๊ณผ๋ฅผ ์„œ๋ฒ„์— ํ›„์›๋ฒˆํ˜ธ ๋ชฉ๋ก์œผ๋กœ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ์‹ค์‹œ๊ฐ„ API ๋™๊ธฐํ™”๋Š” ์—†์Šต๋‹ˆ๋‹ค.

ํ˜„์žฌ ์šด์˜ ํ๋ฆ„์€ ํ…€๋ธ”๋ฒ… Excel ๋‹ค์šด๋กœ๋“œ โ†’ ์„œ๋ฒ„ ์‹œํŠธ ์„ ํƒยท์—ด ์ž๋™ ํŒ๋ณ„ ๋ฐ ๋ฏธ๋ฆฌ๋ณด๊ธฐ โ†’ ๊ด€๋ฆฌ์ž ํ™•์ธ โ†’ ์œ ํšจ ํ›„์› ํ–‰ ์ €์žฅยท๊ฒฐ์ œ ์™„๋ฃŒ ํ–‰ ์ฝ”๋“œ ๋ฐœ๊ธ‰ ๋ฐ ํ…€๋ธ”๋ฒ… ์—…๋กœ๋“œ ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ โ†’ ํ…€๋ธ”๋ฒ… ๋””์ง€ํ„ธ ์„ ๋ฌผ ์—…๋กœ๋“œ โ†’ ์„œ๋ฒ„์— ์ „๋‹ฌ ๊ฒฐ๊ณผ ๊ธฐ๋ก์ž…๋‹ˆ๋‹ค. ํ”Œ๋žซํผ๊ณผ ์„œ๋ฒ„ ์‚ฌ์ด์˜ API ์ž๋™ ๋™๊ธฐํ™”๋Š” ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ฃผ์˜: ๊ณต์‹ ๋„์›€๋ง์˜ ๋””์ง€ํ„ธ ์„ ๋ฌผ Excel ๊ธฐ๋Šฅ์€ ํ…€๋ธ”๋ฒ… ๋‚ด๋ถ€์—์„œ ์„ ๋ฌผ์„ ์ „๋‹ฌํ•˜๋Š” ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ํ”ฝ์ผ€ ์ž์ฒด ๊ตฌ๋งค์ž/์ฝ”๋“œ DB์™€ ์ž๋™ ๋™๊ธฐํ™”๋˜๋Š” API๋กœ ์ทจ๊ธ‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


11. ๊ด€๋ฆฌ์ž ๋Œ€์‹œ๋ณด๋“œ ์„ค๊ณ„

ํ™”๋ฉด์—์„œ ํ™•์ธ๋œ ๊ธฐ๋Šฅ

๊ธฐ๋Šฅ ํ™•์ธ ๊ฒฐ๊ณผ
ํด๋ž˜์Šค ๋ชฉ๋ก/๊ฒ€์ƒ‰/์ƒํƒœยท์ƒํ’ˆยท๋ฐฐํ‹€ ์œ ํ˜• ํ•„ํ„ฐ ์žˆ์Œ (๋ณ„๋„ Classroom ๊ตฌํ˜„ ๋ฒ”์œ„)
ํด๋ž˜์Šค ์šด์˜ ์ง€ํ‘œ ์นด๋“œ ์žˆ์Œ (๋ณ„๋„ Classroom ๊ตฌํ˜„ ๋ฒ”์œ„)
ํด๋ž˜์Šค CSV ๋‚ด๋ณด๋‚ด๊ธฐ ์žˆ์Œ (๋ณ„๋„ Classroom ๊ตฌํ˜„ ๋ฒ”์œ„)
์ด์šฉ๊ถŒ/๋“ฑ๋ก์ž ๋ชฉ๋กยท์ƒํƒœ ์นด๋“œ ์žˆ์Œ
์ด์šฉ๊ถŒ ์ฝ”๋“œ ๋ฐœ๊ธ‰ ์žˆ์Œ
ํŽ€๋”ฉ ๊ตฌ๋งค์ž ๋“ฑ๋ก/๊ฒ€์ƒ‰ ์žˆ์Œ
๊ตฌ๋งค์ž ์—ฐ๋ฝ์ฒ˜ยท์ฃผ๋ฌธยท์ƒํ’ˆยท์ „๋‹ฌ ์ƒํƒœ ์žˆ์Œ
ํด๋ž˜์Šค ์ƒ์„ธ์™€ ๊ธฐ๋ณธ ์ •๋ณด/๋ฉค๋ฒ„ยท์ฐธ์—ฌ/๊ฒฐ๊ณผยทAI/๋ณ€๊ฒฝ ์ด๋ ฅ ํƒญ ์žˆ์Œ (๋ณ„๋„ Classroom/AI ๋ฒ”์œ„)
๋ณ„๋„ ์‚ฌ์šฉ์ž ์ „์ฒด ๋ชฉ๋ก ํ™”๋ฉด ์ฒจ๋ถ€ ์ด๋ฏธ์ง€์—๋Š” ์—†์Œ
์ฝ”๋“œ ์ƒ์„ธ ํ™”๋ฉด/์ˆ˜์ •/๋น„ํ™œ์„ฑ UI ๋ณ„๋„ ์ด๋ฏธ์ง€์— ์—†์Œ
ํ…€๋ธ”๋ฒ… Excel ์ฒ˜๋ฆฌ ๋ฐฑ์—”๋“œ API ์žˆ์Œ, ์ฒจ๋ถ€ ์‹œ์•ˆ์—๋Š” UI ์—†์Œ
๊ตฌ๋งค์ž ํŽธ์ง‘/์‚ญ์ œ ์—†์Œ
์ฝ”๋“œ ์žฌ๋ฐœ๊ธ‰ ๋ฒ„ํŠผ ์—†์Œ
์‚ฌ์šฉ์ž ์„œ๋น„์Šค ๋‚ด๋ถ€ ADMIN ๋กœ๊ทธ์ธ ํ™”๋ฉด ์—†์Œ; ํ—ค๋”๋งŒ ํ‘œ์‹œ

ํ™”๋ฉด์— ์—†๋Š” ์šด์˜ ์š”๊ตฌ๋Š” ๊ธฐ๋ณธ CRUD๋กœ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฒฐ์ œ ํ™˜๋ถˆ/์žฌ๋ฐœ๊ธ‰/๋ช…๋‹จ ์žฌ์ฒ˜๋ฆฌ๊ฐ€ ๊ผญ ํ•„์š”ํ•˜๋ฉด API๋Š” ์„ค๊ณ„์— ํ‘œ์‹œํ•˜๋˜ UI์— ์šด์˜์ƒ ํ•„์š” ๊ฐ€๋Šฅ์„ฑ ์žˆ์Œ - ์ถ”๊ฐ€ ๋…ผ์˜ ํ•„์š”๋กœ ๋‘ก๋‹ˆ๋‹ค.

์œ„ ํ‘œ์˜ ํด๋ž˜์Šค ํ™”๋ฉด์€ UI ๋ถ„์„ ๊ฒฐ๊ณผ์ด๋ฉฐ ์ด๋ฒˆ Funding ๊ธฐ๋Šฅ์—์„œ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ๊ด€๋ฆฌ์ž ๊ตฌํ˜„์€ ์ด์šฉ๊ถŒ/๋“ฑ๋ก์ž ๋ชฉ๋ก, ๊ตฌ๋งค์ž ๋“ฑ๋กยท๊ฒ€์ƒ‰, ์ฝ”๋“œ ๋ฐœ๊ธ‰ ๋ฐ ์ „๋‹ฌ ์ƒํƒœ์— ํ•œ์ •ํ•ฉ๋‹ˆ๋‹ค.

๊ด€๋ฆฌ์ž ๋ชฉ๋ก ์ฒ˜๋ฆฌ ๊ธฐ์ค€

  • server-side paging/filtering ๊ถŒ์žฅ. ์š”์ฒญ์€ page=0, size ๊ธฐ๋ณธ 20, sort๋Š” allowlist.
  • ํด๋ž˜์Šค ๊ฒ€์ƒ‰: name ๋˜๋Š” owner display name/tag, status, capacity, LIBRARY/CUSTOM.
  • ์ด์šฉ๊ถŒ ๊ฒ€์ƒ‰: code ์ผ๋ถ€/๊ตฌ๋งค์ž/๋“ฑ๋ก์ž, capacity, ticket ์ƒํƒœ, registered date range.
  • ํŽ€๋”ฉ ๊ตฌ๋งค์ž ๊ฒ€์ƒ‰: ์ด๋ฆ„ ๋ฐ ์—ฐ๋ฝ์ฒ˜๋Š” ์•”ํ˜ธํ™”/๊ฒ€์ƒ‰์šฉ ๋ณ„๋„ ์„ค๊ณ„๋ฅผ ๊ฑฐ์นœ ๋’ค ์ตœ์†Œ ํ•„๋“œ๋งŒ ๊ฒ€์ƒ‰.
  • ๋‚ ์งœ ๋ฒ”์œ„๋Š” Asia/Seoul ์ž…๋ ฅ, ์„œ๋ฒ„ UTC ์ €์žฅ. ์กฐํšŒ ๋ฒ”์œ„ ์ข…๋ฃŒ์ผ์€ ํ™”๋ฉด๊ณผ ๋ฐฑ์—”๋“œ์—์„œ inclusive/exclusive ์ค‘ ํ•˜๋‚˜๋กœ ํ•ฉ์˜.
  • CSV๋Š” ADMIN๋งŒ ๋‹ค์šด๋กœ๋“œ, ํ˜„์žฌ ๊ฒ€์ƒ‰ ํ•„ํ„ฐ์™€ ๋™์ผํ•œ ์กฐ๊ฑด ์ ์šฉ, PII ์ตœ์†Œํ™”/๋งˆ์Šคํ‚น.
  • ์ฝ”๋“œ ์›๋ฌธ์€ ๋ชฉ๋ก์—์„œ ๊ธฐ๋ณธ ๋งˆ์Šคํ‚นํ•˜๊ณ  ๋ฐœ๊ธ‰ ๋•Œ๋งŒ ํ…€๋ธ”๋ฒ… ์—…๋กœ๋“œ์šฉ ๋‹ค์šด๋กœ๋“œ ํŒŒ์ผ์— ๋‹ด์Šต๋‹ˆ๋‹ค. ํŒŒ์ผ ์‘๋‹ต์€ ์บ์‹œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ™”๋ฉด์—์„œ ๊ฐœ๋ณ„ ์ฝ”๋“œ ๋ฐœ๊ธ‰ ์‹œ์—๋Š” ์‘๋‹ต์— ํ•œ ๋ฒˆ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

12. ๊ด€๋ฆฌ์ž API

๊ด€๋ฆฌ์ž ํ™”๋ฉด ๊ตฌํ˜„์— ํ•„์š”ํ•œ API๋Š” ยง4์˜ [์‹ ๊ทœ ์ œ์•ˆ] endpoint๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

ํ™”๋ฉด ํ•„์š”ํ•œ API ๊ฒ€์ƒ‰/ํŽ˜์ด์ง€ ์กฐ๊ฑด
์ด์šฉ๊ถŒยท๋“ฑ๋ก์ž GET /admin/tickets, POST /admin/tickets/{ticketId}/codes keyword, capacity, status, registeredFrom, registeredTo, page, size
ํŽ€๋”ฉ ๊ตฌ๋งค์ž GET/POST /admin/funding-orders, Tumblbug inspect/preview/digital-gifts, PATCH ์ „๋‹ฌ ๊ฒฐ๊ณผ keyword, capacity, deliveryStatus, claimStatus, page, size
ํ™˜๋ถˆยท์žฌ๋ฐœ๊ธ‰ ์šด์˜ POST /admin/tickets/{ticketId}/refund, POST /admin/tickets/{ticketId}/reissue reason ํ•„์ˆ˜, ์™ธ๋ถ€ ํ™•์ธ ๊ธฐ๋ก

๋ชจ๋“  ์‹ค์ œ URL์€ /api/v1 ์ ‘๋‘์–ด๋ฅผ ๋ถ™์ž…๋‹ˆ๋‹ค. ๊ด€๋ฆฌ์ž ํ™”๋ฉด ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ์˜ ๊ตฌ๋งค์ž ์—ฐ๋ฝ์ฒ˜๋Š” ์ „์ฒด๊ฐ’์„ ๊ธฐ๋ณธ ์‘๋‹ต์— ๋‹ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ด€๋ฆฌ์ž ํด๋ž˜์Šค ๋ชฉ๋ก/์ƒ์„ธ/CSV API๋Š” ๋ณ„๋„ Classroom ๋‹ด๋‹น ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค.


13. ๊ด€๋ฆฌ์ž ์ธ์ฆ/์ธ๊ฐ€

  • ํ˜„์žฌ UserRole์— ADMIN์ด ์žˆ๊ณ  SecurityConfig์—์„œ /api/v1/admin/**๋Š” hasRole("ADMIN")์ž…๋‹ˆ๋‹ค.
  • ์‹ ๊ทœ ๊ด€๋ฆฌ์ž API๋„ ํ•ด๋‹น prefix์— ๋†“๊ณ  ๋ฉ”์„œ๋“œ ๋‹จ์œ„ @PreAuthorize("hasRole('ADMIN')")๋ฅผ ๋ณ‘ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ์ผ๋ฐ˜ ๋กœ๊ทธ์ธ API๋Š” ๊ธฐ์กด OAuth/JWT๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. AdminPickeController์˜ GET /api/v1/admin/login์€ ํ˜„์žฌ ์™ธ๋ถ€ admin-web ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ redirectํ•˜๋Š” ๊ฒฝ๋กœ์ด๋ฉฐ, ๋ฐฑ์—”๋“œ ๋กœ๊ทธ์ธ API๋กœ ํ‘œ์‹œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ํด๋ž˜์Šค ์šด์˜์ž๋Š” ์„œ๋น„์Šค ๋‚ด ํด๋ž˜์Šค owner ๊ถŒํ•œ์œผ๋กœ ๋ณธ์ธ ํด๋ž˜์Šค๋งŒ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ROLE_ADMIN์ด ํด๋ž˜์Šค ์†Œ์œ  ๊ถŒํ•œ์„ ๋Œ€์ฒดํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๊ฐœ์ธ์ •๋ณด ์‘๋‹ต์€ ๊ด€๋ฆฌ์ž์—์„œ๋„ ํ•„์š”ํ•œ ์ปฌ๋Ÿผ๋งŒ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์—ด๋žŒ/์ฝ”๋“œ ๋ฐœ๊ธ‰/ํ™˜๋ถˆ/์žฌ๋ฐœ๊ธ‰์€ AdminAuditLog์— ๊ด€๋ฆฌ์ž id, action, target, reason, ์‹œ๊ฐ์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.

14. ์•ฑ ๊ฐœ๋ฐœ์ž์™€ ๋…ผ์˜ํ•  ์‚ฌํ•ญ

ํ™”๋ฉด/UI

  • ๊ณ ์ • ํ…์ŠคํŠธ/FAQ/์ด๋ฏธ์ง€๋Š” App Asset์œผ๋กœ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ด์šฉ๊ถŒ ์ƒํƒœยท์ •์›ยท๋‚ ์งœยท์ฝ”๋“œ ๊ฒฐ๊ณผ๋Š” ์„œ๋ฒ„ ์‘๋‹ต์„ ์”๋‹ˆ๋‹ค.
  • ๋ฒ„ํŠผ ํ™œ์„ฑ ์กฐ๊ฑด: ์ฝ”๋“œ ์ž…๋ ฅ non-empty, claim ์š”์ฒญ ์ง„ํ–‰ ์ค‘ ์ค‘๋ณต ์ œ์ถœ ๋ฐฉ์ง€.
  • ์ด์šฉ๊ถŒ ์ƒํƒœ์™€ โ€œ์ด์šฉ๊ถŒ ์ถ”๊ฐ€๋“ฑ๋กํ•˜๊ธฐโ€ ์˜๋ฏธ(์บ ํŽ˜์ธ๋ณ„ ๋ณต์ˆ˜ ๋ณด์œ  ํ—ˆ์šฉ ์—ฌ๋ถ€).
  • ๋‚ ์งœ ํ‘œ์‹œ KST, ์„œ๋ฒ„ ISO-8601/UTC, ๋‹ฌ๋ ฅ ๊ธฐ์ค€ 1๋…„/6๊ฐœ์›” ๊ณ„์‚ฐ๊ณผ ๋ง์ผ ๊ฒฝ๊ณ„.
  • Enumโ†’ํ•œ๊ตญ์–ด ๋ผ๋ฒจ ๋งคํ•‘์€ App์—์„œ ํ•˜๊ณ  API message๋ฅผ UI ๋ถ„๊ธฐ๋กœ ์“ฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • Empty/Loading/Error/Network Error/Unauthorized/Forbidden ์ƒํƒœ์—์„œ ์ž…๋ ฅ ๋ณด์กด๊ณผ ์žฌ์‹œ๋„ UX.
  • ์ด์šฉ๊ถŒ ์ฝ”๋“œ ํ˜•์‹, FAQ ๋ฌธ๊ตฌ, ํ™”๋ฉด์—์„œ ์“ธ ์ด์šฉ๊ถŒ ์ƒํƒœ/์ฝ”๋“œ ๋ช…์นญ.

API/Auth

  • ๊ณตํ†ต ์„ฑ๊ณต ์‘๋‹ต์˜ HTTP status์™€ body statusCode ์ผ์น˜ ๋ฐฉ์‹.
  • ErrorCode๋งŒ ๋‚ด๋ ค์ค„์ง€, message๋ฅผ ์•ฑ์—์„œ ๋งคํ•‘ํ• ์ง€.
  • nullable ํ•„๋“œ์™€ ์ด์šฉ๊ถŒ ์ƒํƒœ enum ํ‘œ์‹œ.
  • Refresh Token์€ ํ˜„์žฌ X-Refresh-Token ํ—ค๋” ์‚ฌ์šฉ.
  • Version prefix๋Š” ๊ธฐ์กด /api/v1์„ ์œ ์ง€.
  • Pagination: ์š”์ฒญ 0-based/์‘๋‹ต 1-based์ธ ํ˜„์žฌ ํ˜ผํ•ฉ ๊ณ„์•ฝ์„ ์‹ ๊ทœ API์—์„œ ์–ด๋–ป๊ฒŒ ํ†ต์ผํ• ์ง€.
  • claim์šฉ Idempotency-Key ๋ณด์กด ๊ธฐ๊ฐ„๊ณผ ์•ฑ์˜ ๋„คํŠธ์›Œํฌ ๋ณต๊ตฌ ํ›„ ์žฌ์ „์†ก ๋ฐฉ์‹.
  • ํด๋ž˜์Šค ์ฐธ์—ฌ ์ฝ”๋“œ/๊ฒŒ์ŠคํŠธ ์ž…์žฅ, AI ์ž‘์—… UX๋Š” ๊ฐ๊ฐ Classroom/AI ๋‹ด๋‹น ๋ฒ”์œ„์—์„œ ๋…ผ์˜ํ•ฉ๋‹ˆ๋‹ค.

15. ๊ด€๋ฆฌ์ž ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž์™€ ๋…ผ์˜ํ•  ์‚ฌํ•ญ

  • ์„œ๋ฒ„ pagination/filter/sort ์ฑ„ํƒ ๋ฐ size ์ƒํ•œ, ๊ธฐ๋ณธ ์ •๋ ฌ.
  • ๊ฒ€์ƒ‰ ๋ฒ„ํŠผ ๊ธฐ๋ฐ˜ ์กฐํšŒ์ธ์ง€ debounce ๊ฒ€์ƒ‰์ธ์ง€. ํ˜„ ์‹œ์•ˆ์€ ์กฐํšŒ ๋ฒ„ํŠผ์„ ๋ณด์ด๋ฏ€๋กœ ๋ช…์‹œ์  ์กฐํšŒ๋ฅผ ๊ธฐ๋ณธ์•ˆ์œผ๋กœ ๋‘ก๋‹ˆ๋‹ค.
  • ๋‚ ์งœ ๊ฒ€์ƒ‰์˜ ์‹œ๊ฐ„๋Œ€/๋ ๋‚ ์งœ ํฌํ•จ ์—ฌ๋ถ€.
  • ์ด์šฉ๊ถŒ ์ƒํƒœ/๊ฒฐ์ œ ์ƒํƒœ/์ „๋‹ฌ ์ƒํƒœ Enum ํ‘œ์‹œ๋ช….
  • ๊ตฌ๋งค์ž ์—ฐ๋ฝ์ฒ˜ยท์ด์šฉ๊ถŒ ์ฝ”๋“œ ๋งˆ์Šคํ‚น ๋ฐ ์ƒ์„ธ ์—ด๋žŒ ๊ฐ์‚ฌ.
  • โ€œ๊ตฌ๋งค์ž ๋“ฑ๋กโ€ ์ž…๋ ฅ ํ•„๋“œ์™€ ๊ฒฐ์ œ ์™„๋ฃŒ ์ฆ๋น™ ๋ฐฉ์‹.
  • ์ฝ”๋“œ ๋ฐœ๊ธ‰ ์งํ›„ ์›๋ฌธ์„ ์ผํšŒ ํ‘œ์‹œยท๋ณต์‚ฌํ•˜๋Š” ๋ชจ๋‹ฌ.
  • ์ „๋‹ฌ ์‹คํŒจ ๊ธฐ๋ก๊ณผ ์žฌ์ „๋‹ฌ/์žฌ๋ฐœ๊ธ‰์„ ๊ตฌ๋ณ„.
  • ์ทจ์†Œ/ํ™˜๋ถˆ์€ ๋ฌผ๋ฆฌ ์‚ญ์ œ ๋Œ€์‹  REVOKED ์ƒํƒœ๋กœ ๋ณด์กด.
  • CSV ํ•„ํ„ฐ ์ ์šฉ, ๋‹ค์šด๋กœ๋“œ ์ธ๊ฐ€, ํฌํ•จ ์ปฌ๋Ÿผ/PII.
  • ๋ช…๋‹จ Excel์€ ์šด์˜์ž๊ฐ€ ํ…€๋ธ”๋ฒ…์—์„œ ์ง์ ‘ ๋‚ด๋ ค๋ฐ›์•„ ๊ด€๋ฆฌ์ž ๊ธฐ๋Šฅ์— ์—…๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. ์‹œํŠธ๋ฅผ ์„ ํƒํ•˜๋ฉด ์„œ๋ฒ„๊ฐ€ 9๊ฐœ ์—ด์„ ์ž๋™ ํŒ๋ณ„ํ•˜๊ณ , ์šด์˜์ž๋Š” ๋ฏธ๋ฆฌ๋ณด๊ธฐ์—์„œ ๊ฒฐ์ œ ์ƒํƒœ๋ฅผ ํ™•์ธํ•œ ๋’ค ์ €์žฅยท์ฝ”๋“œ ๋ฐœ๊ธ‰์„ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • ํด๋ž˜์Šค ์ƒ์„ธ/์šด์˜ ํ™”๋ฉด์€ ๋ณ„๋„ Classroom ๋‹ด๋‹น ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค.

16. ํ™”๋ฉด ์ƒํƒœ ์ •์˜

์ƒํƒœ ๋ฐฑ์—”๋“œ ํ‘œํ˜„ ํ™”๋ฉด ์ฒ˜๋ฆฌ
Loading Funding API ์‘๋‹ต ์ „ ์ง„ํ–‰ ํ‘œ์‹œ; AI job ์ƒํƒœ๋Š” ๊ตฌํ˜„ ๋ฒ”์œ„ ๋ฐ–
Empty ๋ชฉ๋ก API content=[] ๋˜๋Š” ticket state=NONE App/๊ด€๋ฆฌ์ž Empty ์•ˆ๋‚ด
Success HTTP 2xx + data ๊ฒฐ๊ณผ ๋ Œ๋”๋ง
Error HTTP 4xx/5xx + ErrorCode ์—…๋ฌด ์˜ค๋ฅ˜๋ณ„ ๋งคํ•‘
Network Error ์„œ๋ฒ„ ์‘๋‹ต ์—†์Œ ์•ฑ/๋ธŒ๋ผ์šฐ์ € ์ž์ฒด ๊ฐ์ง€, ์ž…๋ ฅ ์œ ์ง€
Unauthorized 401 AUTH_UNAUTHORIZED/ํ† ํฐ ๋งŒ๋ฃŒ ์žฌ๋กœ๊ทธ์ธ/refresh
Forbidden 403 AUTH_FORBIDDEN/๋ฒ”์œ„ ๊ถŒํ•œ ์—†์Œ ์ ‘๊ทผ ๊ฑฐ์ ˆ, ๋ฏผ๊ฐ ๋ฐ์ดํ„ฐ ๋ฏธ๋ฐ˜ํ™˜
Classroom ๋งŒ๋ฃŒ ๋ณ„๋„ Classroom ๋„๋ฉ”์ธ์—์„œ ์ฒ˜๋ฆฌ Funding ๊ตฌํ˜„์€ ticket ๋งŒ๋ฃŒ ์ƒํƒœ์™€ ์กฐํšŒ๋งŒ ์ œ๊ณต

์„œ๋ฒ„๊ฐ€ ์—…๋ฌด ์ƒํƒœ์™€ ์˜ค๋ฅ˜ ์ฝ”๋“œ๋ฅผ ๊ตฌ๋ถ„ํ•ด์„œ ์ฃผ๊ณ , Loadingยท๋„คํŠธ์›Œํฌ ๋‹จ์ ˆยทํ† ์ŠคํŠธยท์ •์  ์•ˆ๋‚ด ๋ฌธ๊ตฌ๋Š” ๊ฐ ํ”„๋ก ํŠธ์—”๋“œ์—์„œ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.


17. UI ๋ฌธ๊ตฌ ์ˆ˜์ •์‚ฌํ•ญ

์˜ค๋ฅ˜ ํ™”๋ฉด์— ํ‘œ์‹œ๋œ ๊ตฌ ๋ฌธ๊ตฌ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฌธ์„œ์™€ API ์˜ˆ์‹œ์— ์•„๋ž˜ ๋ฌธ๊ตฌ๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ฝ”๋“œ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์•„์š”.
์ž…๋ ฅํ•œ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ํ™•์ธํ•ด ์ฃผ์„ธ์š”.

๊ถŒ์žฅ API๋Š” ์•ˆ์ •์ ์ธ Funding ErrorCode๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ  App์ด ๋ฌธ๊ตฌ๋ฅผ ๋งคํ•‘ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ ๊ณตํ†ต ์˜ค๋ฅ˜ ์‘๋‹ต์€ message๋„ ํฌํ•จํ•˜๋ฏ€๋กœ, server message๋ฅผ ํ‘œ์‹œํ• ์ง€ App ๋ฒˆ์—ญ ์ƒ์ˆ˜๋กœ ๊ด€๋ฆฌํ• ์ง€๋Š” ์•ฑ ๊ฐœ๋ฐœ์ž ํ˜‘์˜ ํ•ญ๋ชฉ์ž…๋‹ˆ๋‹ค.


18. ์ „์ฒด API ๋ชฉ๋ก

์ด๋ฒˆ ๊ตฌํ˜„ API ๋ชฉ๋ก์€ Funding ๋ฒ”์œ„์™€ ํ˜„์žฌ ๊ตฌํ˜„๋œ ๊ณตํ†ต API๋งŒ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. Classroom ํ™”๋ฉด์—์„œ ๋ณด์ธ ํด๋ž˜์Šค API์™€ PRD์˜ AI API๋Š” ๋ถ„์„ ์ฐธ๊ณ ์‚ฌํ•ญ์ด๋ฉฐ ์‹ ๊ทœ ์ œ์•ˆ/๊ตฌํ˜„ ๋Œ€์ƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. Classroom ์—ฐ๋™์€ ๋‚ด๋ถ€ FundingTicketPolicy ํ˜ธ์ถœ์ด๋ฏ€๋กœ HTTP API๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž

Type Domain Method Endpoint ์ƒํƒœ ์ธ์ฆ
USER Auth POST /api/v1/auth/login/{provider} ์กด์žฌ ์—†์Œ
USER Auth POST /api/v1/auth/refresh ์กด์žฌ Refresh Token
USER Auth POST /api/v1/auth/logout ์กด์žฌ USER
USER Mypage GET /api/v1/me/mypage ์กด์žฌ USER
USER Battle Catalog GET /api/v1/battles ๋ถ€๋ถ„ ์กด์žฌ, ์ผ๋ฐ˜ ๋ชฉ๋ก ๊ธฐ์กด ์ •์ฑ…
USER Battle Catalog GET /api/v1/battles/{battleId} ๋ถ€๋ถ„ ์กด์žฌ, ์ผ๋ฐ˜ ์ƒ์„ธ ๊ธฐ์กด ์ •์ฑ…
USER Fundings GET /api/v1/tickets/me ๊ตฌํ˜„ ์™„๋ฃŒ USER
USER Fundings POST /api/v1/ticket-codes/preview ๊ตฌํ˜„ ์™„๋ฃŒ USER
USER Fundings POST /api/v1/ticket-codes/claim ๊ตฌํ˜„ ์™„๋ฃŒ USER

๊ด€๋ฆฌ์ž

Type Domain Method Endpoint ์ƒํƒœ ์ธ์ฆ
ADMIN Users GET /api/v1/admin/users/search ์กด์žฌ ADMIN
ADMIN Dashboard GET /api/v1/admin/dashboard/summary ์กด์žฌ ADMIN
ADMIN Funding GET /api/v1/admin/tickets ๊ตฌํ˜„ ์™„๋ฃŒ ADMIN
ADMIN Funding GET /api/v1/admin/funding-orders ๊ตฌํ˜„ ์™„๋ฃŒ ADMIN
ADMIN Funding POST /api/v1/admin/funding-orders ๊ตฌํ˜„ ์™„๋ฃŒ, ์ˆ˜๋™ P0 ADMIN
ADMIN Funding POST /api/v1/admin/tickets/{ticketId}/codes ๊ตฌํ˜„ ์™„๋ฃŒ ADMIN
ADMIN Funding PATCH /api/v1/admin/deliveries/{id} ๊ตฌํ˜„ ์™„๋ฃŒ ADMIN
ADMIN Funding POST /api/v1/admin/tickets/{ticketId}/reissue ๊ตฌํ˜„ ์™„๋ฃŒ ADMIN
ADMIN Funding POST /api/v1/admin/tickets/{ticketId}/refund ๊ตฌํ˜„ ์™„๋ฃŒ ADMIN

์ผ๋ฐ˜ ๊ด€๋ฆฌ์ž ๋Œ€์‹œ๋ณด๋“œ์˜ ๊ธฐ์กด ํ†ต๊ณ„ endpoint๋Š” ํด๋ž˜์Šค ์ง€ํ‘œ๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Funding ๋ฒ”์œ„์— ํฌํ•จ๋˜์ง€ ์•Š์€ ํด๋ž˜์Šค ํ™”๋ฉด API๋Š” ๊ตฌํ˜„ ์™„๋ฃŒ ๋˜๋Š” ์‹ ๊ทœ Funding API๋กœ ๊ณ„์‚ฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


19. ์ตœ์ข… Entity ๋ชฉ๋ก

  • User (๊ธฐ์กด): ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž ๋ฐ ์‹œ์Šคํ…œ ์—ญํ• .
  • FundingCampaign: ํŽ€๋”ฉ ํ”Œ๋žซํผ ์บ ํŽ˜์ธ๊ณผ ์ƒํ’ˆ ๋งคํ•‘.
  • FundingOrder: ๊ฒฐ์ œ ํ™•์ • ์ฃผ๋ฌธ/๋ฆฌ์›Œ๋“œ ํ–‰๊ณผ ์ตœ์†Œ ๊ตฌ๋งค์ž ์ •๋ณด.
  • Ticket: ์ •์›ยท๋“ฑ๋ก ๊ธฐํ•œยท๊ณ„์ • ๊ท€์†ยทํ™œ์„ฑ/๋งŒ๋ฃŒ ๊ถŒํ•œ.
  • TicketCode: ์ด์šฉ๊ถŒ claim์šฉ ๋น„๋ฐ€ ์ฝ”๋“œ์˜ ํ•ด์‹œ์™€ ์ƒํƒœ.
  • DeliveryAttempt: ์ฝ”๋“œ ์ „๋‹ฌ ์‹œ๋„ ๋ฐ ์‹คํŒจ ๊ฒฐ๊ณผ.
  • AdminAuditLog: Funding ๊ด€๋ จ ๋ฏผ๊ฐํ•œ ๊ด€๋ฆฌ์ž ๋ณ€๊ฒฝ ์ด๋ ฅ.

Classroom์€ ๋ณ„๋„ ๊ฐœ๋ฐœ์ž๊ฐ€ ์†Œ์œ ํ•ฉ๋‹ˆ๋‹ค. Funding ๊ตฌํ˜„์€ ๋ณ„๋„ ํด๋ž˜์Šค Entity๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๊ณ , ๊ธฐ์กด Classroom์— ticketId ์ฐธ์กฐ์™€ ์ƒ์„ฑ ์‹œ Funding ์œ ํšจ์„ฑ ํ™•์ธ๋งŒ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. AI ๊ด€๋ จ Entity๋Š” ๋งŒ๋“ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


20. ์ตœ์ข… ์•„ํ‚คํ…์ฒ˜ ์š”์•ฝ

ํ•ต์‹ฌ ๋„๋ฉ”์ธ

Funding, Classroom ์ตœ์†Œ ์—ฐ๋™, ๊ธฐ์กด User/Auth/Admin ๊ณตํ†ต ๊ธฐ๋ฐ˜.

ํ•ต์‹ฌ Entity

User(๊ธฐ์กด), FundingCampaign, FundingOrder, Ticket, TicketCode, DeliveryAttempt, AdminAuditLog. Classroom์€ ๋ณ„๋„ ๋‹ด๋‹น์˜ ๊ธฐ์กด Entity์— ticketId ์—ฐ๊ฒฐ๋งŒ ํ•ฉ์˜ํ•ฉ๋‹ˆ๋‹ค.

ํ•ต์‹ฌ Service

FundingTicketService, FundingAdminService, FundingTicketPolicy (๋‚ด๋ถ€ ์—ฐ๋™ ๊ณ„์•ฝ).

ํ•ต์‹ฌ API

์ด์šฉ๊ถŒ: GET /api/v1/tickets/me, POST /api/v1/ticket-codes/preview, POST /api/v1/ticket-codes/claim.
ํด๋ž˜์Šค ์—ฐ๋™: ํด๋ž˜์Šค ๋‹ด๋‹น์ž๊ฐ€ ์ƒ์„ฑ ์‹œ FundingTicketPolicy๋ฅผ ๋‚ด๋ถ€ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค (HTTP endpoint ์ถ”๊ฐ€ ์—†์Œ).
๊ด€๋ฆฌ์ž: /api/v1/admin/tickets, /funding-orders, ํ…€๋ธ”๋ฒ… ์—‘์…€ ๋ฏธ๋ฆฌ๋ณด๊ธฐยท์ฝ”๋“œํŒŒ์ผ ์ƒ์„ฑ๊ณผ ์ „๋‹ฌ ๊ธฐ๋ก.

์™ธ๋ถ€ ์—ฐ๋™

ํ˜„์žฌ ์šด์˜์€ ๊ด€๋ฆฌ์ž๊ฐ€ ํ…€๋ธ”๋ฒ… ์—‘์…€์„ ์ง์ ‘ ๋‚ด๋ ค๋ฐ›์•„ ํ™•์ธํ•˜๊ณ , ์„œ๋ฒ„์— ์—…๋กœ๋“œํ•ด ๊ฒฐ์ œ ์™„๋ฃŒ ํ–‰์˜ ์ฝ”๋“œ์™€ ํ…€๋ธ”๋ฒ… ๋””์ง€ํ„ธ ์„ ๋ฌผ ์—…๋กœ๋“œ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ํ…€๋ธ”๋ฒ… API๋ฅผ ์ด์šฉํ•œ ์ž๋™ ๋™๊ธฐํ™”๋Š” ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ด€๋ฆฌ์ž ๊ธฐ๋Šฅ

ํŽ€๋”ฉ ๊ตฌ๋งค์ž ์ˆ˜๋™ ๋“ฑ๋ก, ์ด์šฉ๊ถŒ ์ฝ”๋“œ ๋ฐœ๊ธ‰๊ณผ ์ „๋‹ฌ ์ƒํƒœ, ์ด์šฉ๊ถŒ/๋“ฑ๋ก์ž ์กฐํšŒ์™€ CSV export. ํด๋ž˜์Šค ๋Œ€์‹œ๋ณด๋“œ๋Š” ๋ณ„๋„ ๊ตฌํ˜„ ๋ฒ”์œ„์ž…๋‹ˆ๋‹ค.

๋จผ์ € ํ•ฉ์˜ํ•  ์‚ฌํ•ญ

  • ์•ฑ: โ€œ์ถ”๊ฐ€ ๋“ฑ๋กโ€๊ณผ 1์ธ 1๊ฐœ ์ œํ•œ, ์ฝ”๋“œ ์˜ค๋ฅ˜ ๋ฌธ๊ตฌ ์ „๋‹ฌ ๋ฐฉ์‹, ๊ธฐ๊ฐ„ ๊ณ„์‚ฐ/์‹œ๊ฐ„๋Œ€.
  • Classroom ๋‹ด๋‹น์ž: ticketId FK ์†Œ์œ ๊ถŒ, ํด๋ž˜์Šค ์ƒ์„ฑ ์‹œ Funding ์ •์ฑ… ํ˜ธ์ถœ ์ง€์ ๊ณผ ํ™˜๋ถˆ ์ƒํƒœ ์žฌ๊ฒ€์ฆ ๋ฐฉ์‹.
  • ๊ด€๋ฆฌ์ž ํ”„๋ก ํŠธ์—”๋“œ: ์ฝ”๋“œ ์›๋ฌธ ๋…ธ์ถœ/๋งˆ์Šคํ‚น, ๊ตฌ๋งค์ž ์—ฐ๋ฝ์ฒ˜ ์ ‘๊ทผ, ์ „๋‹ฌ ์‹คํŒจ/์žฌ๋ฐœ๊ธ‰ ํ๋ฆ„, CSV ํ•„๋“œ.
  • ๊ธฐํš/์šด์˜: ํ”Œ๋žซํผ ์„ ํƒ, ๊ฒฐ์ œ ํ™•์ • ์ฆ๋น™, ํ™˜๋ถˆ ์ •์ฑ…, ๊ตฌ๋งค์ž ๋ฐ์ดํ„ฐ ๋ณด์œ  ๊ธฐ๊ฐ„, Excel ์‹œ์ .

๊ตฌํ˜„ ์šฐ์„ ์ˆœ์œ„

  • P0: ๊ตฌ๋งค์ž/์ฃผ๋ฌธ ์ˆ˜๋™ ๋“ฑ๋ก, ๊ฒฐ์ œ ์ƒํƒœ ํ™•์ธ, ์ด์šฉ๊ถŒยท์ฝ”๋“œ ๋ฐœ๊ธ‰๊ณผ claim, ์ „๋‹ฌ ์ƒํƒœ, ๊ด€๋ฆฌ์ž Funding ์กฐํšŒ, Classroom ์œ ํšจ์„ฑ ์ •์ฑ… ๊ณ„์•ฝ ๋ฐ ticketId ์—ฐ๊ฒฐ.
  • P1: Funding ์šด์˜ ์•Œ๋ฆผยท๋งŒ๋ฃŒ ์ž๋™ํ™”, ์žฌ๋ฐœ๊ธ‰/ํ™˜๋ถˆ ๋ณด์กฐ ํ๋ฆ„, ๊ฐœ์ธ์ •๋ณด ๋ณด๊ด€ยทํŒŒ๊ธฐ ์ž๋™ํ™”.
  • ๋ณด๋ฅ˜: ํ…€๋ธ”๋ฒ… ๊ณต์‹ ํ”Œ๋žซํผ API ์—ฐ๋™/์ž๋™ ๋™๊ธฐํ™”์™€ ์ž๋™ ์ „๋‹ฌ. ๋ช…๋‹จ ํŒŒ์ผ ๊ธฐ๋ฐ˜์˜ ์‚ฌ๋žŒ ๊ฒ€ํ† ํ˜• ๊ฐ€์ ธ์˜ค๊ธฐ/์ฝ”๋“œ ํŒŒ์ผ ์ƒ์„ฑ API๋Š” ๊ตฌํ˜„ ๋Œ€์ƒ์— ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

21. ๊ตฌํ˜„ ์™„๋ฃŒ ๋ฐ ๋ฏธํฌํ•จ ํ•ญ๋ชฉ

๊ตฌํ˜„ ์™„๋ฃŒ

  • ์‚ฌ์šฉ์ž API: ์ด์šฉ๊ถŒ ์ƒํƒœ ์กฐํšŒ, ๋“ฑ๋ก ์ฝ”๋“œ ๋ฏธ๋ฆฌ๋ณด๊ธฐ, ์ฝ”๋“œ ๋“ฑ๋ก.
  • ๊ด€๋ฆฌ์ž API: ๋‹จ๊ฑด ์ฃผ๋ฌธ ๋“ฑ๋ก, ํ…€๋ธ”๋ฒ… XLSX ์‹œํŠธ ํ™•์ธ/๋ฏธ๋ฆฌ๋ณด๊ธฐ/ํ›„์›๋ฒˆํ˜ธ ์ค‘๋ณต ๊ฒ€์‚ฌ, ๊ฒฐ์ œ ์™„๋ฃŒ ํ–‰ ์ฝ”๋“œ ๋ฐœ๊ธ‰ ๋ฐ ๋””์ง€ํ„ธ ์„ ๋ฌผ ์—…๋กœ๋“œ ํŒŒ์ผ ์ƒ์„ฑ, ํ›„์›๋ฒˆํ˜ธ๋ณ„ ์ „๋‹ฌ ๊ฒฐ๊ณผ ๊ธฐ๋ก, ์ฃผ๋ฌธ/์ด์šฉ๊ถŒ ๊ฒ€์ƒ‰, ์ฝ”๋“œ ๋ฐœ๊ธ‰ยท์žฌ๋ฐœ๊ธ‰, ํ™˜๋ถˆ ํ™•์ • ์ฒ˜๋ฆฌ.
  • ์ €์žฅ์†Œ ๊ณ„์ธต: ์บ ํŽ˜์ธ, ์ฃผ๋ฌธ, ์ด์šฉ๊ถŒ, ์ฝ”๋“œ, ์ „๋‹ฌ ์‹œ๋„, ๊ด€๋ฆฌ์ž ๋ณ€๊ฒฝ ๋กœ๊ทธ Entity/Repository ๋ฐ DB migration SQL.
  • ๋™์‹œ์„ฑ/๋ณด์•ˆ: ์ฝ”๋“œ์™€ ์‚ฌ์šฉ์ž ํ–‰ ์ž ๊ธˆ ๊ธฐ๋ฐ˜ claim, ๊ณ ์œ  ์ฃผ๋ฌธ ํ‚ค, ์ฝ”๋“œ ์›๋ฌธ ๋ฏธ์ €์žฅ, ๊ตฌ๋งค์ž ์—ฐ๋ฝ์ฒ˜ AES-GCM ์•”ํ˜ธํ™”ยทHMAC ๊ฒ€์ƒ‰, ์‘๋‹ต ๋งˆ์Šคํ‚น.
  • API ํ‘œ์—์„œ [์กด์žฌ]๋กœ ํ‘œ์‹œ๋œ ๋กœ๊ทธ์ธยท๋งˆ์ดํŽ˜์ด์ง€ยท์ผ๋ฐ˜ ๊ด€๋ฆฌ์ž API๋Š” ์›๋ž˜ ์žˆ๋˜ API์ž…๋‹ˆ๋‹ค. [๊ตฌํ˜„ ์™„๋ฃŒ]๋Š” ์ด๋ฒˆ ๋ณ€๊ฒฝ์œผ๋กœ ์ถ”๊ฐ€๋œ Funding API์ž…๋‹ˆ๋‹ค.
  • Swagger: ์‚ฌ์šฉ์ž Funding API๋Š” ์‚ฌ์šฉ์ž API ๊ทธ๋ฃน ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ์— ๋“ฑ๋กํ–ˆ๊ณ , ์‚ฌ์šฉ์ž/๊ด€๋ฆฌ์ž API ๋ชจ๋‘ ์š”์•ฝยท์„ค๋ช…ยท์ธ์ฆยท์ฃผ์š” ์‘๋‹ต ์ฝ”๋“œ๋ฅผ ๋ช…์‹œํ–ˆ์Šต๋‹ˆ๋‹ค.
  • API๋ณ„ Method, URL, ์š”์ฒญ ์˜ต์…˜, ์ €์žฅ ํ•„๋“œ์™€ ์ฃผ์š” ์˜ค๋ฅ˜๋Š” Funding API ๋น ๋ฅธ ์ฐธ์กฐ์— ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค. Funding ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ์€ ๋‹จ์ผ ํŒŒ์ผ V20261015_01__create_fundings_domain.sql์— ํ†ตํ•ฉํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ณ€๊ฒฝ์— ํฌํ•จํ•˜์ง€ ์•Š์Œ

  • classroom์—๋Š” Funding์˜ ์œ ํšจ ์ด์šฉ๊ถŒ ์กฐํšŒ ๊ณ„์•ฝ๋งŒ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค. ํด๋ž˜์Šค Entity, ticketId ํ•„๋“œ, ํด๋ž˜์Šค API/ํ™”๋ฉด์€ ํด๋ž˜์Šค ๋‹ด๋‹น์ž๊ฐ€ ์—ฐ๊ฒฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • AI ๋„๋ฉ”์ธ, AI API ๋ฐ AI Provider ์—ฐ๋™์€ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
  • ํ…€๋ธ”๋ฒ… ๋ช…๋‹จ๊ณผ ํ…์ŠคํŠธ ์„ ๋ฌผ Excel์€ ์šด์˜์ž๊ฐ€ ํ…€๋ธ”๋ฒ…์—์„œ ์ง์ ‘ ๋‚ด๋ ค๋ฐ›๊ณ  ์—…๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. ์„œ๋ฒ„๋Š” ์šด์˜์ž๊ฐ€ ์„ ํƒํ•œ ์‹œํŠธ์˜ ํ™”๋ฉด 9๊ฐœ ์—ด์„ ์ž๋™ ํŒ๋ณ„ํ•˜๊ณ  ์œ ํšจํ•œ ํ–‰์„ ์ €์žฅํ•˜๋ฉฐ, ๊ฒฐ์ œ ์™„๋ฃŒ ํ–‰๋งŒ ์ฝ”๋“œํ™”ํ•ฉ๋‹ˆ๋‹ค. ํ…€๋ธ”๋ฒ… ์‚ฌ์ดํŠธ ์—…๋กœ๋“œ์™€ ์™„๋ฃŒ ๊ฒฐ๊ณผ ์ž…๋ ฅ์€ ์šด์˜์ž๊ฐ€ ์ˆ˜ํ–‰ํ•˜๋ฉฐ ํ”Œ๋žซํผ API ์ž๋™ ๋™๊ธฐํ™”ยท์ด๋ฉ”์ผ/SMS ์ž๋™ ๋ฐœ์†ก์€ ์—†์Šต๋‹ˆ๋‹ค.
  • ์ƒˆ ์ฝ”๋“œ ํ˜•์‹์€ PICKE- ๋’ค์— O ์ œ์™ธ A-Z์™€ 1-9์—์„œ ๋ฝ‘์€ 28๊ฐœ ๋‚œ์ˆ˜๋ฅผ 4์ž์”ฉ ๊ณ ์ • ๊ทธ๋ฃน์œผ๋กœ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ์ ‘๋‘๋ถ€๋Š” ์—”ํŠธ๋กœํ”ผ์— ํฌํ•จ๋˜์ง€ ์•Š์œผ๋ฉฐ ๋‚œ์ˆ˜ ๊ณต๊ฐ„์€ ์•ฝ 142๋น„ํŠธ์ž…๋‹ˆ๋‹ค. ๊ธฐ์กด PK ์ฝ”๋“œ๋Š” ํ•˜์œ„ ํ˜ธํ™˜์„ ์œ„ํ•ด claim ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ๊ตฌ๋งค์ž ์—ฐ๋ฝ์ฒ˜ ์•”ํ˜ธํ™” ๊ธฐ๋Šฅ์€ ๋ฐฐํฌ ํ™˜๊ฒฝ์— FUNDING_CONTACT_ENCRYPTION_KEY๋ฅผ Base64 ํ˜•์‹์˜ 32๋ฐ”์ดํŠธ ํ‚ค๋กœ ์„ค์ •ํ•ด์•ผ ์ฃผ๋ฌธ ๋“ฑ๋ก๊ณผ ์—ฐ๋ฝ์ฒ˜ ์กฐํšŒ๊ฐ€ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

Classroom ๊ตฌํ˜„๊ณผ AI ๋„๋ฉ”์ธ์€ ์ด๋ฒˆ ๋ฒ”์œ„์— ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Funding์˜ ์ค‘๋ณตยท๊ถŒํ•œยท์ •์›ยท๊ธฐ๊ฐ„ยท์ฝ”๋“œ claim ๋ณด์žฅ์€ DB ์ œ์•ฝ๊ณผ ํŠธ๋žœ์žญ์…˜์„ ๊ธฐ์ค€์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.