- 백엔드: buildMemberMap, getScheduleDetail 함수에서 현재 활동 멤버 전원인 경우 "프로미스나인"으로 대체하여 반환 - 프론트엔드: getDisplayMembers 함수에서 멤버 수 계산 로직 제거 (백엔드에서 처리) - 탈퇴 멤버(is_former=1) 제외하고 현재 활동 멤버만 계산 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
6.3 KiB
API 명세
Base URL: /api
인증
POST /auth/login
로그인 (JWT 토큰 발급)
GET /auth/verify
토큰 검증 및 사용자 정보 (인증 필요)
멤버
GET /members
멤버 목록 조회
GET /members/:id
멤버 상세 조회
앨범
GET /albums
앨범 목록 조회
GET /albums/:id
앨범 상세 조회
일정
GET /schedules
일정 조회
Query Parameters:
year,month- 월별 조회startDate- 시작 날짜 (YYYY-MM-DD), 다가오는 일정 조회search- 검색어 (Meilisearch 사용)offset,limit- 페이징
※ search, startDate, year/month 중 하나는 필수
월별 조회 응답:
{
"2026-01-18": {
"categories": [
{ "id": 2, "name": "유튜브", "color": "#ff0033", "count": 3 }
],
"schedules": [
{
"id": 123,
"title": "...",
"time": "19:00:00",
"category": { "id": 2, "name": "유튜브", "color": "#ff0033" },
"source": {
"name": "fromis_9",
"url": "https://www.youtube.com/watch?v=VIDEO_ID"
}
}
]
}
}
source 객체 (카테고리별):
- YouTube (category_id=2):
{ name: "채널명", url: "https://www.youtube.com/..." } - X (category_id=3):
{ name: "", url: "https://x.com/realfromis_9/status/..." }(name 빈 문자열) - 기타 카테고리: source 없음
다가오는 일정 응답 (startDate):
[
{
"id": 123,
"title": "...",
"date": "2026-01-18",
"time": "19:00:00",
"category_id": 2,
"category_name": "유튜브",
"category_color": "#ff0033",
"members": [{ "name": "송하영" }]
}
]
※ 현재 활동 멤버 전원인 경우 [{ "name": "프로미스나인" }] 반환 (탈퇴 멤버 제외)
검색 응답:
{
"schedules": [
{
"id": 123,
"title": "...",
"datetime": "2026-01-18T19:00:00",
"category": { "id": 2, "name": "유튜브", "color": "#ff0033" },
"source": { "name": "fromis_9", "url": "https://..." },
"members": ["송하영"],
"_rankingScore": 0.95
}
],
"total": 100,
"offset": 0,
"limit": 20,
"hasMore": true
}
GET /schedules/categories
카테고리 목록 조회
응답:
[
{ "id": 1, "name": "기타", "color": "#gray", "sort_order": 0 },
{ "id": 2, "name": "유튜브", "color": "#ff0033", "sort_order": 1 }
]
GET /schedules/:id
일정 상세 조회
DELETE /schedules/:id
일정 삭제 (인증 필요)
POST /schedules/sync-search
Meilisearch 전체 동기화 (인증 필요)
추천 검색어
GET /schedules/suggestions
추천 검색어 조회
Query Parameters:
q- 검색어 (2자 이상)limit- 결과 개수 (기본 10)
응답:
{
"suggestions": ["송하영", "송하영 직캠", "하영"]
}
GET /schedules/suggestions/popular
인기 검색어 조회
Query Parameters:
limit- 결과 개수 (기본 10)
응답:
{
"queries": ["프로미스나인", "송하영", "이서연"]
}
POST /schedules/suggestions/save
검색어 저장 (검색 실행 시 호출)
Request Body:
{
"query": "검색어"
}
GET /schedules/suggestions/dict
사용자 사전 조회 (인증 필요)
응답:
{
"content": "프로미스나인\t프로미스나인\tNNP\n..."
}
PUT /schedules/suggestions/dict
사용자 사전 저장 (인증 필요)
Request Body:
{
"content": "프로미스나인\t프로미스나인\tNNP\n..."
}
관리자 - 봇 관리 (인증 필요)
GET /admin/bots
봇 목록 조회
응답:
[
{
"id": "youtube-fromis9",
"name": "fromis_9",
"type": "youtube",
"status": "running",
"last_check_at": "2026-01-18T10:30:00Z",
"last_added_count": 2,
"schedules_added": 150,
"check_interval": 2,
"error_message": null,
"enabled": true
}
]
POST /admin/bots/:id/start
봇 시작
POST /admin/bots/:id/stop
봇 정지
POST /admin/bots/:id/sync-all
전체 동기화 (모든 영상/트윗 수집)
응답:
{
"success": true,
"addedCount": 25,
"total": 100
}
GET /admin/bots/quota-warning
YouTube API 할당량 경고 조회
응답:
{
"active": true,
"message": "YouTube API 할당량 초과",
"timestamp": "2026-01-18T10:00:00Z"
}
DELETE /admin/bots/quota-warning
할당량 경고 해제
관리자 - YouTube (인증 필요)
GET /admin/youtube/video-info
YouTube 영상 정보 조회
Query Parameters:
url- YouTube URL (watch, shorts, youtu.be 모두 지원)
응답:
{
"videoId": "abc123",
"title": "영상 제목",
"channelId": "UCxxx",
"channelName": "채널명",
"date": "2026-01-19",
"time": "15:00:00",
"videoType": "video",
"videoUrl": "https://www.youtube.com/watch?v=abc123"
}
POST /admin/youtube/schedule
YouTube 일정 저장
Request Body:
{
"videoId": "abc123",
"title": "영상 제목",
"channelId": "UCxxx",
"channelName": "채널명",
"date": "2026-01-19",
"time": "15:00:00",
"videoType": "video"
}
PUT /admin/youtube/schedule/:id
YouTube 일정 수정 (멤버, 영상 유형)
Request Body:
{
"memberIds": [1, 2, 3],
"videoType": "video"
}
※ videoType: "video" 또는 "shorts"
관리자 - X (인증 필요)
GET /admin/x/post-info
X 게시글 정보 조회 (Nitter 스크래핑)
Query Parameters:
postId- 게시글 ID (필수)username- 사용자명 (기본: realfromis_9)
응답:
{
"postId": "1234567890",
"username": "realfromis_9",
"text": "게시글 전체 내용",
"title": "첫 문단 (자동 추출)",
"imageUrls": ["https://pbs.twimg.com/media/..."],
"date": "2026-01-19",
"time": "15:00:00",
"postUrl": "https://x.com/realfromis_9/status/1234567890",
"profile": {
"displayName": "프로미스나인 (fromis_9)",
"avatarUrl": "https://..."
}
}
POST /admin/x/schedule
X 일정 저장
Request Body:
{
"postId": "1234567890",
"title": "게시글 제목",
"content": "게시글 내용",
"imageUrls": ["https://..."],
"date": "2026-01-19",
"time": "15:00:00"
}
헬스 체크
GET /health
서버 상태 확인
API 문서
GET /docs
Scalar API Reference UI
GET /docs/json
OpenAPI JSON 스펙