ai_invest/설계/01/1차 시스템아키텍처.md

429 lines
21 KiB
Markdown

# I'm AI 투자매니저 시스템 아키텍처 설계서
## 1. 개요
### 1.1 문서 목적
I'm AI 투자매니저 시스템의 전체 아키텍처를 정의하여 개발 가이드라인 및 기술적 의사결정 근거 제공
### 1.2 시스템 개요
- **서비스명**: I'm AI 투자매니저
- **아키텍처 패턴**: 하이브리드 클라우드 아키텍처 (로컬 + AWS)
- **배포 전략**: 서버리스 + 로컬 데이터 처리
- **확장성**: 마이크로서비스 기반 확장 가능
## 2. 전체 시스템 아키텍처
### 2.1 시스템 구성도
```
┌─────────────────────────────────────────────────────────────────┐
│ 사용자 (웹브라우저) │
└─────────────────────┬───────────────────────────────────────────┘
│ HTTPS
┌─────────────────────▼───────────────────────────────────────────┐
│ AWS CloudFront (CDN) │
└─────────────────────┬───────────────────────────────────────────┘
┌─────────────────────▼───────────────────────────────────────────┐
│ AWS Lambda (React SSR) │
│ + S3 정적 에셋 (js, css, images) │
└─────────────────────┬───────────────────────────────────────────┘
│ API Calls
┌─────────────────────▼───────────────────────────────────────────┐
│ AWS API Gateway │
└─────────────────────┬───────────────────────────────────────────┘
┌─────────────────────▼───────────────────────────────────────────┐
│ AWS Lambda Functions │
│ ┌─────────────────┬─────────────────┬─────────────────────────┐ │
│ │ Main API │ Product API │ WebSocket API │ │
│ │ Lambda │ Lambda │ Lambda │ │
│ └─────────────────┴─────────────────┴─────────────────────────┘ │
└─────────────────────┬───────────────────────────────────────────┘
│ Data Fetch
┌─────────────────────▼───────────────────────────────────────────┐
│ AWS S3 Bucket │
│ (AI 분석 결과 JSON 파일) │
└─────────────────────▲───────────────────────────────────────────┘
│ Data Upload
┌─────────────────────┴───────────────────────────────────────────┐
│ 로컬 데이터 처리 서버 │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Apache Airflow │ │
│ │ ┌───────────────┬───────────────┬──────────────────────────┐ │ │
│ │ │ 데이터 수집 │ AI 분석 │ S3 업로드 │ │ │
│ │ │ DAGs │ DAGs │ DAGs │ │ │
│ │ └───────────────┴───────────────┴──────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 로컬 데이터베이스 │ │
│ │ (PostgreSQL / MySQL / SQLite) │ │
│ └─────────────────────────────────────────────────────────────┘ │
└─────────────────────┬───┬───────────────────────────────────────┘
│ │
┌───────────▼───▼──────────────┐
│ 외부 API 서비스 │
│ ┌─────────────┬─────────────┐│
│ │ 업비트 API │ 야후파이낸스 ││
│ │ (코인 데이터)│ (주식 데이터) ││
│ └─────────────┴─────────────┘│
│ ┌─────────────┬─────────────┐│
│ │ 뉴스 API │ AI API ││
│ │ (뉴스 데이터)│(Gemini/GPT) ││
│ └─────────────┴─────────────┘│
└─────────────────────────────────┘
```
## 3. 계층별 아키텍처 설계
### 3.1 프레젠테이션 계층 (Frontend)
#### 3.1.1 기술 스택
- **Framework**: React 18 + TypeScript
- **Rendering**: Server-Side Rendering (SSR) via Lambda
- **Static Assets**: S3 호스팅 (JS, CSS, Images)
- **State Management**: Zustand (가벼운 상태관리)
- **Styling**: Tailwind CSS + shadcn/ui
- **Chart Library**: Chart.js + TradingView Widgets
- **Build Tool**: Vite + Lambda Adapter
- **WebSocket**: Socket.IO Client
#### 3.1.2 컴포넌트 구조
```
src/
├── components/
│ ├── common/ # 공통 컴포넌트
│ ├── dashboard/ # 대시보드 관련
│ ├── product/ # 투자상품 상세
│ ├── simulation/ # 수익률 시뮬레이션
│ └── charts/ # 차트 컴포넌트
├── hooks/ # 커스텀 훅
├── stores/ # Zustand 상태관리
├── services/ # API 서비스
├── utils/ # 유틸리티
└── types/ # TypeScript 타입
```
#### 3.1.3 주요 기능
- **실시간 가격 표시**: WebSocket 연결
- **반응형 디자인**: 모바일/데스크톱 대응
- **캐싱 전략**: React Query로 데이터 캐싱
- **성능 최적화**: Code Splitting, Lazy Loading
- **SSR 최적화**: Lambda에서 초기 HTML 렌더링
- **하이브리드 배포**: 동적 페이지(Lambda) + 정적 에셋(S3)
### 3.2 서버리스 계층 (AWS Lambda)
#### 3.2.1 Lambda 함수 구성
```
lambda-functions/
├── frontend-ssr/ # React SSR Lambda
│ ├── index.js # React SSR 핸들러
│ ├── package.json
│ └── dist/ # Vite 빌드 결과
├── main-api/ # 메인 페이지 API
│ ├── handler.py
│ └── requirements.txt
├── product-api/ # 투자상품 상세 API
│ ├── handler.py
│ └── requirements.txt
└── websocket-api/ # 실시간 데이터 API
├── handler.py
└── requirements.txt
```
#### 3.2.2 API 설계
- **GET /api/web/main**
- 메인페이지 데이터 (전체 투자상품 리스트)
- 응답: JSON (투자상품 기본정보 + AI분석 요약)
- **GET /api/web/invest/{product}**
- 투자상품 상세 데이터
- 응답: JSON (상세 AI분석 + 캔들데이터 + 뉴스)
- **WebSocket /ws/realtime**
- 실시간 가격 업데이트
- 메시지: JSON (상품ID + 현재가 + 등락률)
### 3.3 데이터 계층 (로컬 서버)
#### 3.3.1 Apache Airflow 구성
```
airflow/
├── dags/
│ ├── collect_crypto_data.py # 코인 데이터 수집
│ ├── collect_stock_data.py # 주식 데이터 수집
│ ├── collect_news_data.py # 뉴스 데이터 수집
│ ├── ai_analysis.py # AI 분석 수행
│ └── upload_to_s3.py # S3 업로드
├── plugins/
│ ├── api_connectors/ # 외부 API 연결
│ └── ai_processors/ # AI 분석 엔진
└── config/
└── airflow.cfg
```
#### 3.3.2 데이터 파이프라인
1. **데이터 수집 (1회/1분)**: 업비트/야후파이낸스 API 호출
2. **실시간 데이터 수집**: 업비트: 웹소켓/야후파이낸스: 1회/1분
3. **데이터 정규화**: 수집 데이터 표준화 및 검증
4. **AI 분석**: 수집된 데이터로 AI 분석 수행 - 정규 3시간에 한번, 트리거 발생시 즉시(목표가/손절가 도달 -> 새로운 기준 제시를 위함)
5. **결과 업로드**: 분석 결과를 JSON 형태로 S3 업로드
### 3.4 데이터베이스 설계
#### 3.4.1 데이터베이스 선택
- **DBMS**: PostgreSQL 15+
- **이유**: JSON 지원, 확장성, 안정성
#### 3.4.2 주요 테이블 구조
```sql
-- AI API 요청 정보
CREATE TABLE public.ai_requests (
request_id serial4 NOT NULL, -- 요청 KEY
invest_code varchar(10) NULL, -- 투자 상품 코드 (BTC, APPL ...)
model varchar(100) NULL, -- 사용한 AI 모델명 (gemini-2.5-flash-lite)
prompt_token_count int4 NULL, -- 입력 토큰수 (AI API 응답에서 추출)
candidates_token_count int4 NULL, -- 출력 토큰수 (AI API 응답에서 추출)
estimated_cost numeric(20, 6) NULL, -- 예상 비용 (환율반영하여 계산[원])
prompt_schema_version int4 NULL, -- AI 요청 프롬프트 버전 (성능 개선에 따른 버전 관리)
prompt_text text NULL, -- AI 요청에 쓰인 프롬프트 원본
response_json jsonb NULL, -- AI 응답 (JSON으로 응답 받게 설정)
requested_dt timestamp DEFAULT now() NULL, -- AI API 요청 일시
completed_dt timestamp NULL, -- AI API 응답 완료 일시
process_ms int NULL, -- AI API 처리시간 (ms단위)
error text NULL, -- 에러 메세지
CONSTRAINT ai_requests_pkey PRIMARY KEY (request_id)
);
-- AI API 요청 메타 정보
CREATE TABLE public.ai_invest_metrics (
request_id int4 NOT NULL, -- 요청 KEY (ai_requests의 키와 일치 - fk는 설정하지 않음)
for_cash_entry_price numeric(20, 8) NULL, -- 현금보유자용 - 진입가
for_cash_entry_price_reason text NULL, -- 현금보유자용 - 진입가를 설정한 이유
for_cash_entry_price_news_article_ids INTEGER[] NULL, -- 현금보유자용 - 진입가를 설정한 이유 근거 자료(뉴스 id 리스트)
for_holding_target_price numeric(20, 8) NULL, -- 투자상품보유자용 - 목표가
for_holding_target_price_reason text NULL, -- 투자상품보유자용 - 목표가를 설정한 이유
for_holding_target_price_news_article_ids INTEGER[] NULL, -- 투자상품보유자용 - 목표가를 설정한 이유 근거 자료(뉴스 id 리스트)
for_holding_stop_loss numeric(20, 8) NULL, -- 투자상품보유자용 - 손절가
for_holding_stop_loss_reason text NULL, -- 투자상품보유자용 - 손절가를 설정한 이유
for_holding_stop_loss_news_article_ids INTEGER[] NULL, -- 투자상품보유자용 - 손절가를 설정한 이유 근거 자료(뉴스 id 리스트)
invest_score INTEGER NULL, -- 투자상품 매력도 점수 (0~100점)
CONSTRAINT ai_invest_metrics_pkey PRIMARY KEY (request_id)
);
-- ai 분석 요청 플래그 (마지막 요청후 3시간 경과, 목표가/손절가 도달시)
CREATE TABLE public.ai_request_flag (
flag_seq serial4 NOT NULL, -- 플래그 번호
invest_code varchar(10) NULL, -- 투자 상품 코드 (BTC, APPL ...)
request_flag bool DEFAULT true NULL, -- AI 분석 요청 플래그 (True: AI 요청 수행해야함 / False: AI 요청 완료)
flag_reason text NULL, -- AI 플래그가 발생한 이유
created_dt timestamp DEFAULT now() NULL, -- 생성 일시
updated_dt timestamp DEFAULT now() NULL, -- 수정 일시
CONSTRAINT ai_request_flag_pkey PRIMARY KEY (flag_seq)
);
-- ai 프롬프트 버전 관리
CREATE TABLE public.ai_prompt_version (
version_seq serial4 NOT NULL, -- 버전 번호
prompt text NOT NULL, -- 프롬프트 원문
create_dt timestamp DEFAULT now() NULL, -- 생성 일시
update_dt timestamp DEFAULT now() NULL, -- 수정 일시
CONSTRAINT ai_prompt_version_pkey PRIMARY KEY (version_seq)
);
-- 투자상품 코드 관리
CREATE TABLE public.invest_product_code (
invest_code varchar(10) NOT NULL, -- 투자 상품 코드 (BTC, APPL ...)
code_desc text NOT NULL, -- 투자 상품 코드 설명
use_yn char(1) DEFAULT 'Y' NOT NULL, -- 사용 여부부
CONSTRAINT invest_product_code_pkey PRIMARY KEY (invest_code)
);
-- 뉴스 데이터
CREATE TABLE public.news_articles (
news_id bigserial NOT NULL,
invest_code varchar(200) NOT NULL, -- 투자 상품 코드 (BTC, APPL ...)
"source" varchar(200) NULL, -- 뉴스 출처
author varchar(200) NULL, -- 기사 작성자
published_dt timestamp NOT NULL, -- 발생 시각
url text NULL, -- 기사 URL
title text NULL, -- 기사 제목
summary text NULL, -- 기사 요약
CONSTRAINT news_articles_pkey PRIMARY KEY (news_id)
);
-- 투자 상품 캔들 데이터
CREATE TABLE public.invest_candles (
invest_code varchar(10) NOT NULL, -- 투자 상품 코드 (BTC, APPL ...)
"interval" varchar(10) NOT NULL, -- 시간 기준 (MO=월, WE=주, DA=일, HO=시간, MI=분)
target_dt timestamp NOT NULL, -- 타임스탬프
"open" numeric(20, 8) NOT NULL, -- 시가
high numeric(20, 8) NOT NULL, -- 고가
low numeric(20, 8) NOT NULL, -- 저가
"close" numeric(20, 8) NOT NULL, -- 종가
volume numeric(30, 10) NULL, -- 거래량
quote_volume numeric(30, 2) NULL, -- 거래대금
"source" varchar(10) NULL, -- 데이터 출처
received_dt timestamp DEFAULT now() NULL, -- 수신 시각
CONSTRAINT market_candles_pkey PRIMARY KEY (invest_code, "interval", target_dt)
);
CREATE INDEX idx_invest_candles_invest_code_interval_target_dt_desc ON public.market_candles USING btree (invest_code, "interval", target_dt DESC);
```
## 4. 클라우드 아키텍처 (AWS)
### 4.1 AWS 서비스 구성
- **Lambda**: React SSR + API 처리
- **S3**: 정적 에셋 호스팅 (JS/CSS/Images) + AI 분석 결과 저장
- **CloudFront**: CDN (Lambda Origin + S3 정적 에셋)
- **API Gateway**: Lambda 함수 라우팅
- **IAM**: 권한 관리
### 4.2 배포 아키텍처 구조
#### 4.2.1 CloudFront 배포 구조
```
CloudFront Distribution:
├── /* (Default) # Lambda SSR Origin (React HTML)
├── /assets/* # S3 Origin (JS, CSS, Images)
├── /api/* # API Gateway Origin
└── /ws/* # WebSocket API Origin
```
#### 4.2.2 S3 버킷 구조
```
ai-invest-bucket/
├── static-assets/ # Vite 빌드된 정적 에셋
│ ├── assets/
│ │ ├── app-[hash].js
│ │ ├── app-[hash].css
│ │ └── images/
│ └── favicon.ico
└── data/ # AI 분석 결과
├── main/
│ └── latest.json # 메인 페이지 데이터
└── products/
├── BTC.json # 코인별 상세 데이터
├── ETH.json
├── AAPL.json # 주식별 상세 데이터
└── ...
```
### 4.3 보안 설정
- **HTTPS Only**: CloudFront SSL/TLS 인증서
- **CORS 설정**: API Gateway CORS 정책
- **API 키 관리**: AWS Systems Manager Parameter Store
## 5. 데이터 플로우
### 5.1 실시간 데이터 플로우
```
외부 API → Airflow DAG → 로컬 DB → S3 업로드 → Lambda → Frontend
↓ ↑
WebSocket ──────────────────────────────────────────────┘
```
### 5.2 사용자 요청 플로우
#### 5.2.1 페이지 요청 플로우
```
사용자 → CloudFront → Lambda SSR → S3 Data → 응답 (HTML + 초기 데이터)
```
#### 5.2.2 정적 에셋 요청 플로우
```
사용자 → CloudFront → S3 (JS/CSS/Images) → 캐시된 응답
```
#### 5.2.3 API 요청 플로우
```
사용자 → CloudFront → API Gateway → Lambda → S3 Data → 응답 (JSON)
```
### 5.3 AI 분석 플로우
```
캔들데이터 + 뉴스데이터 → AI 프롬프트 생성 → AI API 호출 → 결과 파싱 → DB 저장 → S3 업로드
```
## 6. 성능 최적화 전략
### 6.1 Frontend 최적화
- **번들 최적화**: Code Splitting, Tree Shaking
- **SSR 최적화**: Lambda에서 초기 렌더링으로 FCP 개선
- **정적 에셋 분리**: S3 + CloudFront로 JS/CSS 빠른 로딩
- **이미지 최적화**: WebP 포맷, Lazy Loading
- **캐싱 전략**:
- HTML: Lambda에서 동적 생성 (캐싱 제외)
- 정적 에셋: S3 + CloudFront 장기 캐싱
- **WebSocket**: 실시간 데이터만 필요시 연결
### 6.2 Backend 최적화
- **Lambda Cold Start**:
- SSR Lambda: Provisioned Concurrency 설정 (사용자 체감 중요)
- API Lambda: 온디맨드 (비용 효율성)
- **데이터베이스**: 인덱싱, Connection Pooling
- **S3**: CloudFront 캐시, Gzip 압축
- **Lambda 패키징**: webpack/rollup으로 번들 크기 최소화
### 6.3 비용 최적화
- **Lambda**: 메모리 최적화, 실행시간 단축
- **S3**: Intelligent Tiering, 불필요한 파일 정리
- **AI API**: 배치 처리, 캐시 활용
## 7. 확장성 고려사항
### 7.1 수평적 확장
- **투자상품 추가**: symbols 테이블에 데이터 추가만으로 확장
- **Lambda 스케일링**: Auto Scaling 지원
- **데이터베이스**: Read Replica 추가 가능
### 7.2 수직적 확장
- **Airflow**: Worker 노드 추가
- **데이터베이스**: 인스턴스 사양 업그레이드
- **Lambda**: 메모리 증설
## 8. 모니터링 및 로깅
### 8.1 모니터링 구성
- **AWS CloudWatch**: Lambda 메트릭, 로그 수집
- **Airflow**: DAG 실행 상태 모니터링
- **Database**: 성능 메트릭 수집
### 8.2 알람 설정
- **API 응답시간** > 500ms 알람
- **Lambda 에러율** > 1% 알람
- **데이터 수집 실패** 알람
## 9. 개발 및 배포 전략
### 9.1 개발 환경
```
Local Development → Git Repository → GitHub Actions → AWS Deployment
```
### 9.2 CI/CD 파이프라인
- **Frontend SSR**:
- Vite Build → Lambda 패키징 → SSR Lambda 배포
- 정적 에셋 → S3 업로드 → CloudFront Invalidation
- **API Backend**: Lambda Package → AWS SAM Deploy
- **Database**: Migration Scripts 자동 실행
- **통합 배포**: CloudFront 배포 설정 업데이트
### 9.3 환경 분리
- **Development**: 로컬 환경
- **Staging**: AWS 환경 (소규모)
- **Production**: AWS 환경 (본격 서비스)
## 10. 기술 선택 근거
### 10.1 React vs Vue.js
- **선택**: React 18
- **근거**: 더 큰 생태계, TypeScript 지원 우수, 개발자 풀 확보 용이
### 10.2 Zustand vs Redux
- **선택**: Zustand
- **근거**: 더 간단한 API, 보일러플레이트 최소화, 번들 사이즈 작음
### 10.3 PostgreSQL vs MySQL
- **선택**: PostgreSQL
- **근거**: JSON 지원 우수, 확장성, 오픈소스 안정성