From d4ed9ef66bed431b8185952a8779ca42751a9058 Mon Sep 17 00:00:00 2001 From: caadiq Date: Mon, 9 Feb 2026 22:56:15 +0900 Subject: [PATCH] =?UTF-8?q?chore:=20x-bots-plan.md=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.5 --- docs/x-bots-plan.md | 252 -------------------------------------------- 1 file changed, 252 deletions(-) delete mode 100644 docs/x-bots-plan.md diff --git a/docs/x-bots-plan.md b/docs/x-bots-plan.md deleted file mode 100644 index af6cddd..0000000 --- a/docs/x-bots-plan.md +++ /dev/null @@ -1,252 +0,0 @@ -# X 봇 동적 관리 기능 구현 계획 - -## 개요 -현재 `config/bots.js`에 하드코딩된 X 봇 설정을 DB 기반으로 변경하여, 관리 페이지에서 X 계정을 추가/수정/삭제할 수 있도록 함. - -## 현재 구조 -```javascript -// 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` 테이블 생성 - -```sql -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` - -### 시드 데이터 - -```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 계정 프로필 정보 조회. - -```javascript -// 요청 -{ "username": "realfromis_9" } - -// 응답 -{ - "username": "realfromis_9", - "displayName": "fromis_9", - "avatarUrl": "https://pbs.twimg.com/profile_images/..." -} -``` - -**구현**: `services/x/scraper.js`의 `fetchTweets` 함수 활용 - -### 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 봇 제거 - -```javascript -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` - -```javascript -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.js`에 `fetchProfile()` 함수 추가 - - 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.js`에 `getXBotsFromDB()` 함수 추가 -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. **봇 삭제**: 삭제 후 목록에서 제거, 스케줄러 중지 확인