diff --git a/docs/api.md b/docs/api.md index 967f4b9..d3c5759 100644 --- a/docs/api.md +++ b/docs/api.md @@ -7,8 +7,8 @@ Base URL: `/api` ### POST /auth/login 로그인 (JWT 토큰 발급) -### GET /auth/me -현재 사용자 정보 (인증 필요) +### GET /auth/verify +토큰 검증 및 사용자 정보 (인증 필요) --- @@ -149,6 +149,49 @@ Meilisearch 전체 동기화 (인증 필요) } ``` +### GET /schedules/suggestions/popular +인기 검색어 조회 + +**Query Parameters:** +- `limit` - 결과 개수 (기본 10) + +**응답:** +```json +{ + "queries": ["프로미스나인", "송하영", "이서연"] +} +``` + +### POST /schedules/suggestions/save +검색어 저장 (검색 실행 시 호출) + +**Request Body:** +```json +{ + "query": "검색어" +} +``` + +### GET /schedules/suggestions/dict +사용자 사전 조회 (인증 필요) + +**응답:** +```json +{ + "content": "프로미스나인\t프로미스나인\tNNP\n..." +} +``` + +### PUT /schedules/suggestions/dict +사용자 사전 저장 (인증 필요) + +**Request Body:** +```json +{ + "content": "프로미스나인\t프로미스나인\tNNP\n..." +} +``` + --- ## 관리자 - 봇 관리 (인증 필요) diff --git a/docs/architecture.md b/docs/architecture.md index f2c2a27..ab596f3 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -16,12 +16,22 @@ fromis_9/ │ │ │ ├── meilisearch.js # 검색 엔진 │ │ │ └── scheduler.js # 봇 스케줄러 │ │ ├── routes/ # API 라우트 -│ │ │ ├── auth/ -│ │ │ ├── members/ +│ │ │ ├── admin/ # 관리자 API +│ │ │ │ ├── bots.js # 봇 관리 +│ │ │ │ ├── youtube.js # YouTube 일정 관리 +│ │ │ │ └── x.js # X 일정 관리 │ │ │ ├── albums/ +│ │ │ │ ├── index.js # 앨범 CRUD +│ │ │ │ ├── photos.js # 앨범 사진 관리 +│ │ │ │ └── teasers.js # 앨범 티저 관리 +│ │ │ ├── auth.js # 인증 (로그인, 토큰 검증) +│ │ │ ├── members/ +│ │ │ │ └── index.js # 멤버 조회/수정 │ │ │ ├── schedules/ -│ │ │ │ ├── index.js # 일정 조회/검색 -│ │ │ │ └── suggestions.js +│ │ │ │ ├── index.js # 일정 조회/검색/삭제 +│ │ │ │ └── suggestions.js # 추천 검색어 +│ │ │ ├── stats/ +│ │ │ │ └── index.js # 통계 조회 │ │ │ └── index.js # 라우트 등록 │ │ ├── services/ # 비즈니스 로직 │ │ │ ├── youtube/ # YouTube 봇 @@ -40,7 +50,18 @@ fromis_9/ │ │ ├── api/ # API 클라이언트 │ │ │ ├── index.js # fetchApi 유틸 │ │ │ ├── public/ # 공개 API +│ │ │ │ ├── albums.js +│ │ │ │ ├── members.js +│ │ │ │ └── schedules.js │ │ │ └── admin/ # 어드민 API +│ │ │ ├── albums.js +│ │ │ ├── auth.js +│ │ │ ├── bots.js +│ │ │ ├── categories.js +│ │ │ ├── members.js +│ │ │ ├── schedules.js +│ │ │ ├── stats.js +│ │ │ └── suggestions.js │ │ ├── components/ # 공통 컴포넌트 │ │ │ └── common/ │ │ │ ├── Lightbox.jsx # 이미지 라이트박스 (PC) diff --git a/docs/development.md b/docs/development.md index 2d5a576..bed1934 100644 --- a/docs/development.md +++ b/docs/development.md @@ -166,6 +166,35 @@ docker exec caddy caddy reload --config /etc/caddy/Caddyfile ## 프론트엔드 개발 가이드 +### API 클라이언트 구조 + +``` +src/api/ +├── index.js # fetchApi 유틸 (에러 처리, 토큰 주입) +├── public/ # 공개 API (인증 불필요) +│ ├── albums.js # getAlbums, getAlbumByName, getTrack +│ ├── members.js # getMembers +│ └── schedules.js # getSchedules, getSchedule, getCategories +└── admin/ # 관리자 API (인증 필요) + ├── auth.js # login, verifyToken + ├── albums.js # createAlbum, updateAlbum, deleteAlbum, ... + ├── bots.js # getBots, startBot, stopBot, syncBot + ├── categories.js # getCategories + ├── members.js # updateMember + ├── schedules.js # getYoutubeInfo, saveYoutube, getXInfo, saveX, ... + ├── stats.js # getStats + └── suggestions.js # getDict, saveDict +``` + +**사용 예시:** +```jsx +// 공개 API +import { getSchedules, getSchedule } from '@/api/public/schedules'; + +// 관리자 API +import { getBots, startBot } from '@/api/admin/bots'; +``` + ### React Query 사용 (데이터 페칭) 데이터 페칭 시 `useEffect` 대신 `useQuery`를 사용합니다. diff --git a/docs/migration.md b/docs/migration.md index 91ded01..2a84e3b 100644 --- a/docs/migration.md +++ b/docs/migration.md @@ -2,7 +2,7 @@ ## 개요 -`backend-backup/` (Express) → `backend/` (Fastify)로 마이그레이션 진행 중 +`backend-backup/` (Express) → `backend/` (Fastify)로 마이그레이션 완료 ## 완료된 작업 @@ -18,7 +18,7 @@ ### API 라우트 (`src/routes/`) - [x] 인증 (`/api/auth`) - POST /login - 로그인 - - GET /me - 현재 사용자 정보 + - GET /verify - 토큰 검증 - [x] 멤버 (`/api/members`) - GET / - 목록 조회 - GET /:name - 상세 조회 @@ -40,19 +40,37 @@ - GET / - 목록 - POST / - 업로드 - DELETE /:teaserId - 삭제 -- [x] 일정 (`/api/schedules`) - 조회만 +- [x] 일정 (`/api/schedules`) - GET / - 월별 조회 (생일 포함) - GET /?search= - Meilisearch 검색 - GET /:id - 상세 조회 + - DELETE /:id - 삭제 - POST /sync-search - Meilisearch 동기화 - [x] 추천 검색어 (`/api/schedules/suggestions`) - GET / - 추천 검색어 조회 - - kiwi-nlp 형태소 분석 - - bi-gram 자동완성 - - 초성 검색 + - GET /popular - 인기 검색어 조회 + - POST /save - 검색어 저장 + - GET /dict - 사용자 사전 조회 (관리자) + - PUT /dict - 사용자 사전 저장 (관리자) - [x] 통계 (`/api/stats`) - GET / - 대시보드 통계 +### 관리자 API (`src/routes/admin/`) +- [x] 봇 관리 (`/api/admin/bots`) + - GET / - 봇 목록 + - POST /:id/start - 봇 시작 + - POST /:id/stop - 봇 정지 + - POST /:id/sync-all - 전체 동기화 + - GET /quota-warning - 할당량 경고 조회 + - DELETE /quota-warning - 할당량 경고 해제 +- [x] YouTube 관리 (`/api/admin/youtube`) + - GET /video-info - 영상 정보 조회 + - POST /schedule - 일정 저장 + - PUT /schedule/:id - 일정 수정 +- [x] X 관리 (`/api/admin/x`) + - GET /post-info - 게시글 정보 조회 + - POST /schedule - 일정 저장 + ### 서비스 (`src/services/`) - [x] YouTube 봇 (`services/youtube/`) - 영상 자동 수집 @@ -64,41 +82,33 @@ - 일정 검색 - 전체 동기화 - [x] 추천 검색어 (`services/suggestions/`) - - 형태소 분석 + - 형태소 분석 (kiwi-nlp) - bi-gram 빈도 + - 초성 검색 + - 사용자 사전 관리 - [x] 이미지 업로드 (`services/image.js`) - 앨범 커버 - 멤버 이미지 - 앨범 사진/티저 -## 남은 작업 +## 남은 작업 (미구현) -### 관리자 API (admin.js에서 마이그레이션 필요) -- [ ] 일정 CRUD - - POST /api/schedules - 생성 - - PUT /api/schedules/:id - 수정 - - DELETE /api/schedules/:id - 삭제 -- [ ] 일정 카테고리 CRUD - - GET /api/schedule-categories - 목록 - - POST /api/schedule-categories - 생성 - - PUT /api/schedule-categories/:id - 수정 - - DELETE /api/schedule-categories/:id - 삭제 - - PUT /api/schedule-categories-order - 순서 변경 -- [ ] 봇 관리 API - - GET /api/bots - 봇 목록 - - POST /api/bots/:id/start - 봇 시작 - - POST /api/bots/:id/stop - 봇 정지 - - POST /api/bots/:id/sync-all - 전체 동기화 -- [ ] 카카오 장소 검색 프록시 - - GET /api/kakao/places - 장소 검색 -- [ ] YouTube 할당량 관리 - - POST /api/quota-alert - Webhook 수신 - - GET /api/quota-warning - 경고 상태 조회 - - DELETE /api/quota-warning - 경고 해제 +### 일반 일정 CRUD +- [ ] POST /api/schedules - 일정 생성 (일반) +- [ ] PUT /api/schedules/:id - 일정 수정 (일반) -### 기타 기능 -- [ ] X 프로필 조회 (`/api/schedules/x-profile/:username`) -- [ ] 어드민 사전 관리 (형태소 분석용 사전) +※ 현재는 YouTube/X 전용 일정 생성 API만 구현됨 + +### 카테고리 관리 +- [ ] POST /api/schedule-categories - 생성 +- [ ] PUT /api/schedule-categories/:id - 수정 +- [ ] DELETE /api/schedule-categories/:id - 삭제 +- [ ] PUT /api/schedule-categories-order - 순서 변경 + +※ GET은 구현됨 (목록 조회) + +### 기타 +- [ ] GET /api/kakao/places - 카카오 장소 검색 프록시 ## 파일 비교표 @@ -108,14 +118,17 @@ | routes/admin.js (앨범 CRUD) | routes/albums/index.js | 완료 | | routes/admin.js (사진/티저) | routes/albums/photos.js, teasers.js | 완료 | | routes/admin.js (멤버 수정) | routes/members/index.js | 완료 | -| routes/admin.js (일정 CRUD) | - | 미완료 | -| routes/admin.js (카테고리) | - | 미완료 | -| routes/admin.js (봇 관리) | - | 미완료 | +| routes/admin.js (일정 삭제) | routes/schedules/index.js | 완료 | +| routes/admin.js (일정 생성/수정) | - | 미완료 | +| routes/admin.js (카테고리 CUD) | - | 미완료 | +| routes/admin.js (봇 관리) | routes/admin/bots.js | 완료 | +| routes/admin.js (할당량) | routes/admin/bots.js | 완료 | | routes/admin.js (카카오) | - | 미완료 | -| routes/admin.js (할당량) | - | 미완료 | +| - | routes/admin/youtube.js | 신규 | +| - | routes/admin/x.js | 신규 | | routes/albums.js | routes/albums/index.js | 완료 | | routes/members.js | routes/members/index.js | 완료 | -| routes/schedules.js | routes/schedules/index.js | 부분 완료 | +| routes/schedules.js | routes/schedules/index.js | 완료 | | routes/stats.js | routes/stats/index.js | 완료 | | services/youtube-bot.js | services/youtube/ | 완료 | | services/youtube-scheduler.js | plugins/scheduler.js | 완료 | diff --git a/frontend/src/pages/mobile/public/ScheduleDetail.jsx b/frontend/src/pages/mobile/public/ScheduleDetail.jsx index f2cc58d..368960f 100644 --- a/frontend/src/pages/mobile/public/ScheduleDetail.jsx +++ b/frontend/src/pages/mobile/public/ScheduleDetail.jsx @@ -200,12 +200,12 @@ function YoutubeSection({ schedule }) { - {/* 영상 정보 카드 */} + {/* 영상 정보 */} {/* 제목 */}

@@ -247,17 +247,19 @@ function YoutubeSection({ schedule }) { )} {/* 유튜브에서 보기 버튼 */} - - - - - YouTube에서 보기 - +
+ + + + + YouTube에서 보기 + +
); diff --git a/frontend/src/pages/pc/public/schedule-sections/YoutubeSection.jsx b/frontend/src/pages/pc/public/schedule-sections/YoutubeSection.jsx index 3803707..bc403cc 100644 --- a/frontend/src/pages/pc/public/schedule-sections/YoutubeSection.jsx +++ b/frontend/src/pages/pc/public/schedule-sections/YoutubeSection.jsx @@ -9,7 +9,7 @@ function VideoInfo({ schedule, isShorts }) { const isFullGroup = members.length === 5; return ( -
+
{/* 제목 */}

{decodeHtmlEntities(schedule.title)} @@ -56,7 +56,7 @@ function VideoInfo({ schedule, isShorts }) { )} {/* 유튜브에서 보기 버튼 */} -