mirror of
https://github.com/ktds-dg0501/kt-event-marketing.git
synced 2025-12-06 10:46:23 +00:00
- 공통 OpenAPI 3.0.3 컨벤션 문서 작성 (design/backend/api/API_CONVENTION.md) - 7개 서비스 API 명세서 표준화 완료: * User Service (8081) * Event Service (8080) * Content Service (8082) * AI Service (8083) * Participation Service (8084) * Distribution Service (8085) * Analytics Service (8086) 주요 변경사항: - API 경로에서 /api prefix 제거 (/api/users → /users) - 서버 URL 패턴 통일 (Local → Dev → Prod) - 연락처 정보 표준화 (Digital Garage Team) - ErrorResponse 스키마 통일 (error → message, details 추가) - securitySchemes 이름 통일 (BearerAuth) - 포트 번호 명확히 할당 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
821 lines
25 KiB
YAML
821 lines
25 KiB
YAML
openapi: 3.0.3
|
|
info:
|
|
title: Participation Service API
|
|
description: |
|
|
이벤트 참여 및 당첨자 관리 서비스 API
|
|
- 이벤트 참여 등록
|
|
- 참여자 목록 조회 및 관리
|
|
- 당첨자 추첨 및 관리
|
|
version: 1.0.0
|
|
contact:
|
|
name: Digital Garage Team
|
|
email: support@kt-event-marketing.com
|
|
|
|
servers:
|
|
- url: http://localhost:8084
|
|
description: Local Development Server
|
|
- url: https://dev-api.kt-event-marketing.com/participation/v1
|
|
description: Development Server
|
|
- url: https://api.kt-event-marketing.com/participation/v1
|
|
description: Production Server
|
|
|
|
tags:
|
|
- name: participation
|
|
description: 이벤트 참여 관리
|
|
- name: participant
|
|
description: 참여자 조회 및 관리
|
|
- name: winner
|
|
description: 당첨자 추첨 및 관리
|
|
|
|
paths:
|
|
/events/{eventId}/participate:
|
|
post:
|
|
tags:
|
|
- participation
|
|
summary: 이벤트 참여
|
|
description: |
|
|
고객이 이벤트에 참여합니다.
|
|
- 중복 참여 검증 (전화번호 기반)
|
|
- 이벤트 진행 상태 검증
|
|
- Kafka 이벤트 발행 (ParticipantRegistered)
|
|
operationId: participateEvent
|
|
x-user-story: UFR-PART-010
|
|
x-controller: ParticipationController
|
|
parameters:
|
|
- name: eventId
|
|
in: path
|
|
required: true
|
|
description: 이벤트 ID
|
|
schema:
|
|
type: string
|
|
example: "evt_20250123_001"
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ParticipationRequest'
|
|
examples:
|
|
standard:
|
|
summary: 일반 참여
|
|
value:
|
|
name: "홍길동"
|
|
phoneNumber: "010-1234-5678"
|
|
email: "hong@example.com"
|
|
agreeMarketing: true
|
|
agreePrivacy: true
|
|
storeVisited: false
|
|
storeVisit:
|
|
summary: 매장 방문 참여
|
|
value:
|
|
name: "김철수"
|
|
phoneNumber: "010-9876-5432"
|
|
email: "kim@example.com"
|
|
agreeMarketing: false
|
|
agreePrivacy: true
|
|
storeVisited: true
|
|
responses:
|
|
'201':
|
|
description: 참여 성공
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ParticipationResponse'
|
|
examples:
|
|
success:
|
|
summary: 참여 성공
|
|
value:
|
|
success: true
|
|
message: "이벤트 참여가 완료되었습니다"
|
|
data:
|
|
participantId: "prt_20250123_001"
|
|
eventId: "evt_20250123_001"
|
|
name: "홍길동"
|
|
phoneNumber: "010-1234-5678"
|
|
email: "hong@example.com"
|
|
participatedAt: "2025-01-23T10:30:00Z"
|
|
storeVisited: false
|
|
bonusEntries: 1
|
|
'400':
|
|
description: 잘못된 요청
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
examples:
|
|
invalidPhone:
|
|
summary: 유효하지 않은 전화번호
|
|
value:
|
|
success: false
|
|
error:
|
|
code: "INVALID_PHONE_NUMBER"
|
|
message: "유효하지 않은 전화번호 형식입니다"
|
|
duplicateParticipation:
|
|
summary: 중복 참여
|
|
value:
|
|
success: false
|
|
error:
|
|
code: "DUPLICATE_PARTICIPATION"
|
|
message: "이미 참여하신 이벤트입니다"
|
|
'404':
|
|
description: 이벤트를 찾을 수 없음
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
examples:
|
|
notFound:
|
|
summary: 이벤트 없음
|
|
value:
|
|
success: false
|
|
error:
|
|
code: "EVENT_NOT_FOUND"
|
|
message: "이벤트를 찾을 수 없습니다"
|
|
'409':
|
|
description: 이벤트 진행 불가 상태
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
examples:
|
|
notActive:
|
|
summary: 진행중이 아닌 이벤트
|
|
value:
|
|
success: false
|
|
error:
|
|
code: "EVENT_NOT_ACTIVE"
|
|
message: "현재 참여할 수 없는 이벤트입니다"
|
|
|
|
/events/{eventId}/participants:
|
|
get:
|
|
tags:
|
|
- participant
|
|
summary: 참여자 목록 조회
|
|
description: |
|
|
이벤트의 참여자 목록을 조회합니다.
|
|
- 페이징 지원
|
|
- 참여일시 기준 정렬
|
|
- 매장 방문 여부 필터링
|
|
operationId: getParticipants
|
|
x-user-story: UFR-PART-020
|
|
x-controller: ParticipantController
|
|
parameters:
|
|
- name: eventId
|
|
in: path
|
|
required: true
|
|
description: 이벤트 ID
|
|
schema:
|
|
type: string
|
|
example: "evt_20250123_001"
|
|
- name: page
|
|
in: query
|
|
description: 페이지 번호 (0부터 시작)
|
|
schema:
|
|
type: integer
|
|
default: 0
|
|
minimum: 0
|
|
example: 0
|
|
- name: size
|
|
in: query
|
|
description: 페이지 크기
|
|
schema:
|
|
type: integer
|
|
default: 20
|
|
minimum: 1
|
|
maximum: 100
|
|
example: 20
|
|
- name: storeVisited
|
|
in: query
|
|
description: 매장 방문 여부 필터
|
|
schema:
|
|
type: boolean
|
|
example: true
|
|
responses:
|
|
'200':
|
|
description: 조회 성공
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ParticipantListResponse'
|
|
examples:
|
|
success:
|
|
summary: 참여자 목록
|
|
value:
|
|
success: true
|
|
message: "참여자 목록을 조회했습니다"
|
|
data:
|
|
participants:
|
|
- participantId: "prt_20250123_001"
|
|
name: "홍길동"
|
|
phoneNumber: "010-1234-5678"
|
|
email: "hong@example.com"
|
|
participatedAt: "2025-01-23T10:30:00Z"
|
|
storeVisited: false
|
|
bonusEntries: 1
|
|
isWinner: false
|
|
- participantId: "prt_20250123_002"
|
|
name: "김철수"
|
|
phoneNumber: "010-9876-5432"
|
|
email: "kim@example.com"
|
|
participatedAt: "2025-01-23T11:15:00Z"
|
|
storeVisited: true
|
|
bonusEntries: 2
|
|
isWinner: true
|
|
pagination:
|
|
currentPage: 0
|
|
pageSize: 20
|
|
totalElements: 156
|
|
totalPages: 8
|
|
hasNext: true
|
|
hasPrevious: false
|
|
'404':
|
|
description: 이벤트를 찾을 수 없음
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
|
|
/events/{eventId}/participants/{participantId}:
|
|
get:
|
|
tags:
|
|
- participant
|
|
summary: 참여자 상세 조회
|
|
description: 특정 참여자의 상세 정보를 조회합니다.
|
|
operationId: getParticipantDetail
|
|
x-user-story: UFR-PART-020
|
|
x-controller: ParticipantController
|
|
parameters:
|
|
- name: eventId
|
|
in: path
|
|
required: true
|
|
description: 이벤트 ID
|
|
schema:
|
|
type: string
|
|
example: "evt_20250123_001"
|
|
- name: participantId
|
|
in: path
|
|
required: true
|
|
description: 참여자 ID
|
|
schema:
|
|
type: string
|
|
example: "prt_20250123_001"
|
|
responses:
|
|
'200':
|
|
description: 조회 성공
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ParticipantDetailResponse'
|
|
examples:
|
|
success:
|
|
summary: 참여자 상세 정보
|
|
value:
|
|
success: true
|
|
message: "참여자 정보를 조회했습니다"
|
|
data:
|
|
participantId: "prt_20250123_001"
|
|
eventId: "evt_20250123_001"
|
|
name: "홍길동"
|
|
phoneNumber: "010-1234-5678"
|
|
email: "hong@example.com"
|
|
participatedAt: "2025-01-23T10:30:00Z"
|
|
storeVisited: false
|
|
bonusEntries: 1
|
|
agreeMarketing: true
|
|
agreePrivacy: true
|
|
isWinner: false
|
|
winnerInfo: null
|
|
'404':
|
|
description: 참여자를 찾을 수 없음
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
examples:
|
|
notFound:
|
|
summary: 참여자 없음
|
|
value:
|
|
success: false
|
|
error:
|
|
code: "PARTICIPANT_NOT_FOUND"
|
|
message: "참여자를 찾을 수 없습니다"
|
|
|
|
/events/{eventId}/draw-winners:
|
|
post:
|
|
tags:
|
|
- winner
|
|
summary: 당첨자 추첨
|
|
description: |
|
|
이벤트 당첨자를 추첨합니다.
|
|
- 랜덤 추첨 알고리즘 사용
|
|
- 매장 방문 보너스 가중치 적용
|
|
- 중복 당첨 방지
|
|
operationId: drawWinners
|
|
x-user-story: UFR-PART-030
|
|
x-controller: WinnerController
|
|
parameters:
|
|
- name: eventId
|
|
in: path
|
|
required: true
|
|
description: 이벤트 ID
|
|
schema:
|
|
type: string
|
|
example: "evt_20250123_001"
|
|
requestBody:
|
|
required: true
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/DrawWinnersRequest'
|
|
examples:
|
|
standard:
|
|
summary: 일반 추첨
|
|
value:
|
|
winnerCount: 10
|
|
applyStoreVisitBonus: true
|
|
responses:
|
|
'200':
|
|
description: 추첨 성공
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/DrawWinnersResponse'
|
|
examples:
|
|
success:
|
|
summary: 추첨 완료
|
|
value:
|
|
success: true
|
|
message: "당첨자 추첨이 완료되었습니다"
|
|
data:
|
|
eventId: "evt_20250123_001"
|
|
totalParticipants: 156
|
|
winnerCount: 10
|
|
drawnAt: "2025-01-24T15:00:00Z"
|
|
winners:
|
|
- participantId: "prt_20250123_002"
|
|
name: "김철수"
|
|
phoneNumber: "010-9876-5432"
|
|
rank: 1
|
|
- participantId: "prt_20250123_045"
|
|
name: "이영희"
|
|
phoneNumber: "010-5555-1234"
|
|
rank: 2
|
|
- participantId: "prt_20250123_089"
|
|
name: "박민수"
|
|
phoneNumber: "010-7777-8888"
|
|
rank: 3
|
|
'400':
|
|
description: 잘못된 요청
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
examples:
|
|
invalidCount:
|
|
summary: 잘못된 당첨자 수
|
|
value:
|
|
success: false
|
|
error:
|
|
code: "INVALID_WINNER_COUNT"
|
|
message: "당첨자 수가 참여자 수보다 많습니다"
|
|
'404':
|
|
description: 이벤트를 찾을 수 없음
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
'409':
|
|
description: 이미 추첨 완료
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
examples:
|
|
alreadyDrawn:
|
|
summary: 추첨 완료 상태
|
|
value:
|
|
success: false
|
|
error:
|
|
code: "ALREADY_DRAWN"
|
|
message: "이미 당첨자 추첨이 완료되었습니다"
|
|
|
|
/events/{eventId}/winners:
|
|
get:
|
|
tags:
|
|
- winner
|
|
summary: 당첨자 목록 조회
|
|
description: |
|
|
이벤트의 당첨자 목록을 조회합니다.
|
|
- 당첨 순위별 정렬
|
|
- 페이징 지원
|
|
operationId: getWinners
|
|
x-user-story: UFR-PART-030
|
|
x-controller: WinnerController
|
|
parameters:
|
|
- name: eventId
|
|
in: path
|
|
required: true
|
|
description: 이벤트 ID
|
|
schema:
|
|
type: string
|
|
example: "evt_20250123_001"
|
|
- name: page
|
|
in: query
|
|
description: 페이지 번호 (0부터 시작)
|
|
schema:
|
|
type: integer
|
|
default: 0
|
|
minimum: 0
|
|
example: 0
|
|
- name: size
|
|
in: query
|
|
description: 페이지 크기
|
|
schema:
|
|
type: integer
|
|
default: 20
|
|
minimum: 1
|
|
maximum: 100
|
|
example: 20
|
|
responses:
|
|
'200':
|
|
description: 조회 성공
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/WinnerListResponse'
|
|
examples:
|
|
success:
|
|
summary: 당첨자 목록
|
|
value:
|
|
success: true
|
|
message: "당첨자 목록을 조회했습니다"
|
|
data:
|
|
eventId: "evt_20250123_001"
|
|
drawnAt: "2025-01-24T15:00:00Z"
|
|
totalWinners: 10
|
|
winners:
|
|
- participantId: "prt_20250123_002"
|
|
name: "김철수"
|
|
phoneNumber: "010-9876-5432"
|
|
email: "kim@example.com"
|
|
rank: 1
|
|
wonAt: "2025-01-24T15:00:00Z"
|
|
- participantId: "prt_20250123_045"
|
|
name: "이영희"
|
|
phoneNumber: "010-5555-1234"
|
|
email: "lee@example.com"
|
|
rank: 2
|
|
wonAt: "2025-01-24T15:00:00Z"
|
|
pagination:
|
|
currentPage: 0
|
|
pageSize: 20
|
|
totalElements: 10
|
|
totalPages: 1
|
|
hasNext: false
|
|
hasPrevious: false
|
|
'404':
|
|
description: 이벤트를 찾을 수 없음 또는 당첨자가 없음
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ErrorResponse'
|
|
examples:
|
|
noWinners:
|
|
summary: 당첨자 없음
|
|
value:
|
|
success: false
|
|
error:
|
|
code: "NO_WINNERS_YET"
|
|
message: "아직 당첨자 추첨이 진행되지 않았습니다"
|
|
|
|
components:
|
|
schemas:
|
|
ParticipationRequest:
|
|
type: object
|
|
required:
|
|
- name
|
|
- phoneNumber
|
|
- agreePrivacy
|
|
properties:
|
|
name:
|
|
type: string
|
|
description: 참여자 이름
|
|
minLength: 2
|
|
maxLength: 50
|
|
example: "홍길동"
|
|
phoneNumber:
|
|
type: string
|
|
description: 참여자 전화번호 (하이픈 포함)
|
|
pattern: '^\d{3}-\d{3,4}-\d{4}$'
|
|
example: "010-1234-5678"
|
|
email:
|
|
type: string
|
|
format: email
|
|
description: 참여자 이메일
|
|
example: "hong@example.com"
|
|
agreeMarketing:
|
|
type: boolean
|
|
description: 마케팅 정보 수신 동의
|
|
default: false
|
|
example: true
|
|
agreePrivacy:
|
|
type: boolean
|
|
description: 개인정보 수집 및 이용 동의 (필수)
|
|
example: true
|
|
storeVisited:
|
|
type: boolean
|
|
description: 매장 방문 여부
|
|
default: false
|
|
example: false
|
|
|
|
ParticipationResponse:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
message:
|
|
type: string
|
|
example: "이벤트 참여가 완료되었습니다"
|
|
data:
|
|
$ref: '#/components/schemas/ParticipantInfo'
|
|
|
|
ParticipantInfo:
|
|
type: object
|
|
properties:
|
|
participantId:
|
|
type: string
|
|
description: 참여자 ID
|
|
example: "prt_20250123_001"
|
|
eventId:
|
|
type: string
|
|
description: 이벤트 ID
|
|
example: "evt_20250123_001"
|
|
name:
|
|
type: string
|
|
description: 참여자 이름
|
|
example: "홍길동"
|
|
phoneNumber:
|
|
type: string
|
|
description: 참여자 전화번호
|
|
example: "010-1234-5678"
|
|
email:
|
|
type: string
|
|
description: 참여자 이메일
|
|
example: "hong@example.com"
|
|
participatedAt:
|
|
type: string
|
|
format: date-time
|
|
description: 참여 일시
|
|
example: "2025-01-23T10:30:00Z"
|
|
storeVisited:
|
|
type: boolean
|
|
description: 매장 방문 여부
|
|
example: false
|
|
bonusEntries:
|
|
type: integer
|
|
description: 보너스 응모권 수 (매장 방문 시 +1)
|
|
minimum: 1
|
|
example: 1
|
|
isWinner:
|
|
type: boolean
|
|
description: 당첨 여부
|
|
example: false
|
|
|
|
ParticipantDetailInfo:
|
|
allOf:
|
|
- $ref: '#/components/schemas/ParticipantInfo'
|
|
- type: object
|
|
properties:
|
|
agreeMarketing:
|
|
type: boolean
|
|
description: 마케팅 정보 수신 동의
|
|
example: true
|
|
agreePrivacy:
|
|
type: boolean
|
|
description: 개인정보 수집 및 이용 동의
|
|
example: true
|
|
winnerInfo:
|
|
$ref: '#/components/schemas/WinnerInfo'
|
|
nullable: true
|
|
|
|
ParticipantListResponse:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
message:
|
|
type: string
|
|
example: "참여자 목록을 조회했습니다"
|
|
data:
|
|
type: object
|
|
properties:
|
|
participants:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/ParticipantInfo'
|
|
pagination:
|
|
$ref: '#/components/schemas/Pagination'
|
|
|
|
ParticipantDetailResponse:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
message:
|
|
type: string
|
|
example: "참여자 정보를 조회했습니다"
|
|
data:
|
|
$ref: '#/components/schemas/ParticipantDetailInfo'
|
|
|
|
DrawWinnersRequest:
|
|
type: object
|
|
required:
|
|
- winnerCount
|
|
properties:
|
|
winnerCount:
|
|
type: integer
|
|
description: 당첨자 수
|
|
minimum: 1
|
|
example: 10
|
|
applyStoreVisitBonus:
|
|
type: boolean
|
|
description: 매장 방문 보너스 적용 여부
|
|
default: true
|
|
example: true
|
|
|
|
DrawWinnersResponse:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
message:
|
|
type: string
|
|
example: "당첨자 추첨이 완료되었습니다"
|
|
data:
|
|
type: object
|
|
properties:
|
|
eventId:
|
|
type: string
|
|
description: 이벤트 ID
|
|
example: "evt_20250123_001"
|
|
totalParticipants:
|
|
type: integer
|
|
description: 전체 참여자 수
|
|
example: 156
|
|
winnerCount:
|
|
type: integer
|
|
description: 당첨자 수
|
|
example: 10
|
|
drawnAt:
|
|
type: string
|
|
format: date-time
|
|
description: 추첨 일시
|
|
example: "2025-01-24T15:00:00Z"
|
|
winners:
|
|
type: array
|
|
description: 당첨자 목록
|
|
items:
|
|
$ref: '#/components/schemas/WinnerSummary'
|
|
|
|
WinnerSummary:
|
|
type: object
|
|
properties:
|
|
participantId:
|
|
type: string
|
|
description: 참여자 ID
|
|
example: "prt_20250123_002"
|
|
name:
|
|
type: string
|
|
description: 당첨자 이름
|
|
example: "김철수"
|
|
phoneNumber:
|
|
type: string
|
|
description: 당첨자 전화번호
|
|
example: "010-9876-5432"
|
|
rank:
|
|
type: integer
|
|
description: 당첨 순위
|
|
minimum: 1
|
|
example: 1
|
|
|
|
WinnerInfo:
|
|
type: object
|
|
properties:
|
|
participantId:
|
|
type: string
|
|
description: 참여자 ID
|
|
example: "prt_20250123_002"
|
|
name:
|
|
type: string
|
|
description: 당첨자 이름
|
|
example: "김철수"
|
|
phoneNumber:
|
|
type: string
|
|
description: 당첨자 전화번호
|
|
example: "010-9876-5432"
|
|
email:
|
|
type: string
|
|
description: 당첨자 이메일
|
|
example: "kim@example.com"
|
|
rank:
|
|
type: integer
|
|
description: 당첨 순위
|
|
minimum: 1
|
|
example: 1
|
|
wonAt:
|
|
type: string
|
|
format: date-time
|
|
description: 당첨 일시
|
|
example: "2025-01-24T15:00:00Z"
|
|
|
|
WinnerListResponse:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: true
|
|
message:
|
|
type: string
|
|
example: "당첨자 목록을 조회했습니다"
|
|
data:
|
|
type: object
|
|
properties:
|
|
eventId:
|
|
type: string
|
|
description: 이벤트 ID
|
|
example: "evt_20250123_001"
|
|
drawnAt:
|
|
type: string
|
|
format: date-time
|
|
description: 추첨 일시
|
|
example: "2025-01-24T15:00:00Z"
|
|
totalWinners:
|
|
type: integer
|
|
description: 전체 당첨자 수
|
|
example: 10
|
|
winners:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/WinnerInfo'
|
|
pagination:
|
|
$ref: '#/components/schemas/Pagination'
|
|
|
|
Pagination:
|
|
type: object
|
|
properties:
|
|
currentPage:
|
|
type: integer
|
|
description: 현재 페이지 번호 (0부터 시작)
|
|
minimum: 0
|
|
example: 0
|
|
pageSize:
|
|
type: integer
|
|
description: 페이지 크기
|
|
minimum: 1
|
|
example: 20
|
|
totalElements:
|
|
type: integer
|
|
description: 전체 요소 수
|
|
minimum: 0
|
|
example: 156
|
|
totalPages:
|
|
type: integer
|
|
description: 전체 페이지 수
|
|
minimum: 0
|
|
example: 8
|
|
hasNext:
|
|
type: boolean
|
|
description: 다음 페이지 존재 여부
|
|
example: true
|
|
hasPrevious:
|
|
type: boolean
|
|
description: 이전 페이지 존재 여부
|
|
example: false
|
|
|
|
ErrorResponse:
|
|
type: object
|
|
properties:
|
|
success:
|
|
type: boolean
|
|
example: false
|
|
error:
|
|
type: object
|
|
properties:
|
|
code:
|
|
type: string
|
|
description: 에러 코드
|
|
example: "DUPLICATE_PARTICIPATION"
|
|
message:
|
|
type: string
|
|
description: 에러 메시지
|
|
example: "이미 참여하신 이벤트입니다"
|
|
details:
|
|
type: object
|
|
description: 추가 에러 상세 정보
|
|
additionalProperties: true
|
|
nullable: true
|