mirror of
https://github.com/hwanny1128/HGZero.git
synced 2026-06-13 11:49:10 +00:00
API 설계 완료
- 5개 마이크로서비스 API 명세 작성 (User, Meeting, STT, AI, Notification) - OpenAPI 3.0 표준 준수 - 총 47개 API 설계 - 유저스토리 100% 커버리지 - swagger-cli 검증 통과 - 종합 API 설계서 작성 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,932 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Notification Service API
|
||||
description: |
|
||||
회의록 작성 및 공유 개선 서비스의 알림 발송 및 리마인더 관리 API
|
||||
|
||||
## 주요 기능
|
||||
- 이메일 알림 발송 (회의 초대, Todo 할당, 리마인더)
|
||||
- 알림 이력 조회 및 관리
|
||||
- 사용자 알림 설정 관리
|
||||
|
||||
## Event-Driven Architecture
|
||||
- 알림 발송은 Azure Event Hubs를 통한 이벤트 기반 처리
|
||||
- 비동기 처리로 성능 최적화
|
||||
- 재시도 메커니즘으로 신뢰성 보장
|
||||
version: 1.0.0
|
||||
contact:
|
||||
name: Backend Development Team
|
||||
email: backend@example.com
|
||||
|
||||
servers:
|
||||
- url: https://api.hgzero.com/notification/v1
|
||||
description: Production Server
|
||||
- url: https://dev-api.hgzero.com/notification/v1
|
||||
description: Development Server
|
||||
- url: http://localhost:8083/api/v1
|
||||
description: Local Development
|
||||
|
||||
tags:
|
||||
- name: Notification
|
||||
description: 알림 발송 및 관리 API
|
||||
- name: Notification Settings
|
||||
description: 사용자 알림 설정 API
|
||||
- name: Internal
|
||||
description: 내부 서비스 간 통신 API (Event Handler)
|
||||
|
||||
paths:
|
||||
# ========================================
|
||||
# Notification APIs
|
||||
# ========================================
|
||||
|
||||
/notifications/invitation:
|
||||
post:
|
||||
summary: 회의 초대 알림 발송 (내부 API)
|
||||
description: |
|
||||
MeetingCreated 이벤트를 수신하여 참석자에게 회의 초대 이메일을 발송합니다.
|
||||
- Event-Driven 방식으로 Meeting Service에서 이벤트 발행
|
||||
- 참석자별 병렬 이메일 발송
|
||||
- 발송 이력 저장 및 재시도 메커니즘
|
||||
operationId: sendMeetingInvitation
|
||||
x-user-story: UFR-MEET-010
|
||||
x-controller: NotificationController
|
||||
tags:
|
||||
- Internal
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/MeetingInvitationRequest'
|
||||
example:
|
||||
meetingId: "MTG-20250123-001"
|
||||
title: "2025년 1분기 전략 회의"
|
||||
scheduledAt: "2025-01-30T14:00:00Z"
|
||||
location: "회의실 A"
|
||||
participants:
|
||||
- userId: "U001"
|
||||
userName: "김철수"
|
||||
email: "kim@example.com"
|
||||
- userId: "U002"
|
||||
userName: "이영희"
|
||||
email: "lee@example.com"
|
||||
creatorName: "박팀장"
|
||||
meetingLink: "https://meet.hgzero.com/MTG-20250123-001"
|
||||
calendarLink: "https://calendar.hgzero.com/add/MTG-20250123-001"
|
||||
responses:
|
||||
'200':
|
||||
description: 알림 발송 성공
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationResponse'
|
||||
example:
|
||||
notificationId: "NTF-20250123-001"
|
||||
status: "SENT"
|
||||
sentCount: 2
|
||||
failedCount: 0
|
||||
createdAt: "2025-01-23T10:00:00Z"
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/notifications/todo:
|
||||
post:
|
||||
summary: Todo 할당 알림 발송 (내부 API)
|
||||
description: |
|
||||
TodoAssigned 이벤트를 수신하여 담당자에게 Todo 알림 이메일을 발송합니다.
|
||||
- 할당 즉시 알림
|
||||
- 마감일 3일 전, 1일 전, 당일 리마인더 스케줄링
|
||||
- 회의록 링크 포함
|
||||
operationId: sendTodoNotification
|
||||
x-user-story: UFR-TODO-010
|
||||
x-controller: NotificationController
|
||||
tags:
|
||||
- Internal
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/TodoNotificationRequest'
|
||||
example:
|
||||
todoId: "TODO-20250123-001"
|
||||
meetingId: "MTG-20250123-001"
|
||||
assignee:
|
||||
userId: "U001"
|
||||
userName: "김철수"
|
||||
email: "kim@example.com"
|
||||
content: "API 설계서 작성 및 검토"
|
||||
dueDate: "2025-01-30T23:59:59Z"
|
||||
priority: "HIGH"
|
||||
minutesLink: "https://hgzero.com/minutes/MTG-20250123-001#section-3"
|
||||
meetingTitle: "2025년 1분기 전략 회의"
|
||||
responses:
|
||||
'200':
|
||||
description: 알림 발송 성공
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationResponse'
|
||||
example:
|
||||
notificationId: "NTF-20250123-002"
|
||||
status: "SENT"
|
||||
sentCount: 1
|
||||
failedCount: 0
|
||||
createdAt: "2025-01-23T10:05:00Z"
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/notifications:
|
||||
get:
|
||||
summary: 사용자별 알림 이력 조회
|
||||
description: |
|
||||
사용자가 받은 알림 이력을 조회합니다.
|
||||
- 알림 유형별 필터링 (초대, Todo, 리마인더)
|
||||
- 상태별 필터링 (발송완료, 발송실패)
|
||||
- 페이징 지원
|
||||
operationId: getNotifications
|
||||
x-user-story: AFR-USER-020
|
||||
x-controller: NotificationController
|
||||
tags:
|
||||
- Notification
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/UserIdHeader'
|
||||
- name: type
|
||||
in: query
|
||||
description: 알림 유형 필터
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- INVITATION
|
||||
- TODO_ASSIGNED
|
||||
- REMINDER
|
||||
- TODO_REMINDER
|
||||
- name: status
|
||||
in: query
|
||||
description: 알림 상태 필터
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- SENT
|
||||
- FAILED
|
||||
- PENDING
|
||||
- name: page
|
||||
in: query
|
||||
description: 페이지 번호 (0부터 시작)
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 0
|
||||
default: 0
|
||||
- name: size
|
||||
in: query
|
||||
description: 페이지당 항목 수
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
minimum: 1
|
||||
maximum: 100
|
||||
default: 20
|
||||
responses:
|
||||
'200':
|
||||
description: 알림 이력 조회 성공
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationListResponse'
|
||||
example:
|
||||
notifications:
|
||||
- notificationId: "NTF-20250123-002"
|
||||
type: "TODO_ASSIGNED"
|
||||
title: "[TODO 할당] API 설계서 작성 및 검토"
|
||||
content: "Todo가 할당되었습니다. 마감일: 2025-01-30"
|
||||
status: "SENT"
|
||||
sentAt: "2025-01-23T10:05:00Z"
|
||||
relatedId: "TODO-20250123-001"
|
||||
- notificationId: "NTF-20250123-001"
|
||||
type: "INVITATION"
|
||||
title: "[회의 초대] 2025년 1분기 전략 회의"
|
||||
content: "회의에 초대되었습니다. 일시: 2025-01-30 14:00"
|
||||
status: "SENT"
|
||||
sentAt: "2025-01-23T10:00:00Z"
|
||||
relatedId: "MTG-20250123-001"
|
||||
pagination:
|
||||
currentPage: 0
|
||||
pageSize: 20
|
||||
totalElements: 2
|
||||
totalPages: 1
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
/notifications/{notificationId}:
|
||||
get:
|
||||
summary: 특정 알림 상세 조회
|
||||
description: |
|
||||
알림 ID로 특정 알림의 상세 정보를 조회합니다.
|
||||
- 발송 상태
|
||||
- 수신자 정보
|
||||
- 템플릿 정보
|
||||
- 재시도 이력
|
||||
operationId: getNotificationById
|
||||
x-user-story: AFR-USER-020
|
||||
x-controller: NotificationController
|
||||
tags:
|
||||
- Notification
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/UserIdHeader'
|
||||
- name: notificationId
|
||||
in: path
|
||||
description: 알림 ID
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
pattern: '^NTF-[0-9]{8}-[0-9]{3}$'
|
||||
example: "NTF-20250123-001"
|
||||
responses:
|
||||
'200':
|
||||
description: 알림 상세 조회 성공
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationDetailResponse'
|
||||
example:
|
||||
notificationId: "NTF-20250123-001"
|
||||
type: "INVITATION"
|
||||
title: "[회의 초대] 2025년 1분기 전략 회의"
|
||||
content: "회의에 초대되었습니다."
|
||||
status: "SENT"
|
||||
relatedId: "MTG-20250123-001"
|
||||
recipients:
|
||||
- email: "kim@example.com"
|
||||
status: "SENT"
|
||||
sentAt: "2025-01-23T10:00:05Z"
|
||||
- email: "lee@example.com"
|
||||
status: "SENT"
|
||||
sentAt: "2025-01-23T10:00:06Z"
|
||||
templateId: "meeting-invitation"
|
||||
createdAt: "2025-01-23T10:00:00Z"
|
||||
completedAt: "2025-01-23T10:00:10Z"
|
||||
retryCount: 0
|
||||
'404':
|
||||
$ref: '#/components/responses/NotFound'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
# ========================================
|
||||
# Notification Settings APIs
|
||||
# ========================================
|
||||
|
||||
/notifications/settings:
|
||||
get:
|
||||
summary: 사용자 알림 설정 조회
|
||||
description: |
|
||||
사용자의 알림 설정을 조회합니다.
|
||||
- 알림 채널 설정 (이메일/SMS)
|
||||
- 알림 유형별 활성화 여부
|
||||
- 수신 시간대 설정
|
||||
operationId: getNotificationSettings
|
||||
x-user-story: AFR-USER-020
|
||||
x-controller: NotificationSettingsController
|
||||
tags:
|
||||
- Notification Settings
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/UserIdHeader'
|
||||
responses:
|
||||
'200':
|
||||
description: 알림 설정 조회 성공
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationSettingsResponse'
|
||||
example:
|
||||
userId: "U001"
|
||||
channels:
|
||||
email: true
|
||||
sms: false
|
||||
preferences:
|
||||
invitationEnabled: true
|
||||
todoEnabled: true
|
||||
reminderEnabled: true
|
||||
minutesUpdateEnabled: false
|
||||
quietHours:
|
||||
enabled: true
|
||||
startTime: "22:00"
|
||||
endTime: "08:00"
|
||||
timezone: "Asia/Seoul"
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
put:
|
||||
summary: 사용자 알림 설정 업데이트
|
||||
description: |
|
||||
사용자의 알림 설정을 변경합니다.
|
||||
- 부분 업데이트 지원
|
||||
- 설정 변경 즉시 적용
|
||||
operationId: updateNotificationSettings
|
||||
x-user-story: AFR-USER-020
|
||||
x-controller: NotificationSettingsController
|
||||
tags:
|
||||
- Notification Settings
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/UserIdHeader'
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationSettingsUpdateRequest'
|
||||
example:
|
||||
channels:
|
||||
email: true
|
||||
sms: false
|
||||
preferences:
|
||||
invitationEnabled: true
|
||||
todoEnabled: true
|
||||
reminderEnabled: false
|
||||
minutesUpdateEnabled: false
|
||||
quietHours:
|
||||
enabled: true
|
||||
startTime: "23:00"
|
||||
endTime: "07:00"
|
||||
timezone: "Asia/Seoul"
|
||||
responses:
|
||||
'200':
|
||||
description: 알림 설정 업데이트 성공
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/NotificationSettingsResponse'
|
||||
'400':
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
'401':
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
'500':
|
||||
$ref: '#/components/responses/InternalServerError'
|
||||
|
||||
# ========================================
|
||||
# Components
|
||||
# ========================================
|
||||
|
||||
components:
|
||||
schemas:
|
||||
# Request Schemas
|
||||
MeetingInvitationRequest:
|
||||
type: object
|
||||
required:
|
||||
- meetingId
|
||||
- title
|
||||
- scheduledAt
|
||||
- participants
|
||||
- creatorName
|
||||
properties:
|
||||
meetingId:
|
||||
type: string
|
||||
description: 회의 ID
|
||||
pattern: '^MTG-[0-9]{8}-[0-9]{3}$'
|
||||
example: "MTG-20250123-001"
|
||||
title:
|
||||
type: string
|
||||
description: 회의 제목
|
||||
maxLength: 100
|
||||
example: "2025년 1분기 전략 회의"
|
||||
scheduledAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 회의 시작 일시 (ISO 8601)
|
||||
example: "2025-01-30T14:00:00Z"
|
||||
location:
|
||||
type: string
|
||||
description: 회의 장소
|
||||
maxLength: 200
|
||||
example: "회의실 A"
|
||||
participants:
|
||||
type: array
|
||||
description: 참석자 목록
|
||||
minItems: 1
|
||||
items:
|
||||
$ref: '#/components/schemas/Participant'
|
||||
creatorName:
|
||||
type: string
|
||||
description: 회의 생성자 이름
|
||||
example: "박팀장"
|
||||
meetingLink:
|
||||
type: string
|
||||
format: uri
|
||||
description: 회의 참여 링크
|
||||
example: "https://meet.hgzero.com/MTG-20250123-001"
|
||||
calendarLink:
|
||||
type: string
|
||||
format: uri
|
||||
description: 캘린더 추가 링크
|
||||
example: "https://calendar.hgzero.com/add/MTG-20250123-001"
|
||||
|
||||
TodoNotificationRequest:
|
||||
type: object
|
||||
required:
|
||||
- todoId
|
||||
- meetingId
|
||||
- assignee
|
||||
- content
|
||||
- dueDate
|
||||
- priority
|
||||
- minutesLink
|
||||
- meetingTitle
|
||||
properties:
|
||||
todoId:
|
||||
type: string
|
||||
description: Todo ID
|
||||
pattern: '^TODO-[0-9]{8}-[0-9]{3}$'
|
||||
example: "TODO-20250123-001"
|
||||
meetingId:
|
||||
type: string
|
||||
description: 관련 회의 ID
|
||||
pattern: '^MTG-[0-9]{8}-[0-9]{3}$'
|
||||
example: "MTG-20250123-001"
|
||||
assignee:
|
||||
$ref: '#/components/schemas/Participant'
|
||||
content:
|
||||
type: string
|
||||
description: Todo 내용
|
||||
maxLength: 500
|
||||
example: "API 설계서 작성 및 검토"
|
||||
dueDate:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 마감일 (ISO 8601)
|
||||
example: "2025-01-30T23:59:59Z"
|
||||
priority:
|
||||
type: string
|
||||
description: 우선순위
|
||||
enum:
|
||||
- HIGH
|
||||
- MEDIUM
|
||||
- LOW
|
||||
example: "HIGH"
|
||||
minutesLink:
|
||||
type: string
|
||||
format: uri
|
||||
description: 회의록 링크 (해당 섹션)
|
||||
example: "https://hgzero.com/minutes/MTG-20250123-001#section-3"
|
||||
meetingTitle:
|
||||
type: string
|
||||
description: 회의 제목
|
||||
example: "2025년 1분기 전략 회의"
|
||||
|
||||
NotificationSettingsUpdateRequest:
|
||||
type: object
|
||||
properties:
|
||||
channels:
|
||||
type: object
|
||||
description: 알림 채널 설정
|
||||
properties:
|
||||
email:
|
||||
type: boolean
|
||||
description: 이메일 알림 활성화
|
||||
sms:
|
||||
type: boolean
|
||||
description: SMS 알림 활성화
|
||||
preferences:
|
||||
type: object
|
||||
description: 알림 유형별 활성화 설정
|
||||
properties:
|
||||
invitationEnabled:
|
||||
type: boolean
|
||||
description: 회의 초대 알림
|
||||
todoEnabled:
|
||||
type: boolean
|
||||
description: Todo 할당 알림
|
||||
reminderEnabled:
|
||||
type: boolean
|
||||
description: 리마인더 알림
|
||||
minutesUpdateEnabled:
|
||||
type: boolean
|
||||
description: 회의록 수정 알림
|
||||
quietHours:
|
||||
type: object
|
||||
description: 방해 금지 시간대 설정
|
||||
properties:
|
||||
enabled:
|
||||
type: boolean
|
||||
description: 방해 금지 시간대 활성화
|
||||
startTime:
|
||||
type: string
|
||||
format: time
|
||||
description: 시작 시간 (HH:mm)
|
||||
example: "22:00"
|
||||
endTime:
|
||||
type: string
|
||||
format: time
|
||||
description: 종료 시간 (HH:mm)
|
||||
example: "08:00"
|
||||
timezone:
|
||||
type: string
|
||||
description: 타임존
|
||||
example: "Asia/Seoul"
|
||||
|
||||
# Response Schemas
|
||||
NotificationResponse:
|
||||
type: object
|
||||
required:
|
||||
- notificationId
|
||||
- status
|
||||
- sentCount
|
||||
- failedCount
|
||||
- createdAt
|
||||
properties:
|
||||
notificationId:
|
||||
type: string
|
||||
description: 알림 ID
|
||||
pattern: '^NTF-[0-9]{8}-[0-9]{3}$'
|
||||
example: "NTF-20250123-001"
|
||||
status:
|
||||
type: string
|
||||
description: 알림 전체 상태
|
||||
enum:
|
||||
- SENT
|
||||
- PARTIAL
|
||||
- FAILED
|
||||
- PENDING
|
||||
example: "SENT"
|
||||
sentCount:
|
||||
type: integer
|
||||
description: 발송 성공 건수
|
||||
minimum: 0
|
||||
example: 2
|
||||
failedCount:
|
||||
type: integer
|
||||
description: 발송 실패 건수
|
||||
minimum: 0
|
||||
example: 0
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 알림 생성 일시
|
||||
example: "2025-01-23T10:00:00Z"
|
||||
|
||||
NotificationListResponse:
|
||||
type: object
|
||||
required:
|
||||
- notifications
|
||||
- pagination
|
||||
properties:
|
||||
notifications:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/NotificationSummary'
|
||||
pagination:
|
||||
$ref: '#/components/schemas/PaginationInfo'
|
||||
|
||||
NotificationSummary:
|
||||
type: object
|
||||
required:
|
||||
- notificationId
|
||||
- type
|
||||
- title
|
||||
- status
|
||||
- sentAt
|
||||
properties:
|
||||
notificationId:
|
||||
type: string
|
||||
description: 알림 ID
|
||||
example: "NTF-20250123-001"
|
||||
type:
|
||||
type: string
|
||||
description: 알림 유형
|
||||
enum:
|
||||
- INVITATION
|
||||
- TODO_ASSIGNED
|
||||
- REMINDER
|
||||
- TODO_REMINDER
|
||||
example: "INVITATION"
|
||||
title:
|
||||
type: string
|
||||
description: 알림 제목
|
||||
example: "[회의 초대] 2025년 1분기 전략 회의"
|
||||
content:
|
||||
type: string
|
||||
description: 알림 내용 요약
|
||||
example: "회의에 초대되었습니다. 일시: 2025-01-30 14:00"
|
||||
status:
|
||||
type: string
|
||||
description: 발송 상태
|
||||
enum:
|
||||
- SENT
|
||||
- FAILED
|
||||
- PENDING
|
||||
example: "SENT"
|
||||
sentAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 발송 일시
|
||||
example: "2025-01-23T10:00:00Z"
|
||||
relatedId:
|
||||
type: string
|
||||
description: 관련 객체 ID (회의 ID, Todo ID 등)
|
||||
example: "MTG-20250123-001"
|
||||
|
||||
NotificationDetailResponse:
|
||||
type: object
|
||||
required:
|
||||
- notificationId
|
||||
- type
|
||||
- title
|
||||
- content
|
||||
- status
|
||||
- relatedId
|
||||
- recipients
|
||||
- createdAt
|
||||
properties:
|
||||
notificationId:
|
||||
type: string
|
||||
description: 알림 ID
|
||||
example: "NTF-20250123-001"
|
||||
type:
|
||||
type: string
|
||||
description: 알림 유형
|
||||
enum:
|
||||
- INVITATION
|
||||
- TODO_ASSIGNED
|
||||
- REMINDER
|
||||
- TODO_REMINDER
|
||||
title:
|
||||
type: string
|
||||
description: 알림 제목
|
||||
example: "[회의 초대] 2025년 1분기 전략 회의"
|
||||
content:
|
||||
type: string
|
||||
description: 알림 전체 내용
|
||||
example: "회의에 초대되었습니다."
|
||||
status:
|
||||
type: string
|
||||
description: 알림 전체 상태
|
||||
enum:
|
||||
- SENT
|
||||
- PARTIAL
|
||||
- FAILED
|
||||
- PENDING
|
||||
relatedId:
|
||||
type: string
|
||||
description: 관련 객체 ID
|
||||
example: "MTG-20250123-001"
|
||||
recipients:
|
||||
type: array
|
||||
description: 수신자별 발송 상태
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
email:
|
||||
type: string
|
||||
format: email
|
||||
description: 수신자 이메일
|
||||
status:
|
||||
type: string
|
||||
enum:
|
||||
- SENT
|
||||
- FAILED
|
||||
- PENDING
|
||||
sentAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 발송 일시
|
||||
errorMessage:
|
||||
type: string
|
||||
description: 오류 메시지 (실패 시)
|
||||
templateId:
|
||||
type: string
|
||||
description: 사용된 템플릿 ID
|
||||
example: "meeting-invitation"
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 알림 생성 일시
|
||||
completedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 알림 완료 일시
|
||||
retryCount:
|
||||
type: integer
|
||||
description: 재시도 횟수
|
||||
minimum: 0
|
||||
|
||||
NotificationSettingsResponse:
|
||||
type: object
|
||||
required:
|
||||
- userId
|
||||
- channels
|
||||
- preferences
|
||||
properties:
|
||||
userId:
|
||||
type: string
|
||||
description: 사용자 ID
|
||||
example: "U001"
|
||||
channels:
|
||||
type: object
|
||||
description: 알림 채널 설정
|
||||
required:
|
||||
- email
|
||||
- sms
|
||||
properties:
|
||||
email:
|
||||
type: boolean
|
||||
description: 이메일 알림 활성화
|
||||
sms:
|
||||
type: boolean
|
||||
description: SMS 알림 활성화
|
||||
preferences:
|
||||
type: object
|
||||
description: 알림 유형별 활성화 설정
|
||||
required:
|
||||
- invitationEnabled
|
||||
- todoEnabled
|
||||
- reminderEnabled
|
||||
- minutesUpdateEnabled
|
||||
properties:
|
||||
invitationEnabled:
|
||||
type: boolean
|
||||
description: 회의 초대 알림
|
||||
todoEnabled:
|
||||
type: boolean
|
||||
description: Todo 할당 알림
|
||||
reminderEnabled:
|
||||
type: boolean
|
||||
description: 리마인더 알림
|
||||
minutesUpdateEnabled:
|
||||
type: boolean
|
||||
description: 회의록 수정 알림
|
||||
quietHours:
|
||||
type: object
|
||||
description: 방해 금지 시간대 설정
|
||||
properties:
|
||||
enabled:
|
||||
type: boolean
|
||||
startTime:
|
||||
type: string
|
||||
format: time
|
||||
endTime:
|
||||
type: string
|
||||
format: time
|
||||
timezone:
|
||||
type: string
|
||||
|
||||
# Common Schemas
|
||||
Participant:
|
||||
type: object
|
||||
required:
|
||||
- userId
|
||||
- userName
|
||||
- email
|
||||
properties:
|
||||
userId:
|
||||
type: string
|
||||
description: 사용자 ID
|
||||
example: "U001"
|
||||
userName:
|
||||
type: string
|
||||
description: 사용자 이름
|
||||
example: "김철수"
|
||||
email:
|
||||
type: string
|
||||
format: email
|
||||
description: 이메일 주소
|
||||
example: "kim@example.com"
|
||||
|
||||
PaginationInfo:
|
||||
type: object
|
||||
required:
|
||||
- currentPage
|
||||
- pageSize
|
||||
- totalElements
|
||||
- totalPages
|
||||
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: 2
|
||||
totalPages:
|
||||
type: integer
|
||||
description: 전체 페이지 수
|
||||
minimum: 0
|
||||
example: 1
|
||||
|
||||
ErrorResponse:
|
||||
type: object
|
||||
required:
|
||||
- code
|
||||
- message
|
||||
- timestamp
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
description: 오류 코드
|
||||
example: "INVALID_REQUEST"
|
||||
message:
|
||||
type: string
|
||||
description: 오류 메시지
|
||||
example: "Invalid request parameters"
|
||||
timestamp:
|
||||
type: string
|
||||
format: date-time
|
||||
description: 오류 발생 시각
|
||||
details:
|
||||
type: array
|
||||
description: 상세 오류 정보
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
field:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
|
||||
parameters:
|
||||
UserIdHeader:
|
||||
name: X-User-Id
|
||||
in: header
|
||||
description: 사용자 ID (JWT 토큰에서 추출)
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
example: "U001"
|
||||
|
||||
responses:
|
||||
BadRequest:
|
||||
description: 잘못된 요청
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
code: "INVALID_REQUEST"
|
||||
message: "Invalid request parameters"
|
||||
timestamp: "2025-01-23T10:00:00Z"
|
||||
details:
|
||||
- field: "meetingId"
|
||||
message: "Meeting ID is required"
|
||||
|
||||
Unauthorized:
|
||||
description: 인증 실패
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
code: "UNAUTHORIZED"
|
||||
message: "Authentication required"
|
||||
timestamp: "2025-01-23T10:00:00Z"
|
||||
|
||||
NotFound:
|
||||
description: 리소스를 찾을 수 없음
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
code: "NOT_FOUND"
|
||||
message: "Notification not found"
|
||||
timestamp: "2025-01-23T10:00:00Z"
|
||||
|
||||
InternalServerError:
|
||||
description: 서버 내부 오류
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ErrorResponse'
|
||||
example:
|
||||
code: "INTERNAL_SERVER_ERROR"
|
||||
message: "An unexpected error occurred"
|
||||
timestamp: "2025-01-23T10:00:00Z"
|
||||
|
||||
securitySchemes:
|
||||
BearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
description: JWT 토큰 기반 인증
|
||||
|
||||
security:
|
||||
- BearerAuth: []
|
||||
Reference in New Issue
Block a user