Backend Implementation (FastAPI + MongoDB): - JWT authentication with access/refresh tokens - User registration and login endpoints - Password hashing with bcrypt (fixed 72-byte limit) - Protected endpoints with JWT middleware - Token refresh mechanism - Role-Based Access Control (RBAC) structure - Pydantic v2 models and async MongoDB with Motor - API endpoints: /api/auth/register, /api/auth/login, /api/auth/me, /api/auth/refresh Frontend Implementation (React + TypeScript + Material-UI): - Login and Register pages with validation - AuthContext for global authentication state - API client with Axios interceptors for token refresh - Protected routes with automatic redirect - User profile display in navigation - Logout functionality Technical Achievements: - Resolved bcrypt 72-byte limit (replaced passlib with native bcrypt) - Fixed Pydantic v2 compatibility (PyObjectId, ConfigDict) - Implemented automatic token refresh on 401 errors - Created comprehensive test suite for all auth endpoints Docker & Kubernetes: - Backend image: yakenator/site11-console-backend:latest - Frontend image: yakenator/site11-console-frontend:latest - Deployed to site11-pipeline namespace - Nginx reverse proxy configuration Documentation: - CONSOLE_ARCHITECTURE.md - Complete system architecture - PHASE1_COMPLETION.md - Detailed completion report - PROGRESS.md - Updated with Phase 1 status All authentication endpoints tested and verified working. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
547 lines
17 KiB
Markdown
547 lines
17 KiB
Markdown
# Console Architecture Design
|
|
|
|
## 1. 시스템 개요
|
|
|
|
Site11 Console은 마이크로서비스 기반 뉴스 생성 파이프라인의 중앙 관리 시스템입니다.
|
|
|
|
### 핵심 기능
|
|
1. **인증 및 권한 관리** (OAuth2.0 + JWT)
|
|
2. **서비스 관리** (Microservices CRUD)
|
|
3. **뉴스 시스템** (키워드 기반 뉴스 생성 관리)
|
|
4. **파이프라인 관리** (실시간 모니터링 및 제어)
|
|
5. **대시보드** (시스템 현황 및 모니터링)
|
|
6. **통계 및 분석** (사용자, 서비스, 뉴스 생성 통계)
|
|
|
|
---
|
|
|
|
## 2. 시스템 아키텍처
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ Console Frontend (React) │
|
|
│ ┌──────────┬──────────┬──────────┬──────────┬──────────┐ │
|
|
│ │ Auth │ Services │ News │ Pipeline │Dashboard │ │
|
|
│ │ Module │ Module │ Module │ Module │ Module │ │
|
|
│ └──────────┴──────────┴──────────┴──────────┴──────────┘ │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
│
|
|
│ REST API + WebSocket
|
|
▼
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ Console Backend (FastAPI) │
|
|
│ ┌──────────────────────────────────────────────────────┐ │
|
|
│ │ API Gateway Layer │ │
|
|
│ ├──────────┬──────────┬──────────┬──────────┬──────────┤ │
|
|
│ │ Auth │ Services │ News │ Pipeline │ Stats │ │
|
|
│ │ Service │ Manager │ Manager │ Manager │ Service │ │
|
|
│ └──────────┴──────────┴──────────┴──────────┴──────────┘ │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
│ │ │
|
|
▼ ▼ ▼
|
|
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
|
|
│ MongoDB │ │ Redis │ │ Pipeline │
|
|
│ (Metadata) │ │ (Queue/ │ │ Workers │
|
|
│ │ │ Cache) │ │ │
|
|
└──────────────┘ └──────────────┘ └──────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 3. 데이터 모델 설계
|
|
|
|
### 3.1 Users Collection
|
|
```json
|
|
{
|
|
"_id": "ObjectId",
|
|
"email": "user@example.com",
|
|
"username": "username",
|
|
"password_hash": "bcrypt_hash",
|
|
"full_name": "Full Name",
|
|
"role": "admin|editor|viewer",
|
|
"permissions": ["service:read", "news:write", "pipeline:manage"],
|
|
"oauth_providers": [
|
|
{
|
|
"provider": "google|github|azure",
|
|
"provider_user_id": "external_id",
|
|
"access_token": "encrypted_token",
|
|
"refresh_token": "encrypted_token"
|
|
}
|
|
],
|
|
"profile": {
|
|
"avatar_url": "https://...",
|
|
"department": "Engineering",
|
|
"timezone": "Asia/Seoul"
|
|
},
|
|
"status": "active|suspended|deleted",
|
|
"created_at": "2024-01-01T00:00:00Z",
|
|
"updated_at": "2024-01-01T00:00:00Z",
|
|
"last_login_at": "2024-01-01T00:00:00Z"
|
|
}
|
|
```
|
|
|
|
### 3.2 Services Collection
|
|
```json
|
|
{
|
|
"_id": "ObjectId",
|
|
"service_id": "rss-collector",
|
|
"name": "RSS Collector Service",
|
|
"type": "pipeline_worker",
|
|
"category": "data_collection",
|
|
"description": "Collects news from RSS feeds",
|
|
"status": "running|stopped|error|deploying",
|
|
"deployment": {
|
|
"namespace": "site11-pipeline",
|
|
"deployment_name": "pipeline-rss-collector",
|
|
"replicas": {
|
|
"desired": 2,
|
|
"current": 2,
|
|
"ready": 2
|
|
},
|
|
"image": "yakenator/site11-rss-collector:latest",
|
|
"resources": {
|
|
"requests": {"cpu": "100m", "memory": "256Mi"},
|
|
"limits": {"cpu": "500m", "memory": "512Mi"}
|
|
}
|
|
},
|
|
"config": {
|
|
"env_vars": {
|
|
"REDIS_URL": "redis://...",
|
|
"MONGODB_URL": "mongodb://...",
|
|
"LOG_LEVEL": "INFO"
|
|
},
|
|
"queue_name": "rss_collection",
|
|
"batch_size": 10,
|
|
"worker_count": 2
|
|
},
|
|
"health": {
|
|
"endpoint": "/health",
|
|
"status": "healthy|unhealthy|unknown",
|
|
"last_check": "2024-01-01T00:00:00Z",
|
|
"uptime_seconds": 3600
|
|
},
|
|
"metrics": {
|
|
"requests_total": 1000,
|
|
"requests_failed": 10,
|
|
"avg_response_time_ms": 150,
|
|
"cpu_usage_percent": 45.5,
|
|
"memory_usage_mb": 256
|
|
},
|
|
"created_by": "user_id",
|
|
"created_at": "2024-01-01T00:00:00Z",
|
|
"updated_at": "2024-01-01T00:00:00Z"
|
|
}
|
|
```
|
|
|
|
### 3.3 News Keywords Collection
|
|
```json
|
|
{
|
|
"_id": "ObjectId",
|
|
"keyword": "도널드 트럼프",
|
|
"keyword_type": "person|topic|company|location|custom",
|
|
"category": "politics|technology|business|sports|entertainment",
|
|
"languages": ["ko", "en", "ja", "zh_cn"],
|
|
"config": {
|
|
"enabled": true,
|
|
"priority": 1,
|
|
"collection_frequency": "hourly|daily|realtime",
|
|
"max_articles_per_day": 50,
|
|
"sources": [
|
|
{
|
|
"type": "rss",
|
|
"url": "https://...",
|
|
"enabled": true
|
|
},
|
|
{
|
|
"type": "google_search",
|
|
"query": "도널드 트럼프 news",
|
|
"enabled": true
|
|
}
|
|
]
|
|
},
|
|
"processing_rules": {
|
|
"translate": true,
|
|
"target_languages": ["en", "ja", "zh_cn"],
|
|
"generate_image": true,
|
|
"sentiment_analysis": true,
|
|
"entity_extraction": true
|
|
},
|
|
"statistics": {
|
|
"total_articles_collected": 5000,
|
|
"total_articles_published": 4800,
|
|
"last_collection_at": "2024-01-01T00:00:00Z",
|
|
"success_rate": 96.0
|
|
},
|
|
"status": "active|paused|archived",
|
|
"tags": ["politics", "usa", "election"],
|
|
"created_by": "user_id",
|
|
"created_at": "2024-01-01T00:00:00Z",
|
|
"updated_at": "2024-01-01T00:00:00Z"
|
|
}
|
|
```
|
|
|
|
### 3.4 Pipeline Jobs Collection
|
|
```json
|
|
{
|
|
"_id": "ObjectId",
|
|
"job_id": "job_20240101_001",
|
|
"job_type": "news_collection|translation|image_generation",
|
|
"keyword_id": "ObjectId",
|
|
"keyword": "도널드 트럼프",
|
|
"status": "pending|processing|completed|failed|cancelled",
|
|
"priority": 1,
|
|
"pipeline_stages": [
|
|
{
|
|
"stage": "rss_collection",
|
|
"status": "completed",
|
|
"worker_id": "rss-collector-pod-123",
|
|
"started_at": "2024-01-01T00:00:00Z",
|
|
"completed_at": "2024-01-01T00:00:10Z",
|
|
"duration_ms": 10000,
|
|
"result": {
|
|
"articles_found": 15,
|
|
"articles_processed": 15
|
|
}
|
|
},
|
|
{
|
|
"stage": "google_search",
|
|
"status": "completed",
|
|
"worker_id": "google-search-pod-456",
|
|
"started_at": "2024-01-01T00:00:10Z",
|
|
"completed_at": "2024-01-01T00:00:20Z",
|
|
"duration_ms": 10000,
|
|
"result": {
|
|
"articles_found": 20,
|
|
"articles_processed": 18
|
|
}
|
|
},
|
|
{
|
|
"stage": "translation",
|
|
"status": "processing",
|
|
"worker_id": "translator-pod-789",
|
|
"started_at": "2024-01-01T00:00:20Z",
|
|
"progress": {
|
|
"total": 33,
|
|
"completed": 20,
|
|
"percent": 60.6
|
|
}
|
|
},
|
|
{
|
|
"stage": "ai_article_generation",
|
|
"status": "pending",
|
|
"worker_id": null
|
|
},
|
|
{
|
|
"stage": "image_generation",
|
|
"status": "pending",
|
|
"worker_id": null
|
|
}
|
|
],
|
|
"metadata": {
|
|
"source": "scheduled|manual|api",
|
|
"triggered_by": "user_id",
|
|
"retry_count": 0,
|
|
"max_retries": 3
|
|
},
|
|
"errors": [],
|
|
"created_at": "2024-01-01T00:00:00Z",
|
|
"updated_at": "2024-01-01T00:00:20Z",
|
|
"completed_at": null
|
|
}
|
|
```
|
|
|
|
### 3.5 System Statistics Collection
|
|
```json
|
|
{
|
|
"_id": "ObjectId",
|
|
"date": "2024-01-01",
|
|
"hour": 14,
|
|
"metrics": {
|
|
"users": {
|
|
"total_active": 150,
|
|
"new_registrations": 5,
|
|
"active_sessions": 45
|
|
},
|
|
"services": {
|
|
"total": 7,
|
|
"running": 7,
|
|
"stopped": 0,
|
|
"error": 0,
|
|
"avg_cpu_usage": 45.5,
|
|
"avg_memory_usage": 512.0,
|
|
"total_requests": 10000,
|
|
"failed_requests": 50
|
|
},
|
|
"news": {
|
|
"keywords_active": 100,
|
|
"articles_collected": 500,
|
|
"articles_translated": 450,
|
|
"articles_published": 480,
|
|
"images_generated": 480,
|
|
"avg_processing_time_ms": 15000,
|
|
"success_rate": 96.0
|
|
},
|
|
"pipeline": {
|
|
"jobs_total": 150,
|
|
"jobs_completed": 140,
|
|
"jobs_failed": 5,
|
|
"jobs_running": 5,
|
|
"avg_job_duration_ms": 60000,
|
|
"queue_depth": {
|
|
"rss_collection": 10,
|
|
"google_search": 5,
|
|
"translation": 8,
|
|
"ai_generation": 12,
|
|
"image_generation": 15
|
|
}
|
|
}
|
|
},
|
|
"created_at": "2024-01-01T14:00:00Z"
|
|
}
|
|
```
|
|
|
|
### 3.6 Activity Logs Collection
|
|
```json
|
|
{
|
|
"_id": "ObjectId",
|
|
"user_id": "ObjectId",
|
|
"action": "service.start|news.create|pipeline.cancel|user.login",
|
|
"resource_type": "service|news_keyword|pipeline_job|user",
|
|
"resource_id": "ObjectId",
|
|
"details": {
|
|
"service_name": "rss-collector",
|
|
"previous_status": "stopped",
|
|
"new_status": "running"
|
|
},
|
|
"ip_address": "192.168.1.1",
|
|
"user_agent": "Mozilla/5.0...",
|
|
"status": "success|failure",
|
|
"error_message": null,
|
|
"created_at": "2024-01-01T00:00:00Z"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 4. API 설계
|
|
|
|
### 4.1 Authentication APIs
|
|
```
|
|
POST /api/v1/auth/register # 사용자 등록
|
|
POST /api/v1/auth/login # 로그인 (JWT 발급)
|
|
POST /api/v1/auth/refresh # Token 갱신
|
|
POST /api/v1/auth/logout # 로그아웃
|
|
GET /api/v1/auth/me # 현재 사용자 정보
|
|
POST /api/v1/auth/oauth/{provider} # OAuth 로그인 (Google, GitHub)
|
|
```
|
|
|
|
### 4.2 Service Management APIs
|
|
```
|
|
GET /api/v1/services # 서비스 목록
|
|
GET /api/v1/services/{id} # 서비스 상세
|
|
POST /api/v1/services # 서비스 등록
|
|
PUT /api/v1/services/{id} # 서비스 수정
|
|
DELETE /api/v1/services/{id} # 서비스 삭제
|
|
POST /api/v1/services/{id}/start # 서비스 시작
|
|
POST /api/v1/services/{id}/stop # 서비스 중지
|
|
POST /api/v1/services/{id}/restart # 서비스 재시작
|
|
GET /api/v1/services/{id}/logs # 서비스 로그
|
|
GET /api/v1/services/{id}/metrics # 서비스 메트릭
|
|
```
|
|
|
|
### 4.3 News Keyword APIs
|
|
```
|
|
GET /api/v1/keywords # 키워드 목록
|
|
GET /api/v1/keywords/{id} # 키워드 상세
|
|
POST /api/v1/keywords # 키워드 생성
|
|
PUT /api/v1/keywords/{id} # 키워드 수정
|
|
DELETE /api/v1/keywords/{id} # 키워드 삭제
|
|
POST /api/v1/keywords/{id}/enable # 키워드 활성화
|
|
POST /api/v1/keywords/{id}/disable # 키워드 비활성화
|
|
GET /api/v1/keywords/{id}/stats # 키워드 통계
|
|
```
|
|
|
|
### 4.4 Pipeline Management APIs
|
|
```
|
|
GET /api/v1/pipelines # 파이프라인 작업 목록
|
|
GET /api/v1/pipelines/{id} # 파이프라인 작업 상세
|
|
POST /api/v1/pipelines # 파이프라인 작업 생성 (수동 트리거)
|
|
POST /api/v1/pipelines/{id}/cancel # 파이프라인 작업 취소
|
|
POST /api/v1/pipelines/{id}/retry # 파이프라인 작업 재시도
|
|
GET /api/v1/pipelines/queue # 큐 상태 조회
|
|
GET /api/v1/pipelines/realtime # 실시간 상태 (WebSocket)
|
|
```
|
|
|
|
### 4.5 Dashboard APIs
|
|
```
|
|
GET /api/v1/dashboard/overview # 대시보드 개요
|
|
GET /api/v1/dashboard/services # 서비스 현황
|
|
GET /api/v1/dashboard/news # 뉴스 생성 현황
|
|
GET /api/v1/dashboard/pipeline # 파이프라인 현황
|
|
GET /api/v1/dashboard/alerts # 알림 및 경고
|
|
```
|
|
|
|
### 4.6 Statistics APIs
|
|
```
|
|
GET /api/v1/stats/users # 사용자 통계
|
|
GET /api/v1/stats/services # 서비스 통계
|
|
GET /api/v1/stats/news # 뉴스 통계
|
|
GET /api/v1/stats/pipeline # 파이프라인 통계
|
|
GET /api/v1/stats/trends # 트렌드 분석
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Frontend 페이지 구조
|
|
|
|
```
|
|
/
|
|
├── /login # 로그인 페이지
|
|
├── /register # 회원가입 페이지
|
|
├── /dashboard # 대시보드 (홈)
|
|
│ ├── Overview # 전체 현황
|
|
│ ├── Services Status # 서비스 상태
|
|
│ ├── News Generation # 뉴스 생성 현황
|
|
│ └── Pipeline Status # 파이프라인 현황
|
|
│
|
|
├── /services # 서비스 관리
|
|
│ ├── List # 서비스 목록
|
|
│ ├── Detail/{id} # 서비스 상세
|
|
│ ├── Create # 서비스 등록
|
|
│ ├── Edit/{id} # 서비스 수정
|
|
│ └── Logs/{id} # 서비스 로그
|
|
│
|
|
├── /keywords # 뉴스 키워드 관리
|
|
│ ├── List # 키워드 목록
|
|
│ ├── Detail/{id} # 키워드 상세
|
|
│ ├── Create # 키워드 생성
|
|
│ ├── Edit/{id} # 키워드 수정
|
|
│ └── Statistics/{id} # 키워드 통계
|
|
│
|
|
├── /pipeline # 파이프라인 관리
|
|
│ ├── Jobs # 작업 목록
|
|
│ ├── JobDetail/{id} # 작업 상세
|
|
│ ├── Monitor # 실시간 모니터링
|
|
│ └── Queue # 큐 상태
|
|
│
|
|
├── /statistics # 통계 및 분석
|
|
│ ├── Overview # 통계 개요
|
|
│ ├── Users # 사용자 통계
|
|
│ ├── Services # 서비스 통계
|
|
│ ├── News # 뉴스 통계
|
|
│ └── Trends # 트렌드 분석
|
|
│
|
|
└── /settings # 설정
|
|
├── Profile # 프로필
|
|
├── Security # 보안 설정
|
|
└── System # 시스템 설정
|
|
```
|
|
|
|
---
|
|
|
|
## 6. 기술 스택
|
|
|
|
### Backend
|
|
- **Framework**: FastAPI
|
|
- **Authentication**: OAuth2.0 + JWT (python-jose, passlib)
|
|
- **Database**: MongoDB (Motor - async driver)
|
|
- **Cache/Queue**: Redis
|
|
- **WebSocket**: FastAPI WebSocket
|
|
- **Kubernetes Client**: kubernetes-python
|
|
- **Validation**: Pydantic v2
|
|
|
|
### Frontend
|
|
- **Framework**: React 18 + TypeScript
|
|
- **State Management**: Redux Toolkit / Zustand
|
|
- **UI Library**: Material-UI v7 (MUI)
|
|
- **Routing**: React Router v6
|
|
- **API Client**: Axios / React Query
|
|
- **Real-time**: Socket.IO Client
|
|
- **Charts**: Recharts / Chart.js
|
|
- **Forms**: React Hook Form + Zod
|
|
|
|
---
|
|
|
|
## 7. 보안 고려사항
|
|
|
|
### 7.1 Authentication & Authorization
|
|
- JWT Token (Access + Refresh)
|
|
- OAuth2.0 (Google, GitHub, Azure AD)
|
|
- RBAC (Role-Based Access Control)
|
|
- Permission-based authorization
|
|
|
|
### 7.2 API Security
|
|
- Rate Limiting (per user/IP)
|
|
- CORS 설정
|
|
- Input Validation (Pydantic)
|
|
- SQL/NoSQL Injection 방어
|
|
- XSS/CSRF 방어
|
|
|
|
### 7.3 Data Security
|
|
- Password Hashing (bcrypt)
|
|
- Sensitive Data Encryption
|
|
- API Key Management (Secrets)
|
|
- Audit Logging
|
|
|
|
---
|
|
|
|
## 8. 구현 우선순위
|
|
|
|
### Phase 1: 기본 인프라 (Week 1-2)
|
|
1. ✅ Kubernetes 배포 완료
|
|
2. 🔄 Authentication System (OAuth2.0 + JWT)
|
|
3. 🔄 User Management (CRUD)
|
|
4. 🔄 Permission System (RBAC)
|
|
|
|
### Phase 2: 서비스 관리 (Week 3)
|
|
1. Service Management (CRUD)
|
|
2. Service Control (Start/Stop/Restart)
|
|
3. Service Monitoring (Health/Metrics)
|
|
4. Service Logs Viewer
|
|
|
|
### Phase 3: 뉴스 시스템 (Week 4)
|
|
1. Keyword Management (CRUD)
|
|
2. Keyword Configuration
|
|
3. Keyword Statistics
|
|
4. Article Management
|
|
|
|
### Phase 4: 파이프라인 관리 (Week 5)
|
|
1. Pipeline Job Tracking
|
|
2. Queue Management
|
|
3. Real-time Monitoring (WebSocket)
|
|
4. Pipeline Control (Cancel/Retry)
|
|
|
|
### Phase 5: 대시보드 & 통계 (Week 6)
|
|
1. Dashboard Overview
|
|
2. Real-time Status
|
|
3. Statistics & Analytics
|
|
4. Trend Analysis
|
|
|
|
### Phase 6: 최적화 & 테스트 (Week 7-8)
|
|
1. Performance Optimization
|
|
2. Unit/Integration Tests
|
|
3. Load Testing
|
|
4. Documentation
|
|
|
|
---
|
|
|
|
## 9. 다음 단계
|
|
|
|
현재 작업: **Phase 1 - Authentication System 구현**
|
|
|
|
1. Backend: Auth 모듈 구현
|
|
- JWT 토큰 발급/검증
|
|
- OAuth2.0 Provider 연동
|
|
- User CRUD API
|
|
- Permission System
|
|
|
|
2. Frontend: Auth UI 구현
|
|
- Login/Register 페이지
|
|
- OAuth 로그인 버튼
|
|
- Protected Routes
|
|
- User Context/Store
|
|
|
|
3. Database: Collections 생성
|
|
- Users Collection
|
|
- Sessions Collection (Redis)
|
|
- Activity Logs Collection
|