fromis_9/docs/x-bots-plan.md
caadiq 4f11e14b12 refactor(db): 봇 테이블 이름 통일 및 X 봇 스키마 추가
- youtube_bots → bot_youtube, x_bots → bot_x로 테이블 이름 변경
- bot_x 테이블 생성 및 시드 데이터 추가
- 관련 백엔드 코드에서 테이블 참조 업데이트
- X 봇 동적 관리 구현 계획 문서 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 19:52:41 +09:00

7.6 KiB

X 봇 동적 관리 기능 구현 계획

개요

현재 config/bots.js에 하드코딩된 X 봇 설정을 DB 기반으로 변경하여, 관리 페이지에서 X 계정을 추가/수정/삭제할 수 있도록 함.

현재 구조

// config/bots.js
{
  id: 'x-fromis9',
  type: 'x',
  username: 'realfromis_9',
  nitterUrl: process.env.NITTER_URL || 'http://nitter:8080',
  cron: '*/1 * * * *',
  enabled: true,
}

주요 기능

  1. X username 입력 → Nitter를 통해 프로필 정보 조회 (displayName, avatarUrl)
  2. 동기화 간격 설정 (분 단위)
  3. 봇 활성화/비활성화
  4. 봇 삭제

1. DB 스키마

bot_x 테이블 생성

CREATE TABLE IF NOT EXISTS bot_x (
  id INT AUTO_INCREMENT PRIMARY KEY,
  username VARCHAR(50) NOT NULL,
  display_name VARCHAR(100),
  avatar_url VARCHAR(500),
  cron_interval INT DEFAULT 1,
  enabled TINYINT(1) DEFAULT 1,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  UNIQUE KEY uk_username (username)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

파일: backend/sql/bot_x.sql

시드 데이터

INSERT INTO bot_x (username, display_name, cron_interval, enabled)
VALUES ('realfromis_9', 'fromis_9', 1, 1)
ON DUPLICATE KEY UPDATE display_name = VALUES(display_name);

파일: backend/sql/bot_x_seed.sql


2. 백엔드 API

2.1 프로필 조회 API (신규)

POST /api/admin/x-bots/lookup

Nitter를 통해 X 계정 프로필 정보 조회.

// 요청
{ "username": "realfromis_9" }

// 응답
{
  "username": "realfromis_9",
  "displayName": "fromis_9",
  "avatarUrl": "https://pbs.twimg.com/profile_images/..."
}

구현: services/x/scraper.jsfetchTweets 함수 활용

2.2 봇 CRUD API (신규)

파일: backend/src/routes/admin/x-bots.js

메서드 경로 설명
GET /api/admin/x-bots 봇 목록 조회
GET /api/admin/x-bots/:id 봇 상세 조회
POST /api/admin/x-bots 봇 추가
PUT /api/admin/x-bots/:id 봇 수정
DELETE /api/admin/x-bots/:id 봇 삭제

2.3 기존 봇 API 수정

파일: backend/src/routes/admin/bots.js

  • GET /api/admin/bots: DB에서 X 봇 목록도 조회하도록 수정
  • X 봇 상세 정보 추가 (db_id, username, display_name, avatar_url 등)

3. 스케줄러 수정

파일: backend/src/plugins/scheduler.js

변경 사항

  1. getXBotsFromDB() 함수 추가
  2. getAllBots()에서 X 봇도 DB에서 로드
  3. config/bots.js에서 X 봇 제거
async function getXBotsFromDB() {
  const [rows] = await fastify.db.query(
    'SELECT * FROM bot_x WHERE enabled = 1'
  );
  return rows.map(row => ({
    id: `x-${row.id}`,
    dbId: row.id,
    type: 'x',
    username: row.username,
    displayName: row.display_name,
    avatarUrl: row.avatar_url,
    nitterUrl: process.env.NITTER_URL || 'http://nitter:8080',
    cron: `*/${row.cron_interval} * * * *`,
    enabled: row.enabled === 1,
  }));
}

async function getAllBots(forceRefresh = false) {
  if (cachedBots && !forceRefresh) {
    return cachedBots;
  }
  const xBots = await getXBotsFromDB();
  const youtubeBots = await getYouTubeBotsFromDB();
  cachedBots = [...staticBots, ...xBots, ...youtubeBots];
  return cachedBots;
}

4. 프론트엔드 UI

4.1 봇 추가/수정 다이얼로그

파일: frontend/src/components/pc/admin/bot/XBotDialog.jsx

입력 필드:

  • X username 입력 → "조회" 버튼 → Nitter에서 프로필 정보 가져와 표시
  • 동기화 간격 (분): 드롭다운 (1, 2, 5, 10, 30, 60)

4.2 봇 목록 페이지 수정

파일: frontend/src/pages/pc/admin/schedules/ScheduleBots.jsx

  • X 섹션에 "봇 추가" 버튼 추가 (canAdd: true)
  • X 봇도 수정/삭제 버튼 표시

4.3 API 클라이언트

파일: frontend/src/api/admin/bots.js

export const lookupXProfile = (username) =>
  fetchAuthApi('/admin/x-bots/lookup', { method: 'POST', body: JSON.stringify({ username }) });
export const getXBot = (id) => fetchAuthApi(`/admin/x-bots/${id}`);
export const createXBot = (data) => fetchAuthApi('/admin/x-bots', { method: 'POST', body: JSON.stringify(data) });
export const updateXBot = (id, data) => fetchAuthApi(`/admin/x-bots/${id}`, { method: 'PUT', body: JSON.stringify(data) });
export const deleteXBot = (id) => fetchAuthApi(`/admin/x-bots/${id}`, { method: 'DELETE' });

5. 파일 변경 목록

신규 파일

파일 설명
backend/sql/bot_x.sql 테이블 생성 SQL
backend/sql/bot_x_seed.sql 초기 데이터 SQL
backend/src/routes/admin/x-bots.js X 봇 CRUD API
frontend/src/components/pc/admin/bot/XBotDialog.jsx 봇 추가/수정 다이얼로그

수정 파일

파일 변경 내용
backend/src/plugins/scheduler.js X 봇 DB 로드 추가
backend/src/routes/admin/bots.js X 봇 상세 정보 추가
backend/src/routes/index.js x-bots 라우트 등록
backend/src/config/bots.js X 봇 제거 (meilisearch만 남김)
frontend/src/pages/pc/admin/schedules/ScheduleBots.jsx X 섹션 canAdd, 다이얼로그 연결
frontend/src/components/pc/admin/bot/index.js XBotDialog export
frontend/src/api/admin/bots.js X 봇 API 함수 추가

6. 구현 순서

단계 1: DB 스키마 생성

  1. backend/sql/bot_x.sql 파일 생성
  2. backend/sql/bot_x_seed.sql 파일 생성
  3. DB에 테이블 생성 및 시드 데이터 삽입

단계 2: Nitter 프로필 조회 함수 추가

  1. backend/src/services/x/scraper.jsfetchProfile() 함수 추가
    • Nitter에서 username으로 프로필 정보(displayName, avatarUrl) 조회

단계 3: X 봇 CRUD API 생성

  1. backend/src/routes/admin/x-bots.js 파일 생성
    • POST /lookup: 프로필 조회
    • GET /: 봇 목록 조회
    • GET /:id: 봇 상세 조회
    • POST /: 봇 추가
    • PUT /:id: 봇 수정
    • DELETE /:id: 봇 삭제
  2. backend/src/routes/index.js에 x-bots 라우트 등록

단계 4: 스케줄러 수정

  1. backend/src/plugins/scheduler.jsgetXBotsFromDB() 함수 추가
  2. getBots()에서 X 봇도 DB에서 로드하도록 수정
  3. backend/src/config/bots.js에서 X 봇 제거

단계 5: 기존 봇 API 수정

  1. backend/src/routes/admin/bots.js 스키마에 X 봇 필드 추가
    • db_id, username, display_name, avatar_url

단계 6: 프론트엔드 API 클라이언트

  1. frontend/src/api/admin/bots.js에 X 봇 API 함수 추가
    • lookupXProfile, getXBot, createXBot, updateXBot, deleteXBot

단계 7: X 봇 다이얼로그 컴포넌트 생성

  1. frontend/src/components/pc/admin/bot/XBotDialog.jsx 생성
    • username 입력 → "조회" 버튼 → 프로필 정보 표시
    • 동기화 간격 선택
    • 추가/수정 폼 제출
  2. frontend/src/components/pc/admin/bot/index.js에 export 추가

단계 8: 봇 목록 페이지 수정

  1. frontend/src/pages/pc/admin/schedules/ScheduleBots.jsx 수정
    • X 섹션에 canAdd: true 추가
    • XBotDialog 연결
    • 수정/삭제 핸들러 연결

7. 검증 방법

  1. DB 테이블 확인: SELECT * FROM bot_x
  2. 프로필 조회 API: username 입력 → displayName, avatarUrl 반환 확인
  3. 봇 추가: 새 X 계정 추가 후 목록에 표시, 스케줄러 동작 확인
  4. 봇 수정: 동기화 간격 변경 후 cron 재등록 확인
  5. 봇 삭제: 삭제 후 목록에서 제거, 스케줄러 중지 확인