초기 커밋
This commit is contained in:
666
ZELLYY/zellyy note/02_기술_문서/API_명세서.md
Normal file
666
ZELLYY/zellyy note/02_기술_문서/API_명세서.md
Normal file
@@ -0,0 +1,666 @@
|
||||
# Zellyy API 명세서
|
||||
|
||||
이 문서는 Zellyy 프로젝트의 API 엔드포인트와 기능에 대한 상세 명세를 제공합니다.
|
||||
|
||||
## 기본 정보
|
||||
|
||||
- **기본 URL**: `https://a11.ism.kr/api`
|
||||
- **API 버전**: v1
|
||||
- **인증 방식**: JWT 토큰 (Bearer Authentication)
|
||||
- **응답 형식**: JSON
|
||||
|
||||
## 인증 API
|
||||
|
||||
### 회원가입
|
||||
|
||||
```
|
||||
POST /auth/signup
|
||||
```
|
||||
|
||||
**요청 본문**:
|
||||
```json
|
||||
{
|
||||
"email": "user@example.com",
|
||||
"password": "securepassword",
|
||||
"username": "username"
|
||||
}
|
||||
```
|
||||
|
||||
**응답 (200 OK)**:
|
||||
```json
|
||||
{
|
||||
"user": {
|
||||
"id": "uuid",
|
||||
"email": "user@example.com",
|
||||
"username": "username"
|
||||
},
|
||||
"session": {
|
||||
"access_token": "jwt_token",
|
||||
"refresh_token": "refresh_token",
|
||||
"expires_at": 1672531200
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 로그인
|
||||
|
||||
```
|
||||
POST /auth/login
|
||||
```
|
||||
|
||||
**요청 본문**:
|
||||
```json
|
||||
{
|
||||
"email": "user@example.com",
|
||||
"password": "securepassword"
|
||||
}
|
||||
```
|
||||
|
||||
**응답 (200 OK)**:
|
||||
```json
|
||||
{
|
||||
"user": {
|
||||
"id": "uuid",
|
||||
"email": "user@example.com",
|
||||
"username": "username"
|
||||
},
|
||||
"session": {
|
||||
"access_token": "jwt_token",
|
||||
"refresh_token": "refresh_token",
|
||||
"expires_at": 1672531200
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 토큰 갱신
|
||||
|
||||
```
|
||||
POST /auth/refresh
|
||||
```
|
||||
|
||||
**요청 본문**:
|
||||
```json
|
||||
{
|
||||
"refresh_token": "refresh_token"
|
||||
}
|
||||
```
|
||||
|
||||
**응답 (200 OK)**:
|
||||
```json
|
||||
{
|
||||
"access_token": "new_jwt_token",
|
||||
"refresh_token": "new_refresh_token",
|
||||
"expires_at": 1672531200
|
||||
}
|
||||
```
|
||||
|
||||
### 로그아웃
|
||||
|
||||
```
|
||||
POST /auth/logout
|
||||
```
|
||||
|
||||
**요청 헤더**:
|
||||
```
|
||||
Authorization: Bearer jwt_token
|
||||
```
|
||||
|
||||
**응답 (200 OK)**:
|
||||
```json
|
||||
{
|
||||
"message": "Successfully logged out"
|
||||
}
|
||||
```
|
||||
|
||||
## 사용자 API
|
||||
|
||||
### 사용자 정보 조회
|
||||
|
||||
```
|
||||
GET /users/me
|
||||
```
|
||||
|
||||
**요청 헤더**:
|
||||
```
|
||||
Authorization: Bearer jwt_token
|
||||
```
|
||||
|
||||
**응답 (200 OK)**:
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"email": "user@example.com",
|
||||
"username": "username",
|
||||
"display_name": "Display Name",
|
||||
"avatar_url": "https://example.com/avatar.jpg",
|
||||
"is_premium": false,
|
||||
"premium_until": null,
|
||||
"created_at": "2023-01-01T00:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### 사용자 정보 업데이트
|
||||
|
||||
```
|
||||
PATCH /users/me
|
||||
```
|
||||
|
||||
**요청 헤더**:
|
||||
```
|
||||
Authorization: Bearer jwt_token
|
||||
```
|
||||
|
||||
**요청 본문**:
|
||||
```json
|
||||
{
|
||||
"display_name": "New Display Name",
|
||||
"avatar_url": "https://example.com/new-avatar.jpg"
|
||||
}
|
||||
```
|
||||
|
||||
**응답 (200 OK)**:
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"email": "user@example.com",
|
||||
"username": "username",
|
||||
"display_name": "New Display Name",
|
||||
"avatar_url": "https://example.com/new-avatar.jpg",
|
||||
"updated_at": "2023-01-02T00:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
## 카드 API
|
||||
|
||||
### 카드 생성
|
||||
|
||||
```
|
||||
POST /cards
|
||||
```
|
||||
|
||||
**요청 헤더**:
|
||||
```
|
||||
Authorization: Bearer jwt_token
|
||||
```
|
||||
|
||||
**요청 본문**:
|
||||
```json
|
||||
{
|
||||
"content": "This is a card content",
|
||||
"background_color": "#FFFFFF",
|
||||
"text_color": "#000000",
|
||||
"font_family": "system",
|
||||
"font_size": 16,
|
||||
"text_align": "center",
|
||||
"is_public": false,
|
||||
"tags": ["personal", "ideas"]
|
||||
}
|
||||
```
|
||||
|
||||
**응답 (201 Created)**:
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"content": "This is a card content",
|
||||
"background_color": "#FFFFFF",
|
||||
"text_color": "#000000",
|
||||
"font_family": "system",
|
||||
"font_size": 16,
|
||||
"text_align": "center",
|
||||
"is_public": false,
|
||||
"is_synced": false,
|
||||
"created_at": "2023-01-01T00:00:00Z",
|
||||
"updated_at": "2023-01-01T00:00:00Z",
|
||||
"tags": ["personal", "ideas"]
|
||||
}
|
||||
```
|
||||
|
||||
### 카드 목록 조회
|
||||
|
||||
```
|
||||
GET /cards
|
||||
```
|
||||
|
||||
**요청 헤더**:
|
||||
```
|
||||
Authorization: Bearer jwt_token
|
||||
```
|
||||
|
||||
**쿼리 파라미터**:
|
||||
- `page`: 페이지 번호 (기본값: 1)
|
||||
- `limit`: 페이지당 항목 수 (기본값: 20, 최대: 100)
|
||||
- `sort`: 정렬 기준 (options: created_at, updated_at, 기본값: created_at)
|
||||
- `order`: 정렬 순서 (options: asc, desc, 기본값: desc)
|
||||
- `tag`: 태그로 필터링 (선택 사항)
|
||||
- `search`: 내용 검색 (선택 사항)
|
||||
|
||||
**응답 (200 OK)**:
|
||||
```json
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"id": "uuid1",
|
||||
"content": "Card 1 content",
|
||||
"background_color": "#FFFFFF",
|
||||
"text_color": "#000000",
|
||||
"font_family": "system",
|
||||
"font_size": 16,
|
||||
"text_align": "center",
|
||||
"is_public": false,
|
||||
"is_synced": false,
|
||||
"created_at": "2023-01-01T00:00:00Z",
|
||||
"updated_at": "2023-01-01T00:00:00Z",
|
||||
"tags": ["personal"]
|
||||
},
|
||||
{
|
||||
"id": "uuid2",
|
||||
"content": "Card 2 content",
|
||||
"background_color": "#F0F0F0",
|
||||
"text_color": "#333333",
|
||||
"font_family": "arial",
|
||||
"font_size": 18,
|
||||
"text_align": "left",
|
||||
"is_public": true,
|
||||
"is_synced": true,
|
||||
"created_at": "2023-01-02T00:00:00Z",
|
||||
"updated_at": "2023-01-02T00:00:00Z",
|
||||
"tags": ["ideas", "public"]
|
||||
}
|
||||
],
|
||||
"pagination": {
|
||||
"total": 42,
|
||||
"page": 1,
|
||||
"limit": 20,
|
||||
"total_pages": 3
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 카드 상세 조회
|
||||
|
||||
```
|
||||
GET /cards/{card_id}
|
||||
```
|
||||
|
||||
**요청 헤더**:
|
||||
```
|
||||
Authorization: Bearer jwt_token
|
||||
```
|
||||
|
||||
**응답 (200 OK)**:
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"content": "This is a card content",
|
||||
"background_color": "#FFFFFF",
|
||||
"text_color": "#000000",
|
||||
"font_family": "system",
|
||||
"font_size": 16,
|
||||
"text_align": "center",
|
||||
"is_public": false,
|
||||
"is_synced": false,
|
||||
"created_at": "2023-01-01T00:00:00Z",
|
||||
"updated_at": "2023-01-01T00:00:00Z",
|
||||
"tags": ["personal", "ideas"],
|
||||
"share_count": 2,
|
||||
"share_platforms": ["facebook", "instagram"]
|
||||
}
|
||||
```
|
||||
|
||||
### 카드 업데이트
|
||||
|
||||
```
|
||||
PATCH /cards/{card_id}
|
||||
```
|
||||
|
||||
**요청 헤더**:
|
||||
```
|
||||
Authorization: Bearer jwt_token
|
||||
```
|
||||
|
||||
**요청 본문**:
|
||||
```json
|
||||
{
|
||||
"content": "Updated card content",
|
||||
"background_color": "#F0F0F0",
|
||||
"is_public": true,
|
||||
"tags": ["personal", "ideas", "updated"]
|
||||
}
|
||||
```
|
||||
|
||||
**응답 (200 OK)**:
|
||||
```json
|
||||
{
|
||||
"id": "uuid",
|
||||
"content": "Updated card content",
|
||||
"background_color": "#F0F0F0",
|
||||
"text_color": "#000000",
|
||||
"font_family": "system",
|
||||
"font_size": 16,
|
||||
"text_align": "center",
|
||||
"is_public": true,
|
||||
"is_synced": false,
|
||||
"created_at": "2023-01-01T00:00:00Z",
|
||||
"updated_at": "2023-01-02T00:00:00Z",
|
||||
"tags": ["personal", "ideas", "updated"]
|
||||
}
|
||||
```
|
||||
|
||||
### 카드 삭제
|
||||
|
||||
```
|
||||
DELETE /cards/{card_id}
|
||||
```
|
||||
|
||||
**요청 헤더**:
|
||||
```
|
||||
Authorization: Bearer jwt_token
|
||||
```
|
||||
|
||||
**응답 (204 No Content)**
|
||||
|
||||
## 소셜 공유 API
|
||||
|
||||
### 소셜 계정 연동
|
||||
|
||||
```
|
||||
POST /social/connect/{platform}
|
||||
```
|
||||
|
||||
**지원 플랫폼**: `facebook`, `instagram`, `twitter`
|
||||
|
||||
**요청 헤더**:
|
||||
```
|
||||
Authorization: Bearer jwt_token
|
||||
```
|
||||
|
||||
**요청 본문**:
|
||||
```json
|
||||
{
|
||||
"access_token": "platform_access_token",
|
||||
"refresh_token": "platform_refresh_token",
|
||||
"expires_at": 1672531200
|
||||
}
|
||||
```
|
||||
|
||||
**응답 (200 OK)**:
|
||||
```json
|
||||
{
|
||||
"platform": "facebook",
|
||||
"connected": true,
|
||||
"platform_user_id": "platform_user_id",
|
||||
"expires_at": 1672531200
|
||||
}
|
||||
```
|
||||
|
||||
### 소셜 계정 연동 해제
|
||||
|
||||
```
|
||||
DELETE /social/connect/{platform}
|
||||
```
|
||||
|
||||
**요청 헤더**:
|
||||
```
|
||||
Authorization: Bearer jwt_token
|
||||
```
|
||||
|
||||
**응답 (204 No Content)**
|
||||
|
||||
### 연동된 소셜 계정 목록
|
||||
|
||||
```
|
||||
GET /social/accounts
|
||||
```
|
||||
|
||||
**요청 헤더**:
|
||||
```
|
||||
Authorization: Bearer jwt_token
|
||||
```
|
||||
|
||||
**응답 (200 OK)**:
|
||||
```json
|
||||
{
|
||||
"accounts": [
|
||||
{
|
||||
"platform": "facebook",
|
||||
"platform_user_id": "facebook_user_id",
|
||||
"connected_at": "2023-01-01T00:00:00Z",
|
||||
"expires_at": 1672531200
|
||||
},
|
||||
{
|
||||
"platform": "instagram",
|
||||
"platform_user_id": "instagram_user_id",
|
||||
"connected_at": "2023-01-02T00:00:00Z",
|
||||
"expires_at": 1672617600
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 카드 소셜 공유
|
||||
|
||||
```
|
||||
POST /cards/{card_id}/share/{platform}
|
||||
```
|
||||
|
||||
**요청 헤더**:
|
||||
```
|
||||
Authorization: Bearer jwt_token
|
||||
```
|
||||
|
||||
**요청 본문**:
|
||||
```json
|
||||
{
|
||||
"message": "Check out my new card!" // 선택적 메시지
|
||||
}
|
||||
```
|
||||
|
||||
**응답 (200 OK)**:
|
||||
```json
|
||||
{
|
||||
"id": "share_id",
|
||||
"card_id": "card_id",
|
||||
"platform": "facebook",
|
||||
"status": "success",
|
||||
"share_url": "https://facebook.com/post/123456",
|
||||
"shared_at": "2023-01-01T00:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
## 구독 API
|
||||
|
||||
### 구독 플랜 목록
|
||||
|
||||
```
|
||||
GET /subscriptions/plans
|
||||
```
|
||||
|
||||
**응답 (200 OK)**:
|
||||
```json
|
||||
{
|
||||
"plans": [
|
||||
{
|
||||
"id": "monthly",
|
||||
"name": "Monthly Premium",
|
||||
"description": "Monthly subscription with cloud sync",
|
||||
"price": 4.99,
|
||||
"currency": "USD",
|
||||
"interval": "month",
|
||||
"features": [
|
||||
"Cloud sync",
|
||||
"Unlimited cards",
|
||||
"Premium templates"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "yearly",
|
||||
"name": "Yearly Premium",
|
||||
"description": "Yearly subscription with cloud sync (save 20%)",
|
||||
"price": 47.99,
|
||||
"currency": "USD",
|
||||
"interval": "year",
|
||||
"features": [
|
||||
"Cloud sync",
|
||||
"Unlimited cards",
|
||||
"Premium templates",
|
||||
"Priority support"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 구독 생성
|
||||
|
||||
```
|
||||
POST /subscriptions
|
||||
```
|
||||
|
||||
**요청 헤더**:
|
||||
```
|
||||
Authorization: Bearer jwt_token
|
||||
```
|
||||
|
||||
**요청 본문**:
|
||||
```json
|
||||
{
|
||||
"plan_id": "monthly",
|
||||
"payment_method_id": "payment_method_id",
|
||||
"payment_provider": "stripe"
|
||||
}
|
||||
```
|
||||
|
||||
**응답 (201 Created)**:
|
||||
```json
|
||||
{
|
||||
"id": "subscription_id",
|
||||
"plan_id": "monthly",
|
||||
"status": "active",
|
||||
"start_date": "2023-01-01T00:00:00Z",
|
||||
"end_date": "2023-02-01T00:00:00Z",
|
||||
"payment_provider": "stripe",
|
||||
"payment_id": "payment_id"
|
||||
}
|
||||
```
|
||||
|
||||
### 현재 구독 정보
|
||||
|
||||
```
|
||||
GET /subscriptions/current
|
||||
```
|
||||
|
||||
**요청 헤더**:
|
||||
```
|
||||
Authorization: Bearer jwt_token
|
||||
```
|
||||
|
||||
**응답 (200 OK)**:
|
||||
```json
|
||||
{
|
||||
"id": "subscription_id",
|
||||
"plan_id": "monthly",
|
||||
"status": "active",
|
||||
"start_date": "2023-01-01T00:00:00Z",
|
||||
"end_date": "2023-02-01T00:00:00Z",
|
||||
"auto_renew": true,
|
||||
"payment_provider": "stripe",
|
||||
"payment_id": "payment_id"
|
||||
}
|
||||
```
|
||||
|
||||
### 구독 취소
|
||||
|
||||
```
|
||||
POST /subscriptions/cancel
|
||||
```
|
||||
|
||||
**요청 헤더**:
|
||||
```
|
||||
Authorization: Bearer jwt_token
|
||||
```
|
||||
|
||||
**응답 (200 OK)**:
|
||||
```json
|
||||
{
|
||||
"id": "subscription_id",
|
||||
"status": "canceled",
|
||||
"end_date": "2023-02-01T00:00:00Z",
|
||||
"message": "Subscription will be active until the end date"
|
||||
}
|
||||
```
|
||||
|
||||
## 오류 응답
|
||||
|
||||
모든 API 엔드포인트는 오류 발생 시 다음과 같은 형식으로 응답합니다:
|
||||
|
||||
**응답 (4xx/5xx)**:
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"code": "error_code",
|
||||
"message": "Error message description",
|
||||
"details": {} // 추가 오류 정보 (선택 사항)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 공통 오류 코드
|
||||
|
||||
- `invalid_request`: 잘못된 요청 형식
|
||||
- `authentication_required`: 인증 필요
|
||||
- `invalid_credentials`: 잘못된 인증 정보
|
||||
- `permission_denied`: 권한 없음
|
||||
- `resource_not_found`: 리소스를 찾을 수 없음
|
||||
- `rate_limit_exceeded`: 요청 한도 초과
|
||||
- `internal_server_error`: 서버 내부 오류
|
||||
|
||||
## 웹훅 (Webhook)
|
||||
|
||||
Zellyy는 다음 이벤트에 대한 웹훅을 제공합니다:
|
||||
|
||||
### 웹훅 등록
|
||||
|
||||
```
|
||||
POST /webhooks
|
||||
```
|
||||
|
||||
**요청 헤더**:
|
||||
```
|
||||
Authorization: Bearer admin_token
|
||||
```
|
||||
|
||||
**요청 본문**:
|
||||
```json
|
||||
{
|
||||
"url": "https://your-service.com/webhook",
|
||||
"events": ["user.created", "subscription.created", "subscription.canceled"],
|
||||
"secret": "your_webhook_secret"
|
||||
}
|
||||
```
|
||||
|
||||
**응답 (201 Created)**:
|
||||
```json
|
||||
{
|
||||
"id": "webhook_id",
|
||||
"url": "https://your-service.com/webhook",
|
||||
"events": ["user.created", "subscription.created", "subscription.canceled"],
|
||||
"created_at": "2023-01-01T00:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### 웹훅 이벤트 형식
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "event_id",
|
||||
"type": "event.type",
|
||||
"created_at": "2023-01-01T00:00:00Z",
|
||||
"data": {
|
||||
// 이벤트 관련 데이터
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 결론
|
||||
|
||||
이 API 명세서는 Zellyy 프로젝트의 기본 기능을 구현하기 위한 엔드포인트를 정의합니다. 프로젝트가 발전함에 따라 추가 엔드포인트와 기능이 확장될 수 있습니다.
|
||||
Reference in New Issue
Block a user