fromis_9/docs/api.md
caadiq dc216a0f98 docs: API 문서 업데이트
- 멤버 API: 영문명 조회 지원 추가
- 일정 API: 특수 일정 ID 형식 설명 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-25 20:39:39 +09:00

7.6 KiB

API 명세

Base URL: /api

인증

POST /auth/login

로그인 (JWT 토큰 발급)

Rate Limit: 1분당 5회 (IP 기준)

GET /auth/verify

토큰 검증 및 사용자 정보 (인증 필요)


멤버

GET /members

멤버 목록 조회

GET /members/:name

멤버 상세 조회

Parameters:

  • name - 멤버 이름 (한글 또는 영문, 대소문자 무관)

예시:

  • /members/박지원 - 한글명으로 조회
  • /members/jiwon - 영문명으로 조회

앨범

GET /albums

앨범 목록 조회

GET /albums/:id

앨범 상세 조회


일정

GET /schedules

일정 조회

Query Parameters:

  • year, month - 월별 조회
  • startDate - 시작 날짜 (YYYY-MM-DD), 다가오는 일정 조회
  • search - 검색어 (Meilisearch 사용)
  • offset, limit - 페이징

search, startDate, year/month 중 하나는 필수

월별 조회 응답:

{
  "schedules": [
    {
      "id": 123,
      "title": "...",
      "date": "2026-01-18",
      "time": "19:00:00",
      "category": { "id": 2, "name": "유튜브", "color": "#ff0033" },
      "source": {
        "name": "fromis_9",
        "url": "https://www.youtube.com/watch?v=VIDEO_ID"
      },
      "members": ["송하영"]
    }
  ]
}

특수 일정 ID 형식:

  • 생일: birthday-{year}-{nameEn} (예: birthday-2026-jiwon)
  • 데뷔: debut-{year} (예: debut-2018)
  • 주년: anniversary-{year} (예: anniversary-2026) ※ time: 시간이 없는 일정은 null, 00:00 시간은 "00:00:00"으로 반환

**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):**
```json
{
  "schedules": [
    {
      "id": 123,
      "title": "...",
      "date": "2026-01-18",
      "time": "19:00:00",
      "category": { "id": 2, "name": "유튜브", "color": "#ff0033" },
      "source": { "name": "fromis_9", "url": "https://..." },
      "members": ["송하영"]
    }
  ]
}

※ 현재 활동 멤버 전원인 경우 ["프로미스나인"] 반환 (탈퇴 멤버 제외) ※ time: 시간이 없는 일정은 null, 00:00 시간은 "00:00:00"으로 반환

검색 응답:

{
  "schedules": [
    {
      "id": 123,
      "title": "...",
      "date": "2026-01-18",
      "time": "19: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
}

time: 시간이 없는 일정은 null, 00:00 시간은 "00:00:00"으로 반환


### GET /schedules/categories
카테고리 목록 조회

**응답:**
```json
[
  { "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": ["송하영", "송하영 직캠", "하영"]
}

인기 검색어 조회

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-18T19:30:00+09:00",
    "last_added_count": 2,
    "last_sync_duration": 1234,
    "schedules_added": 150,
    "check_interval": 2,
    "error_message": null,
    "enabled": true
  },
  {
    "id": "meilisearch-sync",
    "name": "Meilisearch 동기화",
    "type": "meilisearch",
    "status": "running",
    "last_check_at": "2026-01-18T04:00:00+09:00",
    "last_added_count": 500,
    "last_sync_duration": 2500,
    "schedules_added": 500,
    "check_interval": 0,
    "error_message": null,
    "enabled": true,
    "version": "1.6.0"
  }
]

필드 설명:

  • last_check_at: 마지막 동기화 시간 (KST, +09:00)
  • last_sync_duration: 마지막 동기화 소요 시간 (ms)
  • version: Meilisearch 버전 (meilisearch 타입만)

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-18T19:00:00+09:00"
}

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 스펙