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๊ฐ ์ ์ํ ์ ์ฑ , ํ์ธ ํ์๋ ์ถ์ ์ ํฉ์ ํญ๋ชฉ
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 ๊ตฌํ ๋ฒ์์ ๋๋ค. ์ด๋ฒ์๋ ํด๋น ์ธ์ฆ ๊ตฌ์กฐ๋ฅผ ์ถ๊ฐํ์ง ์์ต๋๋ค.
- ํ ๋ธ๋ฒ ๊ฒฐ์ ๋ ์ฑ์์ ์ฒ๋ฆฌํ์ง ์์ต๋๋ค. ํ๋ฉ ๊ฒฐ์ ํ์ธ๊ณผ ๋ฆฌ์๋ ์ฝ๋๋ ๊ด๋ฆฌ์ ์ด์ ํ๋ฆ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
ํ์ฌ ํ๋ก์ ํธ์ 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์FundingTicketAccessrecord๋ง ์ถ๊ฐํฉ๋๋ค. ํด๋์ค ๊ธฐ๋ฅ 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 ๊ธฐ๋ฅ์ ๊ตฌํํ์ง ์์ต๋๋ค.
UI ํด๋์๋ ์ด 12์ฅ์ ํ๋ฉด ์ด๋ฏธ์ง๊ฐ ์์ต๋๋ค. ์ฑ ํ๋ฉด์ 8๊ฐ ์ด๋ฏธ์ง/์ํ ๋ฌถ์, ๊ด๋ฆฌ์ ํ๋ฉด์ 4๊ฐ ํ๋ฉด์ผ๋ก ๋ถ์ํ์ต๋๋ค. PRD์ S01~S22 ํด๋์ค ์ฐธ์ฌยท์์ฑ ํ๋ฉด์ ์ด ํด๋์ ์๊ฐ ์์์ด ์์ผ๋ฏ๋ก, ์๋์์ PRD ์ ์ฉ ํ๋ฉด ํ๋ฆ์ผ๋ก ๋ช ์ํฉ๋๋ค.
์ด ์ ์ ์ ์ฒด ์๋ฃ์์ ํ์ธํ ํ๋ฉด๊ณผ ๋ฐ์ดํฐ ์๊ตฌ๋ฅผ ๋ณด์กดํฉ๋๋ค. ๋ค๋ง ์ด๋ฒ ๊ตฌํ์ Funding ํ๋ฉด/๊ธฐ๋ฅ์ ํ์ ํฉ๋๋ค. Classroom ํ๋ฉด ์ค ์ด์ฉ๊ถ ์ ํจ์ฑ ์ฐ๊ฒฐ ์ธ ๊ธฐ๋ฅ๊ณผ AI ๊ด๋ จ ํ๋ฉดยท๊ธฐ๋ฅ์ ๊ฐ๊ฐ ๋ค๋ฅธ ๊ฐ๋ฐ ๋ฒ์์ด๋ฉฐ, ์ฌ๊ธฐ์ ๊ตฌํํ์ง ์์ต๋๋ค.
์ด๋ฏธ์ง: 2026-10-14 232458
- ๋ชฉ์ : ์ฌ์ฉ์๊ฐ ํด๋์ค ์ด์ฉ๊ถ ๋ฉ๋ด๋ก ์ด๋ํฉ๋๋ค.
- ์ก์ : ํด๋์ค ์ด์ฉ๊ถ ๋ฉ๋ด ํญ.
- ๋ฐ์ดํฐ: ๊ธฐ์กด ์ฌ์ฉ์ ํ๋กํ์ ๊ธฐ์กด ๋ง์ดํ์ด์ง API์์ ๋ฐ๊ณ , ์ด์ฉ๊ถ ์กด์ฌ/์ํ ํ์๋ ๋ณ๋ ์ด์ฉ๊ถ API์์ ๋ฐ์ต๋๋ค.
- ํ๋ก ํธ ์ฒ๋ฆฌ: ๋ฉ๋ด๋ช ยท์์ด์ฝยท๊ณ ์ ๋ฌธ๊ตฌ.
- ๋ฐฑ์๋ ์ฒ๋ฆฌ: ์ด์ฉ๊ถ ์ํ์ ํ์ํ ์ ์ยท๊ธฐ๊ฐ.
- API: [์กด์ฌ] GET /api/v1/me/mypage, [๊ตฌํ ์๋ฃ] GET /api/v1/tickets/me.
- ์ธ์ฆ: ๋ก๊ทธ์ธ ํ์.
- ์์ธ/์ด๋: ๋ฏธ๋ณด์ ๋ฉด ์ฝ๋ ๋ฑ๋ก ์๋ด, ๋ณด์ ๋ฉด ์ด์ฉ๊ถ ์์ธ. ๋ก๋ฉยท๋คํธ์ํฌ ์ค๋ฅ๋ ์ฑ ์ํ.
- ๋ ผ์: ๊ธฐ์กด mypage ์๋ต์ ์ด์ฉ๊ถ ํ๋๋ฅผ ํฉ์น ์ง ๋ณ๋ endpoint๋ก ์กฐํํ ์ง. ๋ณธ ์ค๊ณ๋ ๋ณ๋ endpoint๋ฅผ ๊ถ์ฅํด User ๋๋ฉ์ธ ๋ณ๊ฒฝ์ ํผํฉ๋๋ค.
์ด๋ฏธ์ง: 2026-10-14 232009, 232203
- ๋ชฉ์ : ํ๋ฉ ๋ฆฌ์๋๋ก ๋ฐ์ ์ด์ฉ๊ถ ๋ฑ๋ก ์ฝ๋๋ฅผ ์ ๋ ฅํฉ๋๋ค.
- ์ก์ : ์ฝ๋ ์ ๋ ฅ, ์ฝ๋ ํ์ธ, FAQ ์ด๊ธฐ.
- ํ์ ๋ฐ์ดํฐ: ์ฝ๋ ์ ๋ ฅ๊ฐ์ ์ฑ ์ํ. ์ด์ฉ๊ถ ์ ์๊ณผ ๋ฑ๋ก๊ธฐํ์ ๊ฒ์ฆ ํ ๋ฐฑ์๋ ์๋ต.
- ํ๋ก ํธ ์ฒ๋ฆฌ: ๋ผ๋ฒจยท๊ณ ์ ์๋ดยท์ ๋ ฅ ํ์ยท๋ฒํผ ํ์ฑ ์กฐ๊ฑด.
- ๋ฐฑ์๋ ์ฒ๋ฆฌ: ์ฝ๋ ์กด์ฌ/์ํ/๋ฑ๋ก๊ธฐํ/๋ค๋ฅธ ์ฝ๋ ์ ํ ์ฌ๋ถ.
- API: [๊ตฌํ ์๋ฃ] POST /api/v1/ticket-codes/preview.
- ์ธ์ฆ: ๋ก๊ทธ์ธ ํ์, ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ ์ฝ๋๋ฅผ ์๋นํ์ง ์์ต๋๋ค.
- ์์ธ/์ด๋: ์๋ชป๋ ์ฝ๋๋ฉด ์ ๋ ฅ์ ๋ณด์กดํ๊ณ ์ค๋ฅ ์๋ด, ์ ํจํ๋ฉด ๋ฑ๋ก ํ์ธ ํ๋ฉด.
- ๋ ผ์: ์ฝ๋ ์ ๋ ฅ์ ํ์ดํยท๊ณต๋ฐฑ ์ ๊ทํ ๋ฐ ๋ณต์ฌ/๋ถ์ฌ๋ฃ๊ธฐ ๋์.
์ด๋ฏธ์ง: 2026-10-14 232243
- ๋ชฉ์ : ์ฝ๋๋ฅผ ์ด๋์ ๋ฐ๋์ง์ ํด๋์ค ์ฐธ์ฌ ์ฝ๋์์ ์ฐจ์ด๋ฅผ ์๋ดํฉ๋๋ค.
- ํ์ ๋ฐ์ดํฐ: โํ๋ฉ ๋ฆฌ์๋ ์๋ด์์ ํ์ธโ, โ์ฐธ์ฌ ์ฝ๋๋ ๋ชจ์ ์ ์ฅ์ ์ฌ์ฉํ๋ ๋ณ๋ ์ฝ๋โ ๋ฌธ๊ตฌ.
- ํ๋ก ํธ ์ฒ๋ฆฌ ๊ถ์ฅ: FAQ ๋ฌธ๊ตฌ๋ ๊ณ ์ ์๋ด์ด๋ฏ๋ก App์์ ๊ด๋ฆฌํฉ๋๋ค.
- ๋ฐฑ์๋: ๋ถํ์.
- ๋ ผ์: ์ด์ ์ค ํ๋ถ/์ ๋ฌ ๊ฒฝ๋ก๊ฐ ๋ฐ๋๋ฉด ๋ฌธ๊ตฌ ๋ฐฐํฌ๋ฅผ ๋๊ฐ ๋ด๋นํ ์ง ์ ํฉ๋๋ค.
์ด๋ฏธ์ง: 2026-10-14 232144
- ๋ชฉ์ : ์ด๋ฏธ ๋ฑ๋ก๋ ์ด์ฉ๊ถ, ์๋ชป๋ ์ฝ๋, ๋คํธ์ํฌ ๋ฌธ์ , ๋ง๋ฃ ์ฝ๋๋ฅผ ๊ตฌ๋ถํฉ๋๋ค.
- ๋ฐฑ์๋ ๊ตฌ๋ถ: CODE_INVALID, CODE_ALREADY_CLAIMED, CODE_EXPIRED, CODE_REVOKED, NETWORK_ERROR.
- ํ๋ก ํธ ์ฒ๋ฆฌ: ์ค๋ฅ ์์ด์ฝ, ์ฌ์๋ ๋ฒํผ, ์ ๋ ฅ ๋ณด์กด, ํ์ธ/๋ค๋ก๊ฐ๊ธฐ.
- ์ธ์ฆ: ์ฝ๋ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ ๋ก๊ทธ์ธ ํ์.
- ์์ธ ๋ฌธ๊ตฌ: ์ฝ๋ ์ค๋ฅ๋ ๋ค์ ๋ฌธ๊ตฌ๋ก ํต์ผํฉ๋๋ค. โ์ฝ๋๊ฐ ์ฌ๋ฐ๋ฅด์ง ์์์. ์ ๋ ฅํ ์ฝ๋๋ฅผ ๋ค์ ํ์ธํด ์ฃผ์ธ์.โ
- ์ฃผ์: ๋คํธ์ํฌ ์คํจ๋ ์๋ฒ ErrorCode๋ก ๊ฐ์ฅํ์ง ์๊ณ ์ฑ ๋คํธ์ํฌ ์ํ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
์ด๋ฏธ์ง: 2026-10-14 232220
- ๋ชฉ์ : ์ํ ์ ์, ๊ธฐ๊ฐ, ๋ฑ๋ก ์ ์์๋๋ ์ด์ฉ ์กฐ๊ฑด์ ํ์ธํ ๋ค ์ฌ์ฉ์๊ฐ ๋ฑ๋ก์ ํ์ ํฉ๋๋ค.
- ๋ฐฑ์๋ ๋ฐ์ดํฐ: ์ํ๋ช /์ ์, ๋ฑ๋ก๊ธฐํ, ๋ฑ๋ก ์ฆ์ ์์๋ ํ์ฑํยท์ข ๋ฃ ์๊ฐ, ํด๋์ค ์์ฑ ์ ํ ์์.
- ํ๋ก ํธ ์ฒ๋ฆฌ: ํ์ธ ๋ฌธ๊ตฌยท๋ฒํผยท๋ฑ๋ก ํ ๊ธฐ๊ฐ์ด ๋๋๋ฆด ์ ์๋ค๋ ์ค๋ช .
- API: [๊ตฌํ ์๋ฃ] POST /api/v1/ticket-codes/claim.
- ์ธ์ฆ: ๋ก๊ทธ์ธ ํ์. Idempotency-Key ํค๋ ๊ถ์ฅ.
- ์ด๋: ์ฑ๊ณต ์ ๋ฑ๋ก ์๋ฃ, ์ค๋ณต ํญ์ ์ฒซ ๊ฒฐ๊ณผ ๋ฐํ.
- PRD/UI ์ฐจ์ด: UI ์์๋ 30์ธ ์ํ ํ๋์ง๋ง PRD๋ 5/15/30์ธ 3์ข ์ ์ ์ํฉ๋๋ค.
์ด๋ฏธ์ง: 2026-10-14 232308
- ๋ชฉ์ : ํ์ฑํ ๊ฒฐ๊ณผ์ ๊ณตํต ์ด์ฉ ์ข ๋ฃ์ผ์ ๋ณด์ฌ์ค๋๋ค.
- ๋ฐ์ดํฐ: ์ ์, activatedAt, expiresAt, ์ด์ฉ๊ถ ์ํ.
- ํ๋ก ํธ: โ์ด์ฉ๊ถ์ด ๋ฑ๋ก๋์ด์โ ๋ฑ ๊ณ ์ ๋ฌธ๊ตฌ์ ๋ฒํผ.
- ๋ฐฑ์๋: ๋ ์ง ๊ณ์ฐ๊ณผ ์ด์ฉ๊ถ ํ์ฑ ์ํ.
- ์ด๋: ์ด์ฉ๊ถ ํ์ธํ๊ธฐ ๋๋ ๋ง์ดํ์ด์ง.
- ์์ธ: ์ฌ์์ฒญ ์ ์ข ๋ฃ์ผ์ ๋ค์ ๊ณ์ฐํ๊ฑฐ๋ ์ฐ์ฅํ์ง ์์ต๋๋ค.
์ด๋ฏธ์ง: 2026-10-14 232329
- ๋ชฉ์ : ํ์ฌ ํ์ฑ ์ด์ฉ๊ถ์ ์ํยท๊ธฐ๊ฐยท์ ์์ ํ์ธํ๊ณ ์ถ๊ฐ ๋ฑ๋ก ํ๋ฆ์ ์ฝ๋๋ค.
- API: [๊ตฌํ ์๋ฃ] GET /api/v1/tickets/me.
- ์ธ์ฆ: ๋ก๊ทธ์ธ ํ์.
- ํ์ ๋ฐ์ดํฐ: ์ํ, ์ ์, ์ฌ์ฉ ๊ฐ๋ฅ ๊ธฐ๊ฐ, ํด๋์ค ์์ฑ ๊ฐ๋ฅ ์ฌ๋ถ.
- PRD/UI ์ฐจ์ด: PRD์ ๊ธฐ๋ณธ์์ ํ๋ฉ ์บ ํ์ธ ๊ธฐ์ค 1์ธ 1๊ฐ์ง๋ง UI์๋ โ์ด์ฉ๊ถ ์ถ๊ฐ๋ฑ๋กํ๊ธฐโ๊ฐ ์์ต๋๋ค. ์ถ๊ฐ ์บ ํ์ธ/๋ณต์ ๋ณด์ ์๋ฏธ์ธ์ง ์ถ์ ์ ํ์ ์ด ํ์ํฉ๋๋ค. UI๊ฐ ๋ณด์ ํ์ง ์์ ๋ฑ๋ก ์ฝ๋๋ฅผ ํ์ธํด ์ฃผ๋์ง ์ญ์ ํ์ฌ ๊ณ์ฝ์ ์์ต๋๋ค.
์ด๋ฏธ์ง: 2026-10-14 232458 ๋ฐ ์ด์ฉ๊ถ ํ๋ฉด 3์ข
- ๋ฉ๋ด๋ ์๋ฒ ์ํ๋ฅผ ๋ฐํ์ผ๋ก ๋ฑ๋ก ์๋ด/ํ์ฑ ์ด์ฉ๊ถ/๊ธฐ๊ฐ ์ข ๋ฃ ์ํ๋ก ๋ถ๊ธฐํฉ๋๋ค.
- โํ์ฌ ์ด์ฉ๊ถ ์์โ์ ์๋ฒ์์ NONE์ผ๋ก ๋ด๋ ค์ฃผ๋ฉฐ, Loading/Network Error๋ ์ฑ์ด ์ฒ๋ฆฌํฉ๋๋ค.
- UI์ ๋ฏธ๋ฑ๋กยท์ด์ฉ ์คยท๋ฑ๋ก๋ง๋ฃยท์ด์ฉ์ข ๋ฃ๊ฐ ํ์๋์ง๋ง, PRD์ ๊ตฌ๋งค์ ์ ๋ณด๋ ์ฝ๋ ๋ฑ๋ก ์ ์ฑ ๊ณ์ ๊ณผ ์ฐ๊ฒฐ๋์ง ์์ต๋๋ค. ๋ฑ๋ก ์ ์ด์ฉ๊ถ ์ํ๋ฅผ ํน์ ์ฌ์ฉ์์ P03 ํ๋ฉด์์ ๋ณด์ฌ์ฃผ๋ ๋ฐฉ๋ฒ์ ์ ์ฑ ํ์ธ์ด ํ์ํฉ๋๋ค.
ํ์ฌ ๊ด๋ฆฌ์ UI๋ ๋ณ๋ Next.js ์ฑ์ ์ฌ์ฉํฉ๋๋ค. ์๋๋ ์ฒจ๋ถ ์ด๋ฏธ์ง์์ ํ์ธ๋ ํด๋์ค ๊ด๋ฆฌ ํ๋ฉด 4์ข ์ ๋๋ค.
์ด๋ฏธ์ง: 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 ๋ด๋ณด๋ด๊ธฐ ์ ์ฉ ํํฐ.
์ด๋ฏธ์ง: 2026-10-14 233819
- ๋ชฉ์ : ๋ฐ๊ธ๋ ์ฝ๋, ์ํ ์ ์, ๋ฑ๋ก ์ฌ์ฉ์, ์ด์ฉ ๊ธฐ๊ฐ, ์ฐ๊ฒฐ ํด๋์ค ์๋ฅผ ๊ด๋ฆฌํฉ๋๋ค.
- ๋ฐ์ดํฐ: ์ ์ฒด ์ด์ฉ๊ถ/์ด์ฉ ์ค/๋ฏธ๋ฑ๋ก/๋ง๋ฃ ์๋ฐ ์นด๋, ์ฝ๋, ๊ตฌ๋งค์ ์ ๋ณด, ์ด์ฉ๊ถยท๋ฑ๋ก์, ๊ตฌ๋ถ, ๊ธฐ๊ฐ, ์์ฑ ํด๋์ค ์.
- ๊ฒ์/ํํฐ: ์ฝ๋ยท๊ตฌ๋งค์ยท๋ฑ๋ก์ ํค์๋, ์ํ ์ ์(5/15/30), ์ํ, ๋ฑ๋ก ๊ธฐ๊ฐ.
- ์ก์ : ์ด์ฉ๊ถ ์ฝ๋ ๋ฐ๊ธ, ์กฐํ, ํ์ด์ง ์ด๋.
- API: [๊ตฌํ ์๋ฃ] GET /api/v1/admin/tickets, POST /api/v1/admin/tickets/{ticketId}/codes.
- ๊ถํ: ADMIN.
- ๊ฐ์ธ์ ๋ณด: ์ด๋ฉ์ผ ๋ฑ์ ๊ธฐ๋ณธ ๋ง์คํน. ๋ฐ๊ธ ์๋ฃ ์งํ ์ฝ๋ ์๋ฌธ์ ์ ํ๋ ์ผํ ๋ ธ์ถ๋ก ์ ๋ฌํ๋ ์์ ๊ถ์ฅํฉ๋๋ค.
- ๋ ผ์: UI ํ์ ํ์๋ ์ ์ฒด ์ฝ๋ ๋ ธ์ถ๊ณผ ์ฝ๋ ์๋ฌธ ๋น์ ์ฅ ์์น ๊ฐ ์กฐ์ .
์ด๋ฏธ์ง: 2026-10-14 233945
- ๋ชฉ์ : ์ธ๋ถ ๊ตฌ๋งค์, ๋ฆฌ์๋, ์ฝ๋ ๋ฐ๊ธยท์ ๋ฌยท์ฑ ๋ฑ๋ก ์ํ๋ฅผ ์ด์ํฉ๋๋ค.
- ๋ฐ์ดํฐ: ๊ตฌ๋งค์ ์/์ฝ๋ ๋ฐ๊ธ/์ ๋ฌ ์๋ฃ/๋ฏธ์ ๋ฌ, ๊ตฌ๋งค์, ์ฐ๋ฝ์ฒ, ํ๋ฉ ์ฃผ๋ฌธ, ๊ตฌ๋งค ์ํ, ์ ๋ฌ ์ํ, ๋ฑ๋ก ์ํ.
- ๊ฒ์/ํํฐ: ์ด๋ฆยท์ด๋ฉ์ผยท์ ํ๋ฒํธ, ์ํ ์ ์, ์ ๋ฌ ์ํ, ๋ฑ๋ก ์ํ.
- ์ก์ : ๊ตฌ๋งค์ ๋ฑ๋ก, ์กฐํ, ์ ๋ฌ ๊ฒฐ๊ณผ ๊ฐฑ์ .
- API: [๊ตฌํ ์๋ฃ] GET /api/v1/admin/funding-orders, POST /api/v1/admin/funding-orders, ํ ๋ธ๋ฒ ๋ช ๋จ ์ํธ ํ์ธ/๋ฏธ๋ฆฌ๋ณด๊ธฐ/์ฝ๋ ํ์ผ ์์ฑ, PATCH ์ ๋ฌ ๊ฒฐ๊ณผ.
- ๊ถํ: ADMIN.
- ๊ฐ์ธ์ ๋ณด: ๊ตฌ๋งค์ ์ฐ๋ฝ์ฒ๋ ์ํธํ ์ ์ฅยท์๋ต ๋ง์คํน, ์ด๋์ ๊ด๋ฆฌ์ ๊ถํ ๋ฐ ๊ฐ์ฌ ๋ก๊ทธ ๋์.
- UI ์ฐจ์ด: ์ฒจ๋ถ ์ด๋ฏธ์ง๋ ๊ฐ๋ณ ๋ฑ๋ก ๋ฒํผ๊ณผ ๋ชฉ๋ก๋ง ๋ณด์ฌ์ค๋๋ค. ์์ ๋งคํยท๋ฏธ๋ฆฌ๋ณด๊ธฐยท๋์งํธ ์ ๋ฌผ ํ์ผ ๋ค์ด๋ก๋ ํ๋ฉด์ ๋ณ๋ ๊ด๋ฆฌ์ ํ๋ก ํธ์๋ ๊ตฌํ์ด ํ์ํฉ๋๋ค.
์ด๋ฏธ์ง: 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 ํ๋ฉด 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 ํ๋ฆ์ ๊ด๋ฆฌ์ ํ๋ฉด์ผ๋ก ๊ฐ์ ํ์ง ์์ต๋๋ค.
| ๊ตฌ์ฑ์์ | ์ฑ ์ |
|---|---|
| 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๋ ์ด๋ฒ ๊ตฌํ ๋์์ด ์๋๋๋ค.
ํ๋ก์ ํธ์๋ ๊ณตํต ์๋ต์ด ์ด๋ฏธ ์์ต๋๋ค.
{
"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์ ํด๋น ๋ด๋น ๋ฒ์์ ๋๋ค.
| ์ํ | 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๋ ๊ทธ๋๋ก ๋ก๋๋ค.
| ์ํ | 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=®isteredFrom=®isteredTo=&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 |
์ฝ๋ ๋ฏธ๋ฆฌ๋ณด๊ธฐ:
{
"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๋ ์๋ตํ๋ฏ๋ก, ์ ๋ฌธ๊ตฌ๋ฅผ ์๋ฒ์์ ์ ๊ณตํ ์ง ์ฑ ์์๋ก ๊ด๋ฆฌํ ์ง๋ ์ฑ ๊ฐ๋ฐ์์ ํฉ์ํฉ๋๋ค.
๋ชจ๋ ์ฃผ์ 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/ํ ์ด๋ธ๋ก ์ถ๊ฐํ์ง ์์ต๋๋ค.
- 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 ๋งคํยทํ๋ถ ๋ฒ์ยท์ ์ฑ ยท์ ๋ฌ ๊ธฐ๋กยท๊ฐ์ฌ ๋ฒ์๋ฅผ ํ์ ํด์ผ ํ๋ค๋ ๋ป์ ๋๋ค.
- 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 ์๋ฌธ์ ๊ด๋ฆฌ์ ๋ฐ๊ธ ์งํ ํ ๋ฒ๋ง ๋ฐํํฉ๋๋ค. ๋ถ์ค ์ ๊ธฐ์กด ๋ฏธ๋ฑ๋ก ์ฝ๋๋ฅผ ํ๊ธฐํ๊ณ ๊ฐ์ ์ด์ฉ๊ถยท๋ฑ๋ก๊ธฐํ์ผ๋ก ์ฌ๋ฐ๊ธํฉ๋๋ค.
- ADMIN์ด ๊ตฌ๋งค์/์ฃผ๋ฌธ/์ํ/๊ฒฐ์ ์๋ฃ ์ํ๋ฅผ ์๋ ๋ฑ๋กํฉ๋๋ค. ๋ชจ์ง ์ข ๋ฃ๋ ๋ชฉํ ๋ฌ์ฑ๋ง์ผ๋ก ๊ฒฐ์ ์๋ฃ ์ฒ๋ฆฌํ์ง ์์ต๋๋ค.
- ํ๋ซํผยท์บ ํ์ธยท์ฃผ๋ฌธยท๋ฆฌ์๋ ํ ๊ณ ์ ํค๋ก ์ค๋ณต ์ฃผ๋ฌธ์ ํ์ธํฉ๋๋ค.
- ๋ฆฌ์๋ ID๋ฅผ 5/15/30์ธ capacity๋ก ๋งคํํฉ๋๋ค. ๋ถ๋ช ํํ ๋ฆฌ์๋๋ ๋ณด๋ฅํฉ๋๋ค.
- ํ์ธ๋ ๊ฒฐ์ ์๋ฃ ํ์๋ง Ticket์ TicketCode๋ฅผ ๋ฐ๊ธํฉ๋๋ค.
- registerBy๋ ์ต์ข ๊ฒฐ์ ํ์ธ์ผ + ๋ฌ๋ ฅ ๊ธฐ์ค 1๋ ์ ๋๋ค.
- ์ ๋ฌ ์ํ๋ ๋ฐ๊ธ๊ณผ ๋ถ๋ฆฌํ์ฌ ๊ด๋ฆฌ์ ์ก์ /์ ๋ฌ ์๋ ๊ธฐ๋ก์ผ๋ก ๊ด๋ฆฌํฉ๋๋ค.
- ๋ก๊ทธ์ธ๊ณผ ์ ๋ ฅ ํ์์ ํ์ธํ๊ณ ์ฝ๋ ์ ๊ทํ ํ codeHash๋ก ์กฐํํฉ๋๋ค.
- Preview๋ ๋ฑ๋ก๊ธฐํ, ๊ฒฐ์ ์ํ, ์ฝ๋ ์ํ, ์์ ์ํ๋ง ๊ฒ์ฌํ๊ณ ์ฝ๋๋ฅผ ์๋นํ์ง ์์ต๋๋ค.
- Claim ํธ๋์ญ์ ์ TicketCode ํ์ PESSIMISTIC_WRITE๋ก ์ ๊ธ๋๋ค.
- User ํ๋ ์ ๊ทธ๊ณ ๋ณด์ ์ ํยท๊ธฐ์กด ๋์ผ ์์ฒญ์ ํ์ธํฉ๋๋ค.
- ์กฐ๊ฑด ํต๊ณผ ์ Ticket.ownerUser๋ฅผ ํ์ฌ ์ฌ์ฉ์๋ก ์ฐ๊ฒฐํ๊ณ activatedAt/ expiresAt์ ์ ์ฅํฉ๋๋ค. expiresAt์ activatedAt + ๋ฌ๋ ฅ ๊ธฐ์ค 6๊ฐ์์ ๋๋ค.
- TicketCode๋ CLAIMED๋ก ์ ์ดํฉ๋๋ค. codeยท์์ ์ยทํ์ฑยท์ข ๋ฃ ์๊ฐ์ ํ ํธ๋์ญ์ ์ผ๋ก ์ปค๋ฐํฉ๋๋ค.
- ๊ฐ์ ์ฌ์ฉ์์ ์ฌ์๋๋ ๊ธฐ์กด ๊ฒฐ๊ณผ ๋ฐํ. ํ ๊ณ์ ๊ฒฝ์์ ํ ์์ฒญ๋ง ์ฑ๊ณต.
- ํ๋ถ ํ์ ์ Funding์์ REVOKED ์ฒ๋ฆฌํฉ๋๋ค. Classroom ๋ฐ์ดํฐ ๋ณ๊ฒฝ์ด๋ ํ๋ ์ฐจ๋จ ๊ตฌํ์ ๋ณ๋ ์์ ๋ฒ์์ด๋ฉฐ, ํด๋์ค ์์ฑ ์ Funding ์ ํจ์ฑ ํ์ธ์ผ๋ก ์ ๊ท ์ฐ๊ฒฐ์ ๋ง์ต๋๋ค. ์ค๋๋ ๊ฒฐ์ ์ ๋ก๋๊ฐ ํ๋ถ์ ๋๋๋ฆฌ์ง ์๋๋ก ์ํ ์ ์ด ์ฐ์ ์์๋ฅผ ๋ก๋๋ค.
- Funding์ ์ฝ๋ ๋ฑ๋ก ํ
Ticket.ownerUser,capacity,activatedAt,expiresAt,status๋ฅผ ๋ณด์ ํฉ๋๋ค. - Classroom ๋ด๋น์๋ ํด๋์ค ์์ฑ ์ ๊ฐ์ ์ ํ๋ฆฌ์ผ์ด์
์
FundingTicketPolicy.requireUsableBy(userId, ticketId)๋ฅผ ํธ์ถํฉ๋๋ค. - ์ ์ฑ
์ ์์ ์ ์ผ์น,
ACTIVE, ํ์ฌ ์๊ฐ์ดexpiresAt์ด์ ์ธ์ง ๊ฒ์ฌํ๊ณFundingTicketAccess(capacity, expiresAt)์ ๋ฐํํฉ๋๋ค. - Classroom์ ์์ฒด Entity์
ticketId๋ฅผ ๋น๊ณ ์ FK๋ก ์ฐ๊ฒฐํฉ๋๋ค. ์ด์ฉ๊ถ ํ๋๋ก ๋ณต์ ํด๋์ค๋ฅผ ํ์ฉํ๋ฏ๋ก unique ์ ์ฝ์ ๋์ง ์์ต๋๋ค. - Funding์ Classroom์ ํ ์ด๋ธ/์ํ/๋ฉค๋ฒ์ญ์ ์ง์ ๋ณ๊ฒฝํ์ง ์์ต๋๋ค. ํ๋ถ ์ดํ ๊ธฐ์กด ํด๋์ค์์ ์ฐ๊ธฐ๋ฅผ ๋ง๋ ๋์์ ๋ณ๋ Class ๋ด๋น์๊ฐ Funding ์ํ๋ฅผ ์ฌ๊ฒ์ฆํ๋ ๋ฐฉ์์ผ๋ก ๊ฒฐ์ ํฉ๋๋ค.
์ด๋ฒ ๋ฒ์์์ ํด๋์ค ์์ฑ API, ํด๋์ค CRUD, ์ ์ฅ/๋ฉค๋ฒ/ํฌํ/๋๊ธ, ๋ฐฐํ ์นดํ๋ก๊ทธ, ์์ฝยท๋ฆฌํฌํธ API์ ๊ด๋ จ Entity/Service/Repository๋ฅผ ๊ตฌํํ์ง ์์ต๋๋ค. AI ๊ธฐ๋ฅ, AI API, AI ํ ์ด๋ธ, Provider Client์ Worker๋ ๊ตฌํํ์ง ์์ต๋๋ค.
| ์กฐ๊ฑด | 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๋ ์ฑ/๊ด๋ฆฌ์ ํ๋ฉด ๋ถ๊ธฐ ์์ค์
๋๋ค.
| ์ํ | ๊ฐ๊ฒฉ | ํด๋์ค๋ณ ์ ์ |
|---|---|---|
| 5์ธ | 9,900์ | ์ต๋ 5๋ช |
| 15์ธ | 19,900์ | ์ต๋ 15๋ช |
| 30์ธ | 29,900์ | ์ต๋ 30๋ช |
- ํ๋ฉ ๊ฒฐ์ ํ์ ํ 1๋ ์ด๋ด ์ฝ๋ ๋ฑ๋ก.
- ๋ฑ๋ก ํ์ธ ์ฑ๊ณต ์ 6๊ฐ์ ํ์ฑํ.
- ํ์ฑ ์ด์ฉ๊ถ ํ๋๋ก ํด๋์ค ์ ์ ํ ์์ด ์์ฑ.
- ์ํ ์ ์์ ํด๋์ค๋ณ๋ก ์ฌ์ ์ฉ๋๋ฉฐ ์ข์์ ์ด์ฉ๊ถ ์ ์ฒด์์ ์ฐจ๊ฐํ์ง ์์ต๋๋ค.
- ์ธ์ฑ๊ฒฐ์ , ๊ตฌ๋งค ๋ณต์, ์ฑ ๊ฒฐ์ SDK๋ ๊ตฌํ ๋ฒ์๊ฐ ์๋๋๋ค.
- ์/์ฃผ๋ณ ์์ฑ ์ ํ์ ๋์ง ์์ต๋๋ค.
- ์ฝ๋ ์ ๋ฌ๊ณผ ์ฝ๋ ๋ฑ๋ก์ ๋ณ๋ ์ํ์ ๋๋ค.
| ์ข ๋ฅ | ์ฉ๋ | ์ ์ฑ |
|---|---|---|
| TicketCode | ์ ๋ฃ ํ๋ฉ ๋ฆฌ์๋๋ฅผ ๊ณ์ ์ด์ฉ๊ถ์ผ๋ก ์ฐ๊ฒฐ | ์ถฉ๋ถํ ๋์, ํด์ ์ ์ฅ, ๋ก๊ทธ์ธ ์ฌ์ฉ์๋ง ๋ฑ๋ก |
| ํด๋์ค ์ฐธ์ฌ ์ฝ๋(ParticipationCode)๋ ๋ณ๋ Classroom ๋ด๋น ๋ฒ์์ ๋๋ค. Funding์ TicketCode๋ง ๋ฐ๊ธยท์กฐํยท๋ฑ๋กํ๋ฉฐ ์ฐธ์ฌ ์ฝ๋ API/Entity๋ฅผ ์ถ๊ฐํ์ง ์์ต๋๋ค. |
- ๊ด๋ฆฌ์๊ฐ ๊ณต์ ํ๋ฉ ๋ช ๋จ์ ๋์กฐํด ๊ตฌ๋งค ์ฃผ๋ฌธ๊ณผ ๊ฒฐ์ ํ์ ์ฌ๋ถ๋ฅผ ๊ธฐ๋กํฉ๋๋ค.
- ์ํ ๋ฆฌ์๋ ID๋ฅผ ์ ์ 5/15/30์ผ๋ก ๋งคํํฉ๋๋ค.
- ADMIN์ด ์ด์ฉ๊ถ๊ณผ ๋ฑ๋ก ์ฝ๋๋ฅผ ๋ฐ๊ธํฉ๋๋ค.
- ๊ด๋ฆฌ์ ํ๋ฉด์์ ๋ฐ๊ธ ์ฝ๋๋ฅผ ์ผํ ํ์ธํด ์ฌ์ฉ์๊ฐ ์๋ ์ ๋ฌํ๊ฑฐ๋, ์ ๋ฌ ์ฑ๋/์๋ฃ ์ํ๋ง ๊ธฐ๋กํฉ๋๋ค.
- ๊ฒฐ์ ์คํจยท์ทจ์ยทํ๋ถ์ ๋ฐ๊ธ ๋ณด๋ฅ ๋๋ ํ๊ธฐํฉ๋๋ค.
- ๋ฏธ์ฌ์ฉ ์ฝ๋ ์ฌ๋ฐ๊ธ์ ๊ธฐ์กด ์ฝ๋๋ฅผ ํ๊ธฐํ๊ณ 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 ๊ตฌํ ๊ธฐ๋ณธ์์ด๋ฉฐ ๋ณด๊ด ์ ์ฑ ์น์ธ์ด ํ์ํฉ๋๋ค.
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๊ฐ ์ ํ ๊ฐ ์๋ฏธ๋ ์ฑ/๊ธฐํ ํ์ธ ํญ๋ชฉ์ ๋๋ค.
ํ์ธ์ผ์ 2026-10-15์ ๋๋ค. ํ ๋ธ๋ฒ ๊ณต์ ๋์๋ง์์ ์ฐฝ์์๋ ํ์์ ๊ด๋ฆฌ์ ๋ฐ์ดํฐ๋ฅผ Excel๋ก ๋ฉ์ผ ๋ฐ์ก ๋ฐ์ ์ ์๊ณ , ๋์งํธ ์ ๋ฌผ ์ ๋ฌ์์๋ ํ ํ๋ฆฟ์ ํ์๋ฒํธ๋ฅผ ์ ์ xlsx ์ ๋ก๋๊ฐ ๊ฐ๋ฅํ ๊ฒ์ ํ์ธํ์ต๋๋ค. ๊ณต์ ๊ณต๊ฐ ์๋ฃ์์ ์ฐฝ์์์ฉ ํ์์/๊ฒฐ์ ์กฐํ API์ endpoint, ์ธ์ฆ ๋ฐฉ์, webhook, rate limit์ ํ์ธ๋์ง ์์์ต๋๋ค. ๋ฐ๋ผ์ API ์ ๊ณต์ ๋จ์ ํ์ง ์๊ณ , ํ ๋ธ๋ฒ ์ง์/๊ณ์ฝ์ ํตํด API ์ด์ฉ ๊ฐ๋ฅ์ฑ๊ณผ ๋ฒ์๋ฅผ ๋ณ๋ ํ์ธํด์ผ ํฉ๋๋ค.
| ๋ฐฉ์ | ํ์ฌ ๊ฒฐ์ | ์ด์ ๋ฐฉ์ |
|---|---|---|
| ํ ๋ธ๋ฒ API | ๋ณด๋ฅ | ๊ณต์ ๊ณต๊ฐ ์๋ฃ์์ ์ฐฝ์์ ํ์ยท๊ฒฐ์ ์กฐํ API๋ฅผ ํ์ธํ์ง ๋ชปํ์ต๋๋ค. ์ ๊ทผ ๊ถํ๊ณผ ๋ฐ์ดํฐ ๋ฒ์๋ฅผ ๊ณต์ ์ ํด ๋ฌธ์๋ก ํ์ธํ๊ธฐ ์ ์๋ ์ฐ๋์ ์ ์ ํ์ง ์์ต๋๋ค. |
| ๋ช ๋จ Excel | ์ฌ๋ ๊ฒํ + ์๋ฒ ํ์ฑ | ์ด์์๊ฐ ํ ๋ธ๋ฒ ์์ ์ง์ ์์ฒญยท๋ค์ด๋ก๋ํฉ๋๋ค. ๊ด๋ฆฌ์๋ ๋ฆฌ์๋ ์ํธ๋ง ์ ํํ๊ณ ์๋ฒ๊ฐ ํค๋ ํ๊ณผ ํ๋ฉด์ 9๊ฐ ์ด์ ์๋ ํ๋ณํฉ๋๋ค. ๋ฏธ๋ฆฌ๋ณด๊ธฐ์์ ๊ฒฐ์ ์ํยท์ค๋ณตยท์๋์ ๊ฒํ ํฉ๋๋ค. |
| ํฝ์ผ ์ฃผ๋ฌธ ๋ฑ๋กยท๋ฐ๊ธ | ์๋ฒ ์ฒ๋ฆฌ, ๊ด๋ฆฌ์ ์น์ธ | ํ์ ์์ ์์ ์ ํจ ํ๋ง ์ฃผ๋ฌธยทํฐ์ผยท์ฝ๋๋ก ์์ฑํ๊ณ , ํ์๋ฒํธ์ ์ฝ๋ ํ ์คํธ๋ฅผ ์ฐ๊ฒฐํ XLSX๋ฅผ ๋ฐํํฉ๋๋ค. ์๋ฌธ ์ฝ๋๋ DB์ ์ ์ฅํ์ง ์์ต๋๋ค. |
| ํ ๋ธ๋ฒ ์ ๋ฌยท์ํ ๋๊ธฐํ | ์ฌ๋ ์ฒ๋ฆฌ | ์ด์์๊ฐ ํ ๋ธ๋ฒ ๋์งํธ ์ ๋ฌผ ๊ด๋ฆฌ์ ํ ์คํธ ํ์ผ์ ์ ๋ก๋ํ๊ณ , ์ ๋ก๋ ๊ฒฐ๊ณผ๋ฅผ ์๋ฒ์ ํ์๋ฒํธ ๋ชฉ๋ก์ผ๋ก ๊ธฐ๋กํฉ๋๋ค. ์ค์๊ฐ API ๋๊ธฐํ๋ ์์ต๋๋ค. |
ํ์ฌ ์ด์ ํ๋ฆ์ ํ
๋ธ๋ฒ
Excel ๋ค์ด๋ก๋ โ ์๋ฒ ์ํธ ์ ํยท์ด ์๋ ํ๋ณ ๋ฐ ๋ฏธ๋ฆฌ๋ณด๊ธฐ โ ๊ด๋ฆฌ์ ํ์ธ โ ์ ํจ ํ์ ํ ์ ์ฅยท๊ฒฐ์ ์๋ฃ ํ ์ฝ๋ ๋ฐ๊ธ ๋ฐ ํ
๋ธ๋ฒ
์
๋ก๋ ํ์ผ ๋ค์ด๋ก๋ โ ํ
๋ธ๋ฒ
๋์งํธ ์ ๋ฌผ ์
๋ก๋ โ ์๋ฒ์ ์ ๋ฌ ๊ฒฐ๊ณผ ๊ธฐ๋ก์
๋๋ค. ํ๋ซํผ๊ณผ ์๋ฒ ์ฌ์ด์ API ์๋ ๋๊ธฐํ๋ ํฌํจํ์ง ์์ต๋๋ค.
์ฃผ์: ๊ณต์ ๋์๋ง์ ๋์งํธ ์ ๋ฌผ Excel ๊ธฐ๋ฅ์ ํ ๋ธ๋ฒ ๋ด๋ถ์์ ์ ๋ฌผ์ ์ ๋ฌํ๋ ๊ธฐ๋ฅ์ ๋๋ค. ํฝ์ผ ์์ฒด ๊ตฌ๋งค์/์ฝ๋ DB์ ์๋ ๋๊ธฐํ๋๋ API๋ก ์ทจ๊ธํ์ง ์์ต๋๋ค.
| ๊ธฐ๋ฅ | ํ์ธ ๊ฒฐ๊ณผ |
|---|---|
| ํด๋์ค ๋ชฉ๋ก/๊ฒ์/์ํยท์ํยท๋ฐฐํ ์ ํ ํํฐ | ์์ (๋ณ๋ 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 ์ต์ํ/๋ง์คํน.
- ์ฝ๋ ์๋ฌธ์ ๋ชฉ๋ก์์ ๊ธฐ๋ณธ ๋ง์คํนํ๊ณ ๋ฐ๊ธ ๋๋ง ํ ๋ธ๋ฒ ์ ๋ก๋์ฉ ๋ค์ด๋ก๋ ํ์ผ์ ๋ด์ต๋๋ค. ํ์ผ ์๋ต์ ์บ์ํ์ง ์์ต๋๋ค. ํ๋ฉด์์ ๊ฐ๋ณ ์ฝ๋ ๋ฐ๊ธ ์์๋ ์๋ต์ ํ ๋ฒ ํ์ํฉ๋๋ค.
๊ด๋ฆฌ์ ํ๋ฉด ๊ตฌํ์ ํ์ํ 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 ๋ด๋น ๋ฒ์์ ๋๋ค.
- ํ์ฌ 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, ์๊ฐ์ ๊ธฐ๋กํฉ๋๋ค.
- ๊ณ ์ ํ ์คํธ/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 ๋ฌธ๊ตฌ, ํ๋ฉด์์ ์ธ ์ด์ฉ๊ถ ์ํ/์ฝ๋ ๋ช ์นญ.
- ๊ณตํต ์ฑ๊ณต ์๋ต์ 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 ๋ด๋น ๋ฒ์์์ ๋ ผ์ํฉ๋๋ค.
- ์๋ฒ pagination/filter/sort ์ฑํ ๋ฐ size ์ํ, ๊ธฐ๋ณธ ์ ๋ ฌ.
- ๊ฒ์ ๋ฒํผ ๊ธฐ๋ฐ ์กฐํ์ธ์ง debounce ๊ฒ์์ธ์ง. ํ ์์์ ์กฐํ ๋ฒํผ์ ๋ณด์ด๋ฏ๋ก ๋ช ์์ ์กฐํ๋ฅผ ๊ธฐ๋ณธ์์ผ๋ก ๋ก๋๋ค.
- ๋ ์ง ๊ฒ์์ ์๊ฐ๋/๋ ๋ ์ง ํฌํจ ์ฌ๋ถ.
- ์ด์ฉ๊ถ ์ํ/๊ฒฐ์ ์ํ/์ ๋ฌ ์ํ Enum ํ์๋ช .
- ๊ตฌ๋งค์ ์ฐ๋ฝ์ฒยท์ด์ฉ๊ถ ์ฝ๋ ๋ง์คํน ๋ฐ ์์ธ ์ด๋ ๊ฐ์ฌ.
- โ๊ตฌ๋งค์ ๋ฑ๋กโ ์ ๋ ฅ ํ๋์ ๊ฒฐ์ ์๋ฃ ์ฆ๋น ๋ฐฉ์.
- ์ฝ๋ ๋ฐ๊ธ ์งํ ์๋ฌธ์ ์ผํ ํ์ยท๋ณต์ฌํ๋ ๋ชจ๋ฌ.
- ์ ๋ฌ ์คํจ ๊ธฐ๋ก๊ณผ ์ฌ์ ๋ฌ/์ฌ๋ฐ๊ธ์ ๊ตฌ๋ณ.
- ์ทจ์/ํ๋ถ์ ๋ฌผ๋ฆฌ ์ญ์ ๋์ REVOKED ์ํ๋ก ๋ณด์กด.
- CSV ํํฐ ์ ์ฉ, ๋ค์ด๋ก๋ ์ธ๊ฐ, ํฌํจ ์ปฌ๋ผ/PII.
- ๋ช ๋จ Excel์ ์ด์์๊ฐ ํ ๋ธ๋ฒ ์์ ์ง์ ๋ด๋ ค๋ฐ์ ๊ด๋ฆฌ์ ๊ธฐ๋ฅ์ ์ ๋ก๋ํฉ๋๋ค. ์ํธ๋ฅผ ์ ํํ๋ฉด ์๋ฒ๊ฐ 9๊ฐ ์ด์ ์๋ ํ๋ณํ๊ณ , ์ด์์๋ ๋ฏธ๋ฆฌ๋ณด๊ธฐ์์ ๊ฒฐ์ ์ํ๋ฅผ ํ์ธํ ๋ค ์ ์ฅยท์ฝ๋ ๋ฐ๊ธ์ ์งํํฉ๋๋ค.
- ํด๋์ค ์์ธ/์ด์ ํ๋ฉด์ ๋ณ๋ Classroom ๋ด๋น ๋ฒ์์ ๋๋ค.
| ์ํ | ๋ฐฑ์๋ ํํ | ํ๋ฉด ์ฒ๋ฆฌ |
|---|---|---|
| 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ยท๋คํธ์ํฌ ๋จ์ ยทํ ์คํธยท์ ์ ์๋ด ๋ฌธ๊ตฌ๋ ๊ฐ ํ๋ก ํธ์๋์์ ์ฒ๋ฆฌํฉ๋๋ค.
์ค๋ฅ ํ๋ฉด์ ํ์๋ ๊ตฌ ๋ฌธ๊ตฌ๋ ์ฌ์ฉํ์ง ์์ต๋๋ค. ๋ฌธ์์ API ์์์ ์๋ ๋ฌธ๊ตฌ๋ง ์ฌ์ฉํฉ๋๋ค.
์ฝ๋๊ฐ ์ฌ๋ฐ๋ฅด์ง ์์์.
์ ๋ ฅํ ์ฝ๋๋ฅผ ๋ค์ ํ์ธํด ์ฃผ์ธ์.
๊ถ์ฅ API๋ ์์ ์ ์ธ Funding ErrorCode๋ฅผ ๋ฐํํ๊ณ App์ด ๋ฌธ๊ตฌ๋ฅผ ๋งคํํ๋ ๋ฐฉ์์ ๋๋ค. ํ์ฌ ๊ณตํต ์ค๋ฅ ์๋ต์ message๋ ํฌํจํ๋ฏ๋ก, server message๋ฅผ ํ์ํ ์ง App ๋ฒ์ญ ์์๋ก ๊ด๋ฆฌํ ์ง๋ ์ฑ ๊ฐ๋ฐ์ ํ์ ํญ๋ชฉ์ ๋๋ค.
์ด๋ฒ ๊ตฌํ 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๋ก ๊ณ์ฐํ์ง ์์ต๋๋ค.
- User (๊ธฐ์กด): ๋ก๊ทธ์ธ ์ฌ์ฉ์ ๋ฐ ์์คํ ์ญํ .
- FundingCampaign: ํ๋ฉ ํ๋ซํผ ์บ ํ์ธ๊ณผ ์ํ ๋งคํ.
- FundingOrder: ๊ฒฐ์ ํ์ ์ฃผ๋ฌธ/๋ฆฌ์๋ ํ๊ณผ ์ต์ ๊ตฌ๋งค์ ์ ๋ณด.
- Ticket: ์ ์ยท๋ฑ๋ก ๊ธฐํยท๊ณ์ ๊ท์ยทํ์ฑ/๋ง๋ฃ ๊ถํ.
- TicketCode: ์ด์ฉ๊ถ claim์ฉ ๋น๋ฐ ์ฝ๋์ ํด์์ ์ํ.
- DeliveryAttempt: ์ฝ๋ ์ ๋ฌ ์๋ ๋ฐ ์คํจ ๊ฒฐ๊ณผ.
- AdminAuditLog: Funding ๊ด๋ จ ๋ฏผ๊ฐํ ๊ด๋ฆฌ์ ๋ณ๊ฒฝ ์ด๋ ฅ.
Classroom์ ๋ณ๋ ๊ฐ๋ฐ์๊ฐ ์์ ํฉ๋๋ค. Funding ๊ตฌํ์ ๋ณ๋ ํด๋์ค Entity๋ฅผ ๋ง๋ค์ง ์๊ณ , ๊ธฐ์กด Classroom์ ticketId ์ฐธ์กฐ์ ์์ฑ ์ Funding ์ ํจ์ฑ ํ์ธ๋ง ์ฐ๊ฒฐํฉ๋๋ค. AI ๊ด๋ จ Entity๋ ๋ง๋ค์ง ์์ต๋๋ค.
Funding, Classroom ์ต์ ์ฐ๋, ๊ธฐ์กด User/Auth/Admin ๊ณตํต ๊ธฐ๋ฐ.
User(๊ธฐ์กด), FundingCampaign, FundingOrder, Ticket, TicketCode, DeliveryAttempt, AdminAuditLog. Classroom์ ๋ณ๋ ๋ด๋น์ ๊ธฐ์กด Entity์ ticketId ์ฐ๊ฒฐ๋ง ํฉ์ํฉ๋๋ค.
FundingTicketService, FundingAdminService, FundingTicketPolicy (๋ด๋ถ ์ฐ๋ ๊ณ์ฝ).
์ด์ฉ๊ถ: 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 ๋ด๋น์:
ticketIdFK ์์ ๊ถ, ํด๋์ค ์์ฑ ์ Funding ์ ์ฑ ํธ์ถ ์ง์ ๊ณผ ํ๋ถ ์ํ ์ฌ๊ฒ์ฆ ๋ฐฉ์. - ๊ด๋ฆฌ์ ํ๋ก ํธ์๋: ์ฝ๋ ์๋ฌธ ๋ ธ์ถ/๋ง์คํน, ๊ตฌ๋งค์ ์ฐ๋ฝ์ฒ ์ ๊ทผ, ์ ๋ฌ ์คํจ/์ฌ๋ฐ๊ธ ํ๋ฆ, CSV ํ๋.
- ๊ธฐํ/์ด์: ํ๋ซํผ ์ ํ, ๊ฒฐ์ ํ์ ์ฆ๋น, ํ๋ถ ์ ์ฑ , ๊ตฌ๋งค์ ๋ฐ์ดํฐ ๋ณด์ ๊ธฐ๊ฐ, Excel ์์ .
- P0: ๊ตฌ๋งค์/์ฃผ๋ฌธ ์๋ ๋ฑ๋ก, ๊ฒฐ์ ์ํ ํ์ธ, ์ด์ฉ๊ถยท์ฝ๋ ๋ฐ๊ธ๊ณผ claim, ์ ๋ฌ ์ํ, ๊ด๋ฆฌ์ Funding ์กฐํ, Classroom ์ ํจ์ฑ ์ ์ฑ
๊ณ์ฝ ๋ฐ
ticketId์ฐ๊ฒฐ. - P1: Funding ์ด์ ์๋ฆผยท๋ง๋ฃ ์๋ํ, ์ฌ๋ฐ๊ธ/ํ๋ถ ๋ณด์กฐ ํ๋ฆ, ๊ฐ์ธ์ ๋ณด ๋ณด๊ดยทํ๊ธฐ ์๋ํ.
- ๋ณด๋ฅ: ํ ๋ธ๋ฒ ๊ณต์ ํ๋ซํผ API ์ฐ๋/์๋ ๋๊ธฐํ์ ์๋ ์ ๋ฌ. ๋ช ๋จ ํ์ผ ๊ธฐ๋ฐ์ ์ฌ๋ ๊ฒํ ํ ๊ฐ์ ธ์ค๊ธฐ/์ฝ๋ ํ์ผ ์์ฑ API๋ ๊ตฌํ ๋์์ ํฌํจํฉ๋๋ค.
- ์ฌ์ฉ์ 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 ์ ์ฝ๊ณผ ํธ๋์ญ์ ์ ๊ธฐ์ค์ผ๋ก ํฉ๋๋ค.