From 48f711c4a93d95ba3910b6731b1a9b11c1854629 Mon Sep 17 00:00:00 2001 From: YeoJeongHun1 Date: Wed, 27 Aug 2025 18:29:39 +0900 Subject: [PATCH] =?UTF-8?q?=EC=8B=9C=EC=8A=A4=ED=85=9C=EC=95=84=ED=82=A4?= =?UTF-8?q?=ED=85=8D=EC=B2=98=20=EC=99=84=EB=A3=8C.,?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 설계/01/1차 시스템아키텍처.md | 213 ++++++++++++++++++++++++---------- 1 file changed, 150 insertions(+), 63 deletions(-) diff --git a/설계/01/1차 시스템아키텍처.md b/설계/01/1차 시스템아키텍처.md index 2aec031..91d2f38 100644 --- a/설계/01/1차 시스템아키텍처.md +++ b/설계/01/1차 시스템아키텍처.md @@ -24,8 +24,8 @@ I'm AI 투자매니저 시스템의 전체 아키텍처를 정의하여 개발 └─────────────────────┬───────────────────────────────────────────┘ │ ┌─────────────────────▼───────────────────────────────────────────┐ -│ React Frontend App │ -│ (S3 Static Hosting) │ +│ AWS Lambda (React SSR) │ +│ + S3 정적 에셋 (js, css, images) │ └─────────────────────┬───────────────────────────────────────────┘ │ API Calls ┌─────────────────────▼───────────────────────────────────────────┐ @@ -79,10 +79,12 @@ I'm AI 투자매니저 시스템의 전체 아키텍처를 정의하여 개발 #### 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 +- **Build Tool**: Vite + Lambda Adapter - **WebSocket**: Socket.IO Client #### 3.1.2 컴포넌트 구조 @@ -106,12 +108,18 @@ src/ - **반응형 디자인**: 모바일/데스크톱 대응 - **캐싱 전략**: React Query로 데이터 캐싱 - **성능 최적화**: Code Splitting, Lazy Loading +- **SSR 최적화**: Lambda에서 초기 HTML 렌더링 +- **하이브리드 배포**: 동적 페이지(Lambda) + 정적 에셋(S3) -### 3.2 API 계층 (AWS Lambda) +### 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 @@ -155,10 +163,11 @@ airflow/ ``` #### 3.3.2 데이터 파이프라인 -1. **데이터 수집 (매 5분)**: 업비트/야후파이낸스 API 호출 -2. **데이터 정규화**: 수집 데이터 표준화 및 검증 -3. **AI 분석 (매 24시간)**: 수집된 데이터로 AI 분석 수행 -4. **결과 업로드**: 분석 결과를 JSON 형태로 S3 업로드 +1. **데이터 수집 (1회/1분)**: 업비트/야후파이낸스 API 호출 +2. **실시간 데이터 수집**: 업비트: 웹소켓/야후파이낸스: 1회/1분 +3. **데이터 정규화**: 수집 데이터 표준화 및 검증 +4. **AI 분석**: 수집된 데이터로 AI 분석 수행 - 정규 3시간에 한번, 트리거 발생시 즉시(목표가/손절가 도달 -> 새로운 기준 제시를 위함) +5. **결과 업로드**: 분석 결과를 JSON 형태로 S3 업로드 ### 3.4 데이터베이스 설계 @@ -168,72 +177,128 @@ airflow/ #### 3.4.2 주요 테이블 구조 ```sql --- 투자상품 기본정보 -CREATE TABLE symbols ( - id SERIAL PRIMARY KEY, - symbol VARCHAR(20) UNIQUE NOT NULL, - name VARCHAR(100) NOT NULL, - type VARCHAR(10) NOT NULL, -- 'CRYPTO' or 'STOCK' - market VARCHAR(20) NOT NULL, - is_active BOOLEAN DEFAULT true, - created_at TIMESTAMP DEFAULT NOW() +-- 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 분석결과 -CREATE TABLE ai_analysis ( - id SERIAL PRIMARY KEY, - symbol_id INTEGER REFERENCES symbols(id), - target_price DECIMAL(20,8), - stop_loss_price DECIMAL(20,8), - entry_price DECIMAL(20,8), - attractiveness_score INTEGER, -- 1-100점 - analysis_content TEXT, - related_news JSON, - analysis_date TIMESTAMP DEFAULT NOW() +-- 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) ); --- 캔들 데이터 -CREATE TABLE invest_candle_data ( - id SERIAL PRIMARY KEY, - symbol_id INTEGER REFERENCES symbols(id), - open_price DECIMAL(20,8), - high_price DECIMAL(20,8), - low_price DECIMAL(20,8), - close_price DECIMAL(20,8), - volume DECIMAL(20,8), - candle_time TIMESTAMP, - created_at TIMESTAMP DEFAULT NOW() +-- 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) ); --- 뉴스 정보 -CREATE TABLE news_info ( - id SERIAL PRIMARY KEY, - symbol_id INTEGER REFERENCES symbols(id), - title VARCHAR(500), - content TEXT, - source VARCHAR(100), - published_at TIMESTAMP, - url VARCHAR(1000), - created_at TIMESTAMP DEFAULT NOW() +-- 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 서비스 구성 -- **S3**: 정적 웹사이트 호스팅 + AI 분석 결과 저장 -- **CloudFront**: CDN (전세계 캐시) -- **API Gateway**: API 엔드포인트 관리 -- **Lambda**: 서버리스 API 처리 +- **Lambda**: React SSR + API 처리 +- **S3**: 정적 에셋 호스팅 (JS/CSS/Images) + AI 분석 결과 저장 +- **CloudFront**: CDN (Lambda Origin + S3 정적 에셋) +- **API Gateway**: Lambda 함수 라우팅 - **IAM**: 권한 관리 -### 4.2 S3 버킷 구조 +### 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/ -├── web-assets/ # React 빌드 파일 -│ ├── index.html -│ ├── static/ -│ └── assets/ +├── static-assets/ # Vite 빌드된 정적 에셋 +│ ├── assets/ +│ │ ├── app-[hash].js +│ │ ├── app-[hash].css +│ │ └── images/ +│ └── favicon.ico └── data/ # AI 분석 결과 ├── main/ │ └── latest.json # 메인 페이지 데이터 @@ -259,8 +324,20 @@ WebSocket ─────────────────────── ``` ### 5.2 사용자 요청 플로우 + +#### 5.2.1 페이지 요청 플로우 ``` -사용자 → CloudFront → S3 (React App) → API Gateway → Lambda → S3 Data → 응답 +사용자 → 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 분석 플로우 @@ -272,14 +349,21 @@ WebSocket ─────────────────────── ### 6.1 Frontend 최적화 - **번들 최적화**: Code Splitting, Tree Shaking +- **SSR 최적화**: Lambda에서 초기 렌더링으로 FCP 개선 +- **정적 에셋 분리**: S3 + CloudFront로 JS/CSS 빠른 로딩 - **이미지 최적화**: WebP 포맷, Lazy Loading -- **캐싱**: Service Worker, Browser Cache +- **캐싱 전략**: + - HTML: Lambda에서 동적 생성 (캐싱 제외) + - 정적 에셋: S3 + CloudFront 장기 캐싱 - **WebSocket**: 실시간 데이터만 필요시 연결 ### 6.2 Backend 최적화 -- **Lambda Cold Start**: Provisioned Concurrency 설정 +- **Lambda Cold Start**: + - SSR Lambda: Provisioned Concurrency 설정 (사용자 체감 중요) + - API Lambda: 온디맨드 (비용 효율성) - **데이터베이스**: 인덱싱, Connection Pooling - **S3**: CloudFront 캐시, Gzip 압축 +- **Lambda 패키징**: webpack/rollup으로 번들 크기 최소화 ### 6.3 비용 최적화 - **Lambda**: 메모리 최적화, 실행시간 단축 @@ -318,9 +402,12 @@ Local Development → Git Repository → GitHub Actions → AWS Deployment ``` ### 9.2 CI/CD 파이프라인 -- **Frontend**: Vite Build → S3 Upload → CloudFront Invalidation -- **Backend**: Lambda Package → AWS SAM Deploy +- **Frontend SSR**: + - Vite Build → Lambda 패키징 → SSR Lambda 배포 + - 정적 에셋 → S3 업로드 → CloudFront Invalidation +- **API Backend**: Lambda Package → AWS SAM Deploy - **Database**: Migration Scripts 자동 실행 +- **통합 배포**: CloudFront 배포 설정 업데이트 ### 9.3 환경 분리 - **Development**: 로컬 환경