From 29baa2dee99b41d57e8ba2afdc04ac06f477c934 Mon Sep 17 00:00:00 2001 From: cherry2250 Date: Thu, 23 Oct 2025 17:17:09 +0900 Subject: [PATCH 1/2] edit folder --- .../backup/logical-architecture-v2.md.backup | 910 ------------------ .../backup/logical-architecture-v2.mmd.backup | 80 -- .../backup/logical-architecture.md.backup | 626 ------------ .../backup/logical-architecture.mmd.backup | 48 - design/backend/sequence/inner/README-USER.md | 386 -------- .../sequence/inner/README-event-sequences.md | 263 ----- .../sequence/외부내부시퀀스일관성분석.md | 505 ---------- 7 files changed, 2818 deletions(-) delete mode 100644 design/backend/logical/backup/logical-architecture-v2.md.backup delete mode 100644 design/backend/logical/backup/logical-architecture-v2.mmd.backup delete mode 100644 design/backend/logical/backup/logical-architecture.md.backup delete mode 100644 design/backend/logical/backup/logical-architecture.mmd.backup delete mode 100644 design/backend/sequence/inner/README-USER.md delete mode 100644 design/backend/sequence/inner/README-event-sequences.md delete mode 100644 design/backend/sequence/외부내부시퀀스일관성분석.md diff --git a/design/backend/logical/backup/logical-architecture-v2.md.backup b/design/backend/logical/backup/logical-architecture-v2.md.backup deleted file mode 100644 index 38e576f..0000000 --- a/design/backend/logical/backup/logical-architecture-v2.md.backup +++ /dev/null @@ -1,910 +0,0 @@ -# KT AI 기반 소상공인 이벤트 자동 생성 서비스 - 논리 아키텍처 - -## 문서 정보 -- **작성일**: 2025-10-21 -- **최종 수정일**: 2025-10-22 -- **버전**: 2.0 (CQRS + Event-Driven 전환) -- **작성자**: System Architect -- **관련 문서**: - - [유저스토리](../../userstory.md) - - [아키텍처 패턴](../../pattern/architecture-pattern.md) - - [UI/UX 설계서](../../uiux/uiux.md) - -## 버전 이력 -- **v1.0** (2025-10-21): 초기 마이크로서비스 아키텍처 설계 -- **v2.0** (2025-10-22): CQRS 패턴 및 Event-Driven 아키텍처 전환, Resilience 패턴 전면 적용 - ---- - -## 목차 -1. [개요](#1-개요) -2. [서비스 아키텍처](#2-서비스-아키텍처) -3. [주요 사용자 플로우](#3-주요-사용자-플로우) -4. [데이터 흐름 및 캐싱 전략](#4-데이터-흐름-및-캐싱-전략) -5. [확장성 및 성능 고려사항](#5-확장성-및-성능-고려사항) -6. [보안 고려사항](#6-보안-고려사항) -7. [논리 아키텍처 다이어그램](#7-논리-아키텍처-다이어그램) - ---- - -## 1. 개요 - -### 1.1 설계 원칙 - -본 논리 아키텍처는 다음 원칙을 기반으로 설계되었습니다: - -#### 유저스토리 기반 설계 -- 20개 유저스토리와 정확히 매칭 -- 불필요한 추가 기능 배제 -- 비즈니스 요구사항 우선 반영 - -#### CQRS (Command Query Responsibility Segregation) -- **읽기/쓰기 분리**: Command Service와 Query Service로 책임 분리 -- **독립적 확장**: 읽기와 쓰기 부하에 따라 독립적으로 확장 -- **성능 최적화**: Query Service는 읽기 최적화 데이터 모델 사용 -- **이벤트 소싱 준비**: 도메인 이벤트 기반 상태 동기화 - -#### Event-Driven 아키텍처 -- **비동기 메시징**: Event Bus(Kafka/SQS)를 통한 서비스 간 통신 -- **느슨한 결합**: 서비스 간 직접 의존성 제거 -- **확장성**: 이벤트 구독자 추가로 기능 확장 용이 -- **장애 격리**: 이벤트 발행/구독 실패 시 서비스 독립성 유지 - -#### Resilience 패턴 적용 -- **Circuit Breaker**: 외부 API 장애 시 빠른 실패 및 복구 (Hystrix/Resilience4j) -- **Retry Pattern**: 일시적 장애 시 자동 재시도 (지수 백오프) -- **Timeout Pattern**: 응답 시간 제한으로 리소스 점유 방지 -- **Bulkhead Pattern**: 리소스 격리로 장애 전파 차단 -- **Fallback Pattern**: 장애 시 대체 로직 실행 (캐시 응답 등) - -### 1.2 핵심 컴포넌트 정의 - -#### Command Services (쓰기 전용) -1. **User Service**: 사용자 인증 및 매장정보 관리 - - 회원가입/로그인 (JWT 발급) - - 프로필 수정 - - 사업자번호 검증 (외부 API 연동) - -2. **Event Command Service**: 이벤트 생성/수정/삭제 - - 이벤트 생성 플로우 오케스트레이션 - - 도메인 이벤트 발행 (EventCreated, EventPublished) - - 이벤트 상태 변경 - -3. **Participation Command Service**: 참여 및 당첨자 관리 - - 참여 접수 및 검증 - - 당첨자 추첨 실행 - - 도메인 이벤트 발행 (ParticipantRegistered, WinnerSelected) - -#### Query Services (읽기 전용) -1. **Event Query Service**: 이벤트 조회 최적화 - - 이벤트 목록/상세 조회 - - 이벤트 검색 및 필터링 - - 읽기 최적화 데이터 모델 (비정규화) - -2. **Participation Query Service**: 참여자/당첨자 조회 - - 참여자 목록 조회 - - 당첨자 조회 - - 읽기 최적화 집계 데이터 - -3. **Analytics Query Service**: 실시간 성과 분석 - - 대시보드 데이터 조회 - - 채널별 성과 집계 - - ROI 계산 및 분석 - -#### Async Services (비동기 처리) -1. **AI Service**: AI 기반 이벤트 추천 - - Job Queue를 통한 비동기 처리 - - Circuit Breaker 적용 (외부 AI API) - - 결과 캐싱 (Redis) - -2. **Content Service**: SNS 이미지 생성 - - Job Queue를 통한 비동기 처리 - - Circuit Breaker 적용 (외부 이미지 API) - - CDN 업로드 및 캐싱 - -3. **Distribution Service**: 다중 채널 배포 - - Event Bus를 통한 EventPublished 구독 - - 병렬 배포 및 Circuit Breaker 적용 - - 배포 완료 이벤트 발행 (DistributionCompleted) - -#### Event Bus (Kafka/SQS) -- **도메인 이벤트 발행/구독**: 서비스 간 비동기 통신 -- **이벤트 종류**: - - EventCreated: 이벤트 생성 시 - - EventPublished: 이벤트 배포 승인 시 - - ParticipantRegistered: 참여자 등록 시 - - WinnerSelected: 당첨자 선정 시 - - DistributionCompleted: 배포 완료 시 -- **보장 수준**: At-Least-Once Delivery - -#### Job Queue (RabbitMQ) -- **장시간 비동기 작업**: AI 추천, 이미지 생성 -- **Priority Queue**: 작업 우선순위 관리 -- **Dead Letter Queue**: 실패 작업 처리 - -#### Data Layer -- **Redis Cache**: 세션, AI 결과, 이미지 URL, 대시보드 캐싱 -- **PostgreSQL**: 서비스별 독립 데이터베이스 - - User DB, Event Write DB, Event Read DB, Participation Write DB, Participation Read DB, Analytics DB -- **읽기 전용 복제본**: Query Service 성능 최적화 - -#### External Systems -- **국세청 API**: 사업자번호 검증 -- **AI APIs**: Claude/GPT-4 (트렌드 분석) -- **이미지 생성 APIs**: Stable Diffusion/DALL-E -- **배포 채널 APIs**: 우리동네TV, 링고비즈, 지니TV, SNS APIs - ---- - -## 2. 서비스 아키텍처 - -### 2.1 CQRS 패턴 적용 - -#### 설계 원칙 -- **Command와 Query 분리**: 쓰기와 읽기 책임을 독립된 서비스로 분리 -- **독립적 확장**: 읽기/쓰기 부하에 따라 독립적으로 스케일링 -- **최적화된 데이터 모델**: Query Service는 비정규화된 읽기 최적화 모델 사용 -- **이벤트 동기화**: Command Service가 발행한 도메인 이벤트로 Query Service 동기화 - -### 2.2 Command Services (쓰기 전용) - -#### User Service -**핵심 책임**: -- 회원가입/로그인 (JWT 토큰 발급) -- 프로필 수정 (매장 정보 포함) -- 사업자번호 검증 (국세청 API 연동) -- 세션 관리 - -**관련 유저스토리**: UFR-USER-010, 020, 030, 040 - -**Resilience 패턴**: -- **Circuit Breaker**: 국세청 API 호출 시 (실패율 5% 초과 시 Open) -- **Retry**: 최대 3회 재시도 (지수 백오프: 1초, 2초, 4초) -- **Timeout**: 5초 -- **Fallback**: 사업자번호 검증 스킵 (수동 확인 안내) - -**데이터 저장**: -- User DB: users, stores 테이블 -- Redis: 세션 정보 (TTL 7일), 사업자번호 검증 결과 (TTL 7일) - -#### Event Command Service -**핵심 책임**: -- 이벤트 생성/수정/삭제 -- 이벤트 생성 플로우 오케스트레이션 -- 도메인 이벤트 발행 (EventCreated, EventPublished) - -**관련 유저스토리**: UFR-EVENT-010, 020, 030, 040, 050, 060, 070 - -**도메인 이벤트**: -1. **EventCreated**: 이벤트 생성 완료 시 - - Payload: eventId, storeId, title, objective, createdAt - - 구독자: Event Query Service, Analytics Query Service - -2. **EventPublished**: 이벤트 배포 승인 시 - - Payload: eventId, distributionChannels, publishedAt - - 구독자: Distribution Service - -**주요 플로우**: -1. 이벤트 목적 선택 → Event DB 저장 -2. AI 추천 요청 → Job Queue 발행 -3. 이미지 생성 요청 → Job Queue 발행 -4. 배포 승인 → EventPublished 이벤트 발행 - -**데이터 저장**: -- Event Write DB: events, event_objectives, event_prizes 테이블 - -#### Participation Command Service -**핵심 책임**: -- 이벤트 참여 접수 및 검증 -- 당첨자 추첨 실행 -- 도메인 이벤트 발행 (ParticipantRegistered, WinnerSelected) - -**관련 유저스토리**: UFR-PART-010, 020, 030 - -**도메인 이벤트**: -1. **ParticipantRegistered**: 참여자 등록 시 - - Payload: participantId, eventId, phoneNumber, registeredAt - - 구독자: Participation Query Service, Analytics Query Service - -2. **WinnerSelected**: 당첨자 선정 시 - - Payload: winnerId, eventId, selectedAt - - 구독자: Participation Query Service - -**주요 기능**: -- 중복 참여 체크 (전화번호 기반) -- 난수 기반 무작위 추첨 -- 매장 방문 고객 가산점 적용 - -**데이터 저장**: -- Participation Write DB: participants, winners 테이블 - -### 2.3 Query Services (읽기 전용) - -#### Event Query Service -**핵심 책임**: -- 이벤트 목록/상세 조회 -- 이벤트 검색 및 필터링 -- 읽기 최적화 데이터 제공 - -**이벤트 구독**: -- **EventCreated**: 읽기 DB에 이벤트 데이터 동기화 - -**데이터 모델**: -- **비정규화**: 조인 없이 단일 쿼리로 조회 가능 -- **인덱스 최적화**: storeId, status, createdAt - -**데이터 저장**: -- Event Read DB: events_view (비정규화 테이블) - -#### Participation Query Service -**핵심 책임**: -- 참여자 목록 조회 -- 당첨자 조회 -- 집계 데이터 제공 - -**이벤트 구독**: -- **ParticipantRegistered**: 참여자 데이터 동기화 -- **WinnerSelected**: 당첨자 데이터 동기화 - -**데이터 모델**: -- **집계 테이블**: 이벤트별 참여자 수, 당첨자 수 사전 계산 - -**데이터 저장**: -- Participation Read DB: participants_view, winners_view, event_participant_stats - -#### Analytics Query Service -**핵심 책임**: -- 실시간 성과 대시보드 -- 채널별 성과 분석 -- ROI 계산 - -**관련 유저스토리**: UFR-ANAL-010 - -**이벤트 구독**: -- **EventCreated**: 이벤트 기본 정보 동기화 -- **ParticipantRegistered**: 참여자 수 실시간 업데이트 -- **DistributionCompleted**: 배포 통계 업데이트 - -**Resilience 패턴**: -- **Circuit Breaker**: 외부 채널 API 조회 시 -- **Fallback**: 캐시된 이전 데이터 반환 -- **Cache-Aside**: Redis 캐싱 (TTL 5분) - -**데이터 통합**: -- Event Query Service: 이벤트 정보 -- Participation Query Service: 참여자/당첨자 데이터 -- Distribution Service: 배포 통계 -- 외부 APIs: 우리동네TV, 지니TV, SNS 통계 - -**데이터 저장**: -- Analytics DB: event_stats, channel_stats -- Redis: 대시보드 데이터 (TTL 5분) - -### 2.4 Async Services (비동기 처리) - -#### AI Service -**핵심 책임**: -- 업종/지역/시즌 트렌드 분석 -- 3가지 이벤트 기획안 자동 생성 -- 예상 성과 계산 - -**관련 유저스토리**: UFR-AI-010 - -**Resilience 패턴**: -- **Circuit Breaker**: AI API 호출 시 (실패율 10% 초과 시 Open) -- **Timeout**: 30초 -- **Fallback**: 캐시된 이전 추천 결과 + 안내 메시지 -- **Cache-Aside**: Redis 캐싱 (TTL 24시간) - -**처리 시간**: -- 캐시 HIT: 0.1초 -- 캐시 MISS: 10초 이내 (비동기 Job 처리) - -**데이터 저장**: -- Redis: AI 추천 결과 (TTL 24시간) -- Redis: Job 상태 정보 (TTL 1시간) - -#### Content Service -**핵심 책임**: -- 3가지 스타일 SNS 이미지 자동 생성 -- 플랫폼별 이미지 최적화 -- 이미지 편집 기능 - -**관련 유저스토리**: UFR-CONT-010, 020 - -**Resilience 패턴**: -- **Circuit Breaker**: 이미지 생성 API 호출 시 -- **Timeout**: 20초 -- **Fallback**: 기본 템플릿 이미지 제공 -- **Cache-Aside**: Redis 캐싱 (TTL 7일) - -**처리 시간**: -- 캐시 HIT: 0.1초 -- 캐시 MISS: 5초 이내 (비동기 Job 처리) - -**데이터 저장**: -- Redis: 이미지 생성 결과 (CDN URL, TTL 7일) -- CDN: 생성된 이미지 파일 - -#### Distribution Service -**핵심 책임**: -- 다중 채널 동시 배포 -- 배포 상태 모니터링 -- 도메인 이벤트 발행 (DistributionCompleted) - -**관련 유저스토리**: UFR-DIST-010, 020 - -**이벤트 구독**: -- **EventPublished**: 배포 작업 시작 트리거 - -**도메인 이벤트**: -- **DistributionCompleted**: 배포 완료 시 - - Payload: eventId, distributedChannels, completedAt - - 구독자: Analytics Query Service - -**Resilience 패턴**: -- **Circuit Breaker**: 각 외부 채널 API별 독립 적용 -- **Retry**: 최대 3회 재시도 (지수 백오프) -- **Bulkhead**: 채널별 스레드 풀 격리 (장애 전파 방지) -- **Fallback**: 실패 채널 스킵 + 알림 - -**처리 시간**: 1분 이내 (모든 채널 배포 완료) - -**데이터 저장**: -- Event Read DB: distribution_logs 테이블 - -### 2.5 Event-Driven 통신 전략 - -#### Event Bus 아키텍처 -**기술 스택**: Kafka 또는 AWS SQS -**보장 수준**: At-Least-Once Delivery -**메시지 포맷**: JSON - -#### 도메인 이벤트 정의 - -| 이벤트명 | 발행자 | 구독자 | Payload | 용도 | -|---------|--------|--------|---------|------| -| **EventCreated** | Event Command | Event Query
Analytics Query | eventId, storeId, title, objective, createdAt | 이벤트 생성 동기화 | -| **EventPublished** | Event Command | Distribution Service | eventId, distributionChannels, publishedAt | 배포 작업 트리거 | -| **ParticipantRegistered** | Participation Command | Participation Query
Analytics Query | participantId, eventId, phoneNumber, registeredAt | 참여자 등록 동기화 | -| **WinnerSelected** | Participation Command | Participation Query | winnerId, eventId, selectedAt | 당첨자 선정 동기화 | -| **DistributionCompleted** | Distribution Service | Analytics Query | eventId, distributedChannels, completedAt | 배포 완료 통계 업데이트 | - -#### 통신 패턴별 설계 - -**1. Event-Driven 통신 (비동기 메시징)** -- **사용 시나리오**: 서비스 간 상태 동기화, 느슨한 결합 필요 시 -- **장점**: - - 서비스 독립성 보장 - - 장애 격리 - - 확장 용이 -- **단점**: - - 최종 일관성 (Eventual Consistency) - - 디버깅 복잡도 증가 - -**2. Job Queue 통신 (비동기 작업)** -- **사용 시나리오**: 장시간 작업 (AI 추천, 이미지 생성) -- **기술 스택**: RabbitMQ -- **패턴**: Asynchronous Request-Reply -- **처리 플로우**: - 1. Command Service → Job Queue: Job 발행 - 2. Async Service → Job Queue: Job 수신 및 처리 - 3. Client → Command Service: Job 상태 폴링 (5초 간격) - 4. Async Service → Redis: 결과 캐싱 - 5. Command Service → Client: 완료 응답 - -**3. Query Service 간 통신** -- **사용 시나리오**: Analytics Query가 다른 Query Service 데이터 필요 시 -- **패턴**: Cache-Aside -- **통신 방식**: REST API (HTTP/JSON) -- **특징**: 읽기 전용이므로 직접 호출 허용 - -#### Cache-Aside 전략 - -| 서비스 | 캐시 키 패턴 | TTL | 히트율 목표 | 효과 | -|--------|-------------|-----|-----------|------| -| AI Service | `ai:recommendation:{업종}:{지역}:{목적}` | 24시간 | 80% | 10초 → 0.1초 (99% 개선) | -| Content Service | `content:image:{이벤트ID}:{스타일}` | 7일 | 80% | 5초 → 0.1초 (98% 개선) | -| User Service | `user:business:{사업자번호}` | 7일 | 90% | - | -| Analytics Query | `analytics:dashboard:{이벤트ID}` | 5분 | 95% | 3초 → 0.5초 (83% 개선) | - -#### Resilience 패턴 적용 - -**1. Circuit Breaker 패턴** -- **적용 대상**: 모든 외부 API 호출 -- **라이브러리**: Resilience4j 또는 Hystrix -- **설정**: - ```yaml - circuit-breaker: - failure-rate-threshold: 50% # 실패율 50% 초과 시 Open - slow-call-rate-threshold: 50% # 느린 호출 50% 초과 시 Open - slow-call-duration-threshold: 5s # 5초 초과 시 느린 호출로 간주 - wait-duration-in-open-state: 30s # Open 상태 30초 유지 후 Half-Open - permitted-calls-in-half-open: 3 # Half-Open 상태에서 3개 요청 테스트 - ``` - -**2. Retry 패턴** -- **적용 대상**: 일시적 장애가 예상되는 외부 API -- **재시도 전략**: 지수 백오프 (Exponential Backoff) -- **설정**: - ```yaml - retry: - max-attempts: 3 # 최대 3회 재시도 - wait-duration: 1s # 초기 대기 시간 1초 - exponential-backoff-multiplier: 2 # 2배씩 증가 (1초, 2초, 4초) - retry-exceptions: - - java.net.SocketTimeoutException - - java.net.ConnectException - ``` - -**3. Timeout 패턴** -- **적용 대상**: 모든 외부 API 호출 -- **설정**: - | 서비스 | Timeout | 이유 | - |--------|---------|------| - | User Service (국세청 API) | 5초 | 빠른 검증 필요 | - | AI Service (AI API) | 30초 | 복잡한 분석 작업 | - | Content Service (이미지 API) | 20초 | 이미지 생성 시간 고려 | - | Distribution Service (채널 APIs) | 10초 | 빠른 배포 필요 | - -**4. Bulkhead 패턴** -- **적용 대상**: Distribution Service (다중 채널 배포) -- **목적**: 채널별 리소스 격리로 장애 전파 차단 -- **설정**: - ```yaml - bulkhead: - max-concurrent-calls: 10 # 채널당 최대 10개 동시 호출 - max-wait-duration: 0s # 대기 없이 즉시 실패 - ``` - -**5. Fallback 패턴** -- **적용 대상**: 모든 외부 API 호출 -- **전략**: - | 서비스 | Fallback 전략 | - |--------|---------------| - | User Service | 사업자번호 검증 스킵 (수동 확인 안내) | - | AI Service | 캐시된 이전 추천 결과 + 안내 메시지 | - | Content Service | 기본 템플릿 이미지 제공 | - | Distribution Service | 실패 채널 스킵 + 알림 | - | Analytics Query | 캐시된 이전 데이터 반환 | - -#### 이벤트 순서 보장 -- **Kafka Partition Key**: eventId 기준으로 파티션 할당 -- **동일 이벤트의 모든 이벤트**: 동일 파티션 → 순서 보장 -- **다른 이벤트**: 독립적 처리 → 병렬 처리 가능 - -#### 이벤트 재처리 (At-Least-Once) -- **멱등성 보장**: 구독자는 동일 이벤트 중복 처리 시 멱등성 유지 -- **방법**: 이벤트 ID 기반 중복 체크 (Redis Set 사용) - ---- - -## 3. 주요 사용자 플로우 - -### 3.1 이벤트 생성 플로우 (CQRS + Event-Driven) - -``` -1. [이벤트 목적 선택] - ┌─────────────────────────────────────────────────────────────┐ - │ Client → Event Command Service │ - │ - POST /api/events (목적, 매장 정보) │ - │ - Event Write DB에 저장 │ - │ - EventCreated 이벤트 발행 → Event Bus │ - └─────────────────────────────────────────────────────────────┘ - - ┌─────────────────────────────────────────────────────────────┐ - │ Event Bus → Event Query Service │ - │ - EventCreated 이벤트 구독 │ - │ - Event Read DB에 동기화 (비정규화) │ - └─────────────────────────────────────────────────────────────┘ - - ┌─────────────────────────────────────────────────────────────┐ - │ Event Bus → Analytics Query Service │ - │ - EventCreated 이벤트 구독 │ - │ - Analytics DB에 기본 통계 초기화 │ - └─────────────────────────────────────────────────────────────┘ - -2. [AI 이벤트 추천] - ┌─────────────────────────────────────────────────────────────┐ - │ Client → Event Command Service │ - │ - POST /api/events/{id}/ai-recommendations │ - │ - Job Queue 발행 (AI 작업 요청) │ - │ - Job ID 즉시 반환 (0.1초) │ - └─────────────────────────────────────────────────────────────┘ - - ┌─────────────────────────────────────────────────────────────┐ - │ AI Service (Background) │ - │ - Job Queue 구독 │ - │ - Redis 캐시 확인 (Cache-Aside) │ - │ - 캐시 MISS: Claude API 호출 (10초) [Circuit Breaker] │ - │ - 결과 캐싱 (TTL 24시간) │ - │ - Job 상태 완료로 업데이트 │ - └─────────────────────────────────────────────────────────────┘ - - ┌─────────────────────────────────────────────────────────────┐ - │ Client (Polling) │ - │ - GET /api/jobs/{id} (5초 간격) │ - │ - 완료 시: AI 추천 결과 반환 (3가지 옵션) │ - └─────────────────────────────────────────────────────────────┘ - -3. [SNS 이미지 생성] - ┌─────────────────────────────────────────────────────────────┐ - │ Client → Event Command Service │ - │ - POST /api/events/{id}/content-generation │ - │ - Job Queue 발행 (이미지 생성 요청) │ - │ - Job ID 즉시 반환 (0.1초) │ - └─────────────────────────────────────────────────────────────┘ - - ┌─────────────────────────────────────────────────────────────┐ - │ Content Service (Background) │ - │ - Job Queue 구독 │ - │ - Redis 캐시 확인 │ - │ - 캐시 MISS: Stable Diffusion API (5초) [Circuit Breaker] │ - │ - 이미지 CDN 업로드 │ - │ - CDN URL 캐싱 (TTL 7일) │ - │ - Job 상태 완료로 업데이트 │ - └─────────────────────────────────────────────────────────────┘ - - ┌─────────────────────────────────────────────────────────────┐ - │ Client (Polling) │ - │ - GET /api/jobs/{id} (3초 간격) │ - │ - 완료 시: 3가지 스타일 이미지 URL 반환 │ - └─────────────────────────────────────────────────────────────┘ - -4. [최종 승인 및 배포] - ┌─────────────────────────────────────────────────────────────┐ - │ Client → Event Command Service │ - │ - POST /api/events/{id}/publish │ - │ - Event 상태 변경 (DRAFT → PUBLISHED) │ - │ - EventPublished 이벤트 발행 → Event Bus │ - └─────────────────────────────────────────────────────────────┘ - - ┌─────────────────────────────────────────────────────────────┐ - │ Event Bus → Distribution Service │ - │ - EventPublished 이벤트 구독 │ - │ - 다중 채널 병렬 배포 시작 [Circuit Breaker + Bulkhead] │ - │ * 우리동네TV API (영상 업로드) [Retry: 3회] │ - │ * 링고비즈 API (연결음 업데이트) [Retry: 3회] │ - │ * 지니TV API (광고 등록) [Retry: 3회] │ - │ * SNS APIs (Instagram, Naver, Kakao) [Retry: 3회] │ - │ - 배포 완료: DistributionCompleted 이벤트 발행 │ - └─────────────────────────────────────────────────────────────┘ - - ┌─────────────────────────────────────────────────────────────┐ - │ Event Bus → Analytics Query Service │ - │ - DistributionCompleted 이벤트 구독 │ - │ - Analytics DB 배포 통계 업데이트 │ - │ - 대시보드 캐시 무효화 (다음 조회 시 갱신) │ - └─────────────────────────────────────────────────────────────┘ -``` - -### 3.2 고객 참여 플로우 (Event-Driven) - -``` -1. [이벤트 참여] - ┌─────────────────────────────────────────────────────────────┐ - │ Client → Participation Command Service │ - │ - POST /api/events/{id}/participate │ - │ - 중복 참여 체크 (전화번호 기반) │ - │ - Participation Write DB에 저장 │ - │ - ParticipantRegistered 이벤트 발행 → Event Bus │ - │ - 응모 번호 즉시 반환 │ - └─────────────────────────────────────────────────────────────┘ - - ┌─────────────────────────────────────────────────────────────┐ - │ Event Bus → Participation Query Service │ - │ - ParticipantRegistered 이벤트 구독 │ - │ - Participation Read DB에 동기화 │ - │ - 이벤트별 참여자 수 집계 테이블 업데이트 │ - └─────────────────────────────────────────────────────────────┘ - - ┌─────────────────────────────────────────────────────────────┐ - │ Event Bus → Analytics Query Service │ - │ - ParticipantRegistered 이벤트 구독 │ - │ - 실시간 참여자 수 증가 │ - │ - 대시보드 캐시 무효화 │ - └─────────────────────────────────────────────────────────────┘ - -2. [당첨자 추첨] - ┌─────────────────────────────────────────────────────────────┐ - │ Client → Participation Command Service │ - │ - POST /api/events/{id}/draw-winners │ - │ - 난수 기반 무작위 추첨 │ - │ - Winners Write DB에 저장 │ - │ - WinnerSelected 이벤트 발행 → Event Bus │ - └─────────────────────────────────────────────────────────────┘ - - ┌─────────────────────────────────────────────────────────────┐ - │ Event Bus → Participation Query Service │ - │ - WinnerSelected 이벤트 구독 │ - │ - Winners Read DB에 동기화 │ - └─────────────────────────────────────────────────────────────┘ -``` - -### 3.3 성과 분석 플로우 (Query Service + Event 구독) - -``` -1. [실시간 대시보드 조회] - ┌─────────────────────────────────────────────────────────────┐ - │ Client → Analytics Query Service │ - │ - GET /api/events/{id}/analytics │ - │ - Redis 캐시 확인 (TTL 5분) │ - │ * 캐시 HIT: 즉시 반환 (0.5초) │ - │ * 캐시 MISS: 아래 데이터 통합 │ - └─────────────────────────────────────────────────────────────┘ - - ┌─────────────────────────────────────────────────────────────┐ - │ Analytics Query Service (데이터 통합) │ - │ - Analytics DB: 이벤트 통계 조회 │ - │ - Event Query Service: 이벤트 정보 조회 (REST) │ - │ - Participation Query Service: 참여자/당첨자 조회 (REST) │ - │ - 외부 APIs: 채널별 노출/클릭 수 [Circuit Breaker + Fallback] │ - │ * 우리동네TV API (조회수) │ - │ * 지니TV API (광고 노출 수) │ - │ * SNS APIs (좋아요, 댓글, 공유 수) │ - │ - Redis 캐싱 (TTL 5분) │ - │ - 대시보드 데이터 반환 │ - └─────────────────────────────────────────────────────────────┘ - -2. [실시간 업데이트 (Event 구독)] - ┌─────────────────────────────────────────────────────────────┐ - │ Analytics Query Service (Background) │ - │ - EventCreated 구독: 이벤트 기본 정보 초기화 │ - │ - ParticipantRegistered 구독: 참여자 수 실시간 증가 │ - │ - DistributionCompleted 구독: 배포 채널 통계 업데이트 │ - │ - 캐시 무효화: 다음 조회 시 최신 데이터 갱신 │ - └─────────────────────────────────────────────────────────────┘ -``` - -### 3.4 플로우 특징 - -#### CQRS 이점 -- **Command Service**: 쓰기 작업에 집중, 트랜잭션 보장 -- **Query Service**: 읽기 최적화 데이터 모델, 빠른 조회 -- **독립적 확장**: 읽기/쓰기 부하에 따라 독립 스케일링 - -#### Event-Driven 이점 -- **느슨한 결합**: 서비스 간 직접 의존성 제거 -- **장애 격리**: 한 서비스 장애가 다른 서비스에 영향 없음 -- **확장 용이**: 새로운 구독자 추가로 기능 확장 -- **비동기 처리**: 사용자 응답 시간 단축 - -#### Resilience 이점 -- **Circuit Breaker**: 외부 API 장애 시 빠른 실패 및 복구 -- **Retry**: 일시적 장애 자동 복구 -- **Fallback**: 장애 시에도 서비스 지속 (Graceful Degradation) -- **Bulkhead**: 리소스 격리로 장애 전파 차단 - ---- - -## 4. 데이터 흐름 및 캐싱 전략 - -### 4.1 데이터 흐름 - -#### 읽기 플로우 (Cache-Aside 패턴) -``` -1. Application → Cache 확인 - - Cache HIT: 캐시된 데이터 즉시 반환 - - Cache MISS: - 2. Application → Database/External API 조회 - 3. Database/External API → Application 데이터 반환 - 4. Application → Cache 데이터 저장 (TTL 설정) - 5. Application → Client 데이터 반환 -``` - -#### 쓰기 플로우 (Write-Through 패턴) -``` -1. Application → Database 쓰기 -2. Database → Application 성공 응답 -3. Application → Cache 무효화 또는 업데이트 -4. Application → Client 성공 응답 -``` - -### 4.2 캐싱 전략 - -#### Redis 캐시 구조 - -| 서비스 | 캐시 키 패턴 | 데이터 타입 | TTL | 예상 크기 | 히트율 목표 | -|--------|-------------|-----------|-----|----------|-----------| -| User | `user:session:{token}` | String | 7일 | 1KB | - | -| User | `user:business:{사업자번호}` | String | 7일 | 0.5KB | 90% | -| AI | `ai:recommendation:{업종}:{지역}:{목적}` | Hash | 24시간 | 10KB | 80% | -| Content | `content:image:{이벤트ID}:{스타일}` | String | 7일 | 0.2KB (URL) | 80% | -| Analytics | `analytics:dashboard:{이벤트ID}` | Hash | 5분 | 5KB | 95% | -| AI | `job:{jobId}` | Hash | 1시간 | 1KB | - | -| Content | `job:{jobId}` | Hash | 1시간 | 1KB | - | - -#### Redis 메모리 산정 -- **예상 동시 사용자**: 100명 -- **예상 이벤트 수**: 50개 -- **예상 캐시 항목 수**: 10,000개 -- **예상 총 메모리**: 약 50MB (운영 환경 2GB 할당) - -#### 캐시 무효화 전략 -- **TTL 기반 자동 만료**: 대부분의 캐시 -- **수동 무효화**: 이벤트 수정/삭제 시 관련 캐시 삭제 -- **Lazy 무효화**: 데이터 변경 시 다음 조회 시점에 갱신 - -### 4.3 데이터베이스 전략 - -#### 서비스별 독립 데이터베이스 -- **User DB**: users, stores -- **Event DB**: events, event_objectives, event_prizes, distribution_logs -- **Participation DB**: participants, winners -- **Analytics DB**: event_stats, channel_stats - -#### 데이터 일관성 전략 -- **Eventual Consistency**: 서비스 간 데이터는 최종 일관성 보장 -- **Strong Consistency**: 서비스 내부 트랜잭션은 강한 일관성 보장 -- **Saga 패턴**: 이벤트 생성 플로우 (보상 트랜잭션) - ---- - -## 5. 확장성 및 성능 고려사항 - -### 5.1 수평 확장 전략 - -#### 서비스별 확장 전략 -| 서비스 | 초기 인스턴스 | 확장 조건 | 최대 인스턴스 | Auto-scaling 메트릭 | -|--------|-------------|----------|-------------|-------------------| -| User | 2 | CPU > 70% | 5 | CPU, 메모리 | -| Event | 2 | CPU > 70% | 10 | CPU, 메모리 | -| AI | 1 | Job Queue > 10 | 3 | Queue 길이 | -| Content | 1 | Job Queue > 10 | 3 | Queue 길이 | -| Distribution | 2 | CPU > 70% | 5 | CPU, 메모리 | -| Participation | 1 | CPU > 70% | 3 | CPU, 메모리 | -| Analytics | 1 | CPU > 70% | 3 | CPU, 메모리 | - -#### Redis Cluster -- **초기 구성**: 3 노드 (Master 3, Replica 3) -- **확장**: 노드 추가를 통한 수평 확장 -- **HA**: Redis Sentinel을 통한 자동 Failover - -#### Database Replication -- **Primary-Replica 구조**: 읽기 부하 분산 -- **읽기 확장**: Read Replica 추가 (필요 시) -- **쓰기 확장**: Sharding (Phase 2 이후) - -### 5.2 성능 목표 - -#### 응답 시간 목표 -| 기능 | 목표 시간 | 캐시 HIT | 캐시 MISS | -|------|----------|---------|----------| -| 로그인 | 0.5초 | - | - | -| 이벤트 목록 조회 | 0.3초 | - | - | -| AI 트렌드 분석 + 추천 | 0.1초 | ✅ | 10초 (비동기) | -| SNS 이미지 생성 | 0.1초 | ✅ | 5초 (비동기) | -| 다중 채널 배포 | 1분 | - | - | -| 대시보드 로딩 | 0.5초 | ✅ | 3초 | - -#### 처리량 목표 -- **동시 사용자**: 100명 (MVP 목표) -- **API 요청**: 1,000 req/min -- **AI 작업**: 10 jobs/min -- **이미지 생성**: 10 jobs/min - -### 5.3 성능 최적화 기법 - -#### Frontend 최적화 -- **Code Splitting**: 페이지별 번들 분할 -- **Lazy Loading**: 차트 라이브러리 지연 로딩 -- **CDN**: 정적 자산 CDN 배포 -- **Compression**: Gzip/Brotli 압축 - -#### Backend 최적화 -- **Connection Pooling**: 데이터베이스 연결 풀 관리 -- **Query Optimization**: 인덱스 최적화, N+1 쿼리 방지 -- **Batch Processing**: 대량 데이터 일괄 처리 -- **Pagination**: 목록 조회 페이지네이션 - -#### Cache 최적화 -- **Multi-Level Caching**: Browser Cache → CDN → Redis → Database -- **Cache Warming**: 자주 사용되는 데이터 사전 로딩 -- **Cache Preloading**: 피크 시간 전 캐시 준비 - ---- - -## 6. 보안 고려사항 - -### 6.1 인증 및 인가 - -#### JWT 기반 인증 -- **토큰 발급**: User Service에서 로그인 시 JWT 토큰 발급 -- **토큰 검증**: API Gateway에서 모든 요청의 JWT 토큰 검증 -- **토큰 저장**: Redis에 세션 정보 저장 (TTL 7일) -- **토큰 갱신**: Refresh Token 패턴 (선택) - -#### 역할 기반 접근 제어 (RBAC) -- **역할**: OWNER (매장 사장님), CUSTOMER (이벤트 참여자) -- **권한 관리**: API별 필요 역할 정의 -- **API Gateway 검증**: 요청자의 역할 확인 - -### 6.2 데이터 보안 - -#### 민감 정보 암호화 -- **비밀번호**: bcrypt 해싱 (Cost Factor: 10) -- **사업자번호**: AES-256 암호화 저장 -- **개인정보**: 전화번호 마스킹 (010-****-1234) - -#### 전송 보안 -- **HTTPS**: 모든 통신 TLS 1.3 암호화 -- **API Key**: 외부 API 호출 시 안전한 Key 관리 (AWS Secrets Manager) - -#### 데이터 접근 통제 -- **Database**: 서비스별 독립 계정, 최소 권한 원칙 -- **Redis**: 비밀번호 설정, ACL 적용 -- **백업**: 암호화된 백업 저장 - -### 6.3 보안 모니터링 - -#### 위협 탐지 -- **Rate Limiting**: API Gateway에서 사용자당 100 req/min -- **Brute Force 방지**: 로그인 5회 실패 시 계정 잠금 (삭제됨, 향후 추가 가능) -- **SQL Injection 방지**: Prepared Statement 사용 -- **XSS 방지**: 입력 데이터 Sanitization - -#### 로깅 및 감사 -- **Access Log**: 모든 API 요청 로깅 -- **Audit Log**: 민감 작업 (로그인, 이벤트 생성, 당첨자 추첨) 감사 로그 -- **중앙집중식 로깅**: ELK Stack 또는 CloudWatch Logs - ---- - -## 7. 논리 아키텍처 다이어그램 - -논리 아키텍처 다이어그램은 별도 Mermaid 파일로 작성되었습니다. - -**파일 위치**: `logical-architecture.mmd` - -**다이어그램 확인 방법**: -1. https://mermaid.live/edit 접속 -2. `logical-architecture.mmd` 파일 내용 붙여넣기 -3. 다이어그램 시각적 확인 - -**다이어그램 구성**: -- Client Layer: Web/Mobile Client -- Gateway Layer: API Gateway -- Service Layer: 7개 마이크로서비스 -- Data Layer: Redis Cache, Message Queue, Databases -- External APIs: 7개 외부 API - -**의존성 표현**: -- 실선 화살표 (→): 동기적 의존성 -- 점선 화살표 (-.->): 비동기 의존성 또는 캐시 접근 -- 화살표 레이블: 의존성 목적 명시 - ---- - -## 부록 - -### A. 참고 문서 -- [유저스토리](../../userstory.md) -- [아키텍처 패턴](../../pattern/architecture-pattern.md) -- [UI/UX 설계서](../../uiux/uiux.md) -- [클라우드 디자인 패턴](../../../claude/cloud-design-patterns.md) - -### B. 주요 결정사항 -1. **CQRS 패턴 채택**: 읽기/쓰기 책임 분리로 독립적 확장 및 성능 최적화 -2. **Event-Driven 아키텍처 채택**: Event Bus(Kafka/SQS)를 통한 서비스 간 느슨한 결합 -3. **도메인 이벤트 정의**: 5개 핵심 이벤트로 서비스 간 상태 동기화 -4. **Resilience 패턴 전면 적용**: Circuit Breaker, Retry, Timeout, Bulkhead, Fallback -5. **At-Least-Once Delivery**: 이벤트 보장 수준 및 멱등성 설계 -6. **Cache-Aside 패턴**: AI/이미지 생성 결과 캐싱으로 응답 시간 90% 개선 -7. **Job Queue 분리**: RabbitMQ로 장시간 비동기 작업 처리 -8. **서비스별 독립 Database**: Command/Query별 독립 DB로 CQRS 지원 - -### C. 향후 개선 방안 (Phase 2 이후) -1. **Event Sourcing 완전 적용**: 모든 상태 변경을 이벤트로 저장하여 시간 여행 및 감사 추적 강화 -2. **Saga 패턴 적용**: 복잡한 분산 트랜잭션 보상 로직 체계화 -3. **Service Mesh 도입**: Istio를 통한 서비스 간 통신 관찰성 및 보안 강화 -4. **Database Sharding**: Event/Participation Write DB 샤딩으로 쓰기 확장성 개선 -5. **WebSocket 기반 실시간 푸시**: 대시보드 실시간 업데이트 (폴링 대체) -6. **GraphQL API Gateway**: 클라이언트 맞춤형 데이터 조회 최적화 -7. **Dead Letter Queue 고도화**: 실패 이벤트 재처리 및 알림 자동화 - ---- - -**문서 버전**: 2.0 -**최종 수정일**: 2025-10-22 -**작성자**: System Architect -**변경 사항**: CQRS 패턴 및 Event-Driven 아키텍처 전환, Resilience 패턴 전면 적용 diff --git a/design/backend/logical/backup/logical-architecture-v2.mmd.backup b/design/backend/logical/backup/logical-architecture-v2.mmd.backup deleted file mode 100644 index 4f71ff3..0000000 --- a/design/backend/logical/backup/logical-architecture-v2.mmd.backup +++ /dev/null @@ -1,80 +0,0 @@ -graph TB - %% KT AI 기반 소상공인 이벤트 자동 생성 서비스 - 논리 아키텍처 (CQRS + Event-Driven) - - %% Command Services (Write) - subgraph "Command Services" - UserCmd["User Service
• 회원가입/로그인
• 프로필 관리
• 사업자번호 검증"] - EventCmd["Event Command
Service
• 이벤트 생성/수정/삭제
• 플로우 오케스트레이션"] - PartCmd["Participation
Command Service
• 참여 접수
• 당첨자 추첨"] - end - - %% Query Services (Read) - subgraph "Query Services" - EventQuery["Event Query
Service
• 이벤트 목록/상세
• 이벤트 검색"] - PartQuery["Participation
Query Service
• 참여자 목록
• 당첨자 조회"] - AnalQuery["Analytics Query
Service
• 실시간 대시보드
• 성과 분석"] - end - - %% Async Services - subgraph "Async Services" - AISvc["AI Service
• 트렌드 분석
• 이벤트 추천
[Circuit Breaker]"] - ContentSvc["Content Service
• SNS 이미지 생성
• 3가지 스타일
[Circuit Breaker]"] - DistSvc["Distribution
Service
• 다중 채널 배포
[Circuit Breaker]
[Retry Pattern]"] - end - - %% Event Bus - EventBus["Event Bus
(Kafka/SQS)
━━━━━━━━━━
• EventCreated
• EventPublished
• ParticipantRegistered
• WinnerSelected
• DistributionCompleted"] - - %% Job Queue - JobQueue["Job Queue
(RabbitMQ)
━━━━━━━━━━
• AI 작업 큐
• 이미지 생성 큐"] - - %% External System - External["외부시스템
[Circuit Breaker]
━━━━━━━━━━
• 국세청 API
• AI API
• 이미지 생성 API
• 배포 채널 APIs"] - - %% Command to Event Bus (이벤트 발행) - EventCmd ==>|"1. EventCreated
발행"| EventBus - EventCmd ==>|"2. EventPublished
발행"| EventBus - PartCmd ==>|"3. ParticipantRegistered
발행"| EventBus - PartCmd ==>|"4. WinnerSelected
발행"| EventBus - DistSvc ==>|"5. DistributionCompleted
발행"| EventBus - - %% Event Bus to Services (이벤트 구독) - EventBus -.->|"EventCreated
구독"| EventQuery - EventBus -.->|"EventCreated
구독"| AnalQuery - EventBus -.->|"EventPublished
구독"| DistSvc - EventBus -.->|"ParticipantRegistered
구독"| PartQuery - EventBus -.->|"ParticipantRegistered
구독"| AnalQuery - EventBus -.->|"WinnerSelected
구독"| PartQuery - EventBus -.->|"DistributionCompleted
구독"| AnalQuery - - %% Command to Job Queue (비동기 작업) - EventCmd -->|"AI 추천 요청"| JobQueue - EventCmd -->|"이미지 생성 요청"| JobQueue - JobQueue -->|작업 처리| AISvc - JobQueue -->|작업 처리| ContentSvc - - %% Query to Query (읽기 최적화) - AnalQuery -.->|캐시 조회| EventQuery - AnalQuery -.->|캐시 조회| PartQuery - - %% Services to External (Resilience 패턴) - UserCmd -->|"사업자번호 검증
[Circuit Breaker]
[Retry: 3회]"| External - AISvc -->|"트렌드 분석/추천
[Circuit Breaker]
[Timeout: 30s]"| External - ContentSvc -->|"이미지 생성
[Circuit Breaker]
[Timeout: 20s]"| External - DistSvc -->|"다중 채널 배포
[Circuit Breaker]
[Retry: 3회]
[Bulkhead]"| External - AnalQuery -->|"채널별 통계
[Circuit Breaker]
[Fallback: Cache]"| External - - %% Styling - classDef command fill:#4ECDC4,stroke:#14B8A6,stroke-width:3px - classDef query fill:#10B981,stroke:#059669,stroke-width:3px - classDef async fill:#8B5CF6,stroke:#7C3AED,stroke-width:3px,color:#fff - classDef eventbus fill:#F59E0B,stroke:#D97706,stroke-width:3px - classDef jobqueue fill:#FB923C,stroke:#EA580C,stroke-width:3px - classDef external fill:#E5E7EB,stroke:#9CA3AF,stroke-width:2px - - class UserCmd,EventCmd,PartCmd command - class EventQuery,PartQuery,AnalQuery query - class AISvc,ContentSvc,DistSvc async - class EventBus eventbus - class JobQueue jobqueue - class External external diff --git a/design/backend/logical/backup/logical-architecture.md.backup b/design/backend/logical/backup/logical-architecture.md.backup deleted file mode 100644 index a8f3553..0000000 --- a/design/backend/logical/backup/logical-architecture.md.backup +++ /dev/null @@ -1,626 +0,0 @@ -# KT AI 기반 소상공인 이벤트 자동 생성 서비스 - 논리 아키텍처 - -## 문서 정보 -- **작성일**: 2025-10-21 -- **버전**: 1.0 -- **작성자**: System Architect -- **관련 문서**: - - [유저스토리](../../userstory.md) - - [아키텍처 패턴](../../pattern/architecture-pattern.md) - - [UI/UX 설계서](../../uiux/uiux.md) - ---- - -## 목차 -1. [개요](#1-개요) -2. [서비스 아키텍처](#2-서비스-아키텍처) -3. [주요 사용자 플로우](#3-주요-사용자-플로우) -4. [데이터 흐름 및 캐싱 전략](#4-데이터-흐름-및-캐싱-전략) -5. [확장성 및 성능 고려사항](#5-확장성-및-성능-고려사항) -6. [보안 고려사항](#6-보안-고려사항) -7. [논리 아키텍처 다이어그램](#7-논리-아키텍처-다이어그램) - ---- - -## 1. 개요 - -### 1.1 설계 원칙 - -본 논리 아키텍처는 다음 원칙을 기반으로 설계되었습니다: - -#### 유저스토리 기반 설계 -- 20개 유저스토리와 정확히 매칭 -- 불필요한 추가 기능 배제 -- 비즈니스 요구사항 우선 반영 - -#### 마이크로서비스 아키텍처 -- **서비스 독립성**: 각 서비스는 독립적으로 배포 및 확장 가능 -- **캐시 우선 전략**: Redis를 통한 서비스 간 데이터 공유 최소화 -- **선택적 비동기**: AI 및 이미지 생성 등 장시간 작업만 비동기 처리 -- **느슨한 결합**: 서비스 간 직접 의존성 최소화 - -#### 클라우드 디자인 패턴 적용 -- **Cache-Aside**: AI 응답, 이미지 생성 결과 캐싱 (응답 시간 90% 개선) -- **API Gateway**: 중앙집중식 인증/라우팅/Rate Limiting -- **Asynchronous Request-Reply**: AI 추천, 이미지 생성 비동기 처리 -- **Circuit Breaker**: 7개 외부 API 장애 격리 (가용성 99% 목표) - -### 1.2 핵심 컴포넌트 정의 - -#### Client Layer -- **Web/Mobile Client**: 반응형 React 애플리케이션 - - Mobile First 설계 (60% 모바일 사용자) - - Progressive Web App (PWA) 지원 - -#### Gateway Layer -- **API Gateway**: Kong 또는 AWS API Gateway - - JWT 토큰 기반 인증/인가 - - URL 기반 서비스 라우팅 - - Rate Limiting (사용자당 100 req/min) - - 중앙집중식 로깅 및 모니터링 - -#### Service Layer (7개 마이크로서비스) -1. **User Service**: 사용자 인증 및 매장정보 관리 -2. **Event Service**: 이벤트 CRUD 및 상태 관리 -3. **AI Service**: 트렌드 분석 및 이벤트 추천 -4. **Content Service**: SNS 이미지 자동 생성 -5. **Distribution Service**: 다중 채널 배포 관리 -6. **Participation Service**: 이벤트 참여 및 당첨자 관리 -7. **Analytics Service**: 실시간 성과 대시보드 - -#### Data Layer -- **Redis Cache**: - - 세션 정보 (User) - - AI 추천 결과 (TTL 24시간) - - 이미지 생성 결과 (TTL 7일) - - 사업자번호 검증 결과 (TTL 7일) - - 대시보드 데이터 (TTL 5분) -- **Message Queue** (RabbitMQ/Kafka): - - AI 작업 큐 (비동기 처리) - - 이미지 생성 큐 - - 배포 작업 큐 -- **Database** (PostgreSQL): - - 서비스별 독립 데이터베이스 - - User DB, Event DB, Participation DB, Analytics DB - -#### External APIs -- **국세청 사업자등록정보 진위확인 API**: 사업자번호 검증 -- **Claude API / GPT-4 API**: AI 트렌드 분석 및 이벤트 추천 -- **Stable Diffusion / DALL-E API**: SNS 이미지 생성 -- **우리동네TV API**: 영상 배포 -- **링고비즈 API**: 연결음 업데이트 -- **지니TV 광고 API**: TV 광고 배포 -- **SNS APIs** (Instagram, Naver, Kakao): SNS 자동 포스팅 - ---- - -## 2. 서비스 아키텍처 - -### 2.1 서비스별 책임 - -#### User Service -**핵심 책임**: -- 회원가입/로그인 (JWT 토큰 발급) -- 프로필 관리 (매장 정보 포함) -- 사업자번호 검증 (국세청 API 연동) -- 로그아웃 및 세션 관리 - -**관련 유저스토리**: UFR-USER-010, 020, 030, 040 - -**주요 기능**: -- JWT 기반 인증/인가 -- Redis를 통한 세션 관리 -- 사업자번호 검증 결과 캐싱 (TTL 7일) -- 매장 정보 CRUD - -**데이터 저장**: -- User DB: users, stores 테이블 -- Redis: 세션 정보, 사업자번호 검증 결과 - -#### Event Service -**핵심 책임**: -- 이벤트 CRUD 및 상태 관리 -- 이벤트 생성 플로우 오케스트레이션 -- 이벤트 목록 조회 및 필터링 -- 이벤트 상세 정보 조회 - -**관련 유저스토리**: UFR-EVENT-010, 020, 030, 040, 050, 060, 070 - -**주요 기능**: -- 이벤트 생성 플로우 관리 (목적 선택 → AI 추천 → 콘텐츠 생성 → 배포) -- 이벤트 상태 관리 (진행중/예정/종료) -- 대시보드용 이벤트 목록 제공 -- 이벤트 검색 및 필터링 - -**데이터 저장**: -- Event DB: events, event_objectives, event_prizes 테이블 - -#### AI Service -**핵심 책임**: -- 업종/지역/시즌 트렌드 분석 -- 3가지 이벤트 기획안 자동 생성 -- 예상 성과 계산 (참여자 수, 비용, ROI) - -**관련 유저스토리**: UFR-AI-010 - -**주요 기능**: -- Claude/GPT-4 API 연동 -- 비동기 처리 (Job 기반) -- 트렌드 분석 결과 캐싱 (TTL 24시간) -- 3가지 옵션 차별화 (저비용/중비용/고비용) - -**처리 시간**: -- 캐시 HIT: 0.1초 -- 캐시 MISS: 10초 이내 (비동기 Job 처리) - -**데이터 저장**: -- Redis: AI 추천 결과 (TTL 24시간) -- Redis: Job 상태 정보 (TTL 1시간) - -#### Content Service -**핵심 책임**: -- 3가지 스타일 SNS 이미지 자동 생성 -- 플랫폼별 이미지 최적화 (Instagram, Naver, Kakao) -- 이미지 편집 기능 제공 - -**관련 유저스토리**: UFR-CONT-010, 020 - -**주요 기능**: -- Stable Diffusion/DALL-E API 연동 -- 비동기 이미지 생성 (Job 기반) -- 3가지 스타일 카드 생성 (심플/화려한/트렌디) -- 생성 이미지 캐싱 및 CDN 업로드 - -**처리 시간**: -- 캐시 HIT: 0.1초 -- 캐시 MISS: 5초 이내 (비동기 Job 처리) - -**데이터 저장**: -- Redis: 이미지 생성 결과 (CDN URL, TTL 7일) -- CDN: 생성된 이미지 파일 - -#### Distribution Service -**핵심 책임**: -- 다중 채널 동시 배포 (우리동네TV, 링고비즈, 지니TV, SNS) -- 배포 상태 모니터링 -- 채널별 독립적 처리 및 실패 재시도 - -**관련 유저스토리**: UFR-DIST-010, 020 - -**주요 기능**: -- 7개 외부 API 병렬 연동 (Circuit Breaker 적용) -- 채널별 독립 처리 (하나 실패해도 다른 채널 계속) -- 자동 재시도 (최대 3회) -- Fallback 전략 (배포 스킵 + 알림) - -**처리 시간**: 1분 이내 (모든 채널 배포 완료) - -**데이터 저장**: -- Event DB: distribution_logs 테이블 - -#### Participation Service -**핵심 책임**: -- 고객 이벤트 참여 접수 -- 참여자 목록 관리 -- 당첨자 자동 추첨 - -**관련 유저스토리**: UFR-PART-010, 020, 030 - -**주요 기능**: -- 중복 참여 체크 (전화번호 기반) -- 참여자 목록 조회 및 필터링 -- 난수 기반 무작위 추첨 -- 매장 방문 고객 가산점 옵션 - -**데이터 저장**: -- Participation DB: participants, winners 테이블 - -#### Analytics Service -**핵심 책임**: -- 실시간 성과 대시보드 -- 채널별 성과 분석 -- 투자 대비 수익률 계산 - -**관련 유저스토리**: UFR-ANAL-010 - -**주요 기능**: -- 다중 데이터 소스 통합 (7개 외부 API + 내부 서비스) -- 5분 간격 데이터 폴링 및 캐싱 -- 실시간 차트 및 그래프 생성 -- POS 시스템 연동 (선택) - -**처리 시간**: 0.5초 (캐시 기반) - -**데이터 저장**: -- Analytics DB: event_stats, channel_stats 테이블 -- Redis: 대시보드 데이터 (TTL 5분) - -### 2.2 서비스 간 통신 전략 - -#### 동기 통신 (Synchronous) -**사용 시나리오**: 즉시 응답이 필요한 단순 조회 - -- **User → Redis**: 세션 정보 조회 -- **Event → User**: 사용자 정보 검증 (Token 검증은 API Gateway에서 처리) -- **Participation → Event**: 이벤트 정보 조회 -- **Analytics → Event/Participation**: 통계 데이터 조회 - -**통신 방식**: REST API (HTTP/JSON) - -#### 캐시 우선 전략 (Cache-Aside) -**사용 시나리오**: 자주 사용되는 데이터, 외부 API 결과 - -- **AI Service**: 트렌드 분석 및 이벤트 추천 결과 - - 캐시 키: `ai:recommendation:{업종}:{지역}:{목적}` - - TTL: 24시간 - - 히트율 목표: 80% - -- **Content Service**: 생성된 이미지 URL - - 캐시 키: `content:image:{이벤트ID}:{스타일}` - - TTL: 7일 - - 히트율 목표: 80% - -- **User Service**: 사업자번호 검증 결과 - - 캐시 키: `user:business:{사업자번호}` - - TTL: 7일 - - 히트율 목표: 90% - -- **Analytics Service**: 대시보드 데이터 - - 캐시 키: `analytics:dashboard:{이벤트ID}` - - TTL: 5분 - - 히트율 목표: 95% - -**효과**: -- AI 응답 시간: 10초 → 0.1초 (99% 개선, 캐시 히트 시) -- 이미지 생성 시간: 5초 → 0.1초 (98% 개선, 캐시 히트 시) -- 대시보드 로딩 시간: 3초 → 0.5초 (83% 개선) - -#### 비동기 처리 (Asynchronous Request-Reply) -**사용 시나리오**: 장시간 작업 (10초 이상 소요) - -- **AI Service**: 트렌드 분석 + 이벤트 추천 (10초) - 1. 클라이언트 → Event Service: POST /api/ai/recommendations - 2. Event Service → AI Service: Job 생성 - 3. AI Service → 클라이언트: Job ID 즉시 반환 (0.1초) - 4. 백그라운드: AI Service → Claude API (10초) - 5. 폴링: 클라이언트 → Event Service: GET /api/jobs/{id} (5초 간격) - 6. 완료: AI Service → 클라이언트: 최종 결과 반환 - -- **Content Service**: 이미지 생성 (5초) - 1. 클라이언트 → Event Service: POST /api/content/images - 2. Event Service → Content Service: Job 생성 - 3. Content Service → 클라이언트: Job ID 즉시 반환 (0.1초) - 4. 백그라운드: Content Service → Stable Diffusion API (5초) - 5. 폴링: 클라이언트 → Event Service: GET /api/jobs/{id} (3초 간격) - 6. 완료: Content Service → 클라이언트: 최종 결과 반환 - -**Message Queue 사용**: -- RabbitMQ 또는 Kafka -- Priority Queue: AI 작업 우선순위 관리 -- Dead Letter Queue: 실패 작업 처리 - -#### Circuit Breaker 패턴 -**사용 시나리오**: 외부 API 장애 격리 - -- **적용 대상**: 7개 외부 API - - 국세청 API - - Claude/GPT-4 API - - Stable Diffusion/DALL-E API - - 우리동네TV API - - 링고비즈 API - - 지니TV API - - SNS APIs (Instagram, Naver, Kakao) - -- **동작 방식**: - - Closed (정상): 실패율 5% 미만 - - Open (차단): 실패율 5% 초과 시 Circuit Open → 모든 요청 Fallback - - Half-Open (테스트): 30초 후 1개 요청 시도 → 성공 시 Closed로 전환 - -- **Fallback 전략**: - - AI Service: 캐시된 이전 추천 결과 + 안내 메시지 - - Distribution Service: 해당 채널 배포 스킵 + 알림 - - User Service: 사업자번호 검증 스킵 (수동 확인으로 대체) - -**효과**: 가용성 95% → 99% 개선 - ---- - -## 3. 주요 사용자 플로우 - -### 3.1 이벤트 생성 플로우 (핵심 플로우) - -``` -1. [User] 07-이벤트목적선택 - - 클라이언트 → API Gateway → Event Service - - Event: 목적 저장 (신규 고객 유치/재방문 유도/매출 증대/인지도 향상) - -2. [AI] 08-AI이벤트추천 - - 클라이언트 → API Gateway → Event Service → AI Service - - AI: Job ID 즉시 반환 (0.1초) - - 백그라운드: AI Service → Claude API (10초) - * 캐시 확인 (Cache-Aside) - * 캐시 MISS: Claude API 호출 → 결과 캐싱 (TTL 24시간) - - 폴링: 클라이언트 → Event Service (5초 간격) - - 완료: AI 추천 결과 (3가지 옵션) 반환 - -3. [Content] 09-SNS이미지생성 - - 클라이언트 → API Gateway → Event Service → Content Service - - Content: Job ID 즉시 반환 (0.1초) - - 백그라운드: Content Service → Stable Diffusion API (5초) - * 캐시 확인 (Cache-Aside) - * 캐시 MISS: Stable Diffusion API 호출 → 이미지 CDN 업로드 → 결과 캐싱 (TTL 7일) - - 폴링: 클라이언트 → Event Service (3초 간격) - - 완료: 3가지 스타일 이미지 URL 반환 - -4. [Content] 10-콘텐츠편집 - - 클라이언트 → API Gateway → Content Service - - Content: 텍스트/색상 편집 적용 → 새 이미지 생성 - -5. [Distribution] 11-배포채널선택 - - 클라이언트 → API Gateway → Event Service - - Event: 배포 채널 정보 저장 - -6. [Event] 12-최종승인 - - 클라이언트 → API Gateway → Event Service - - Event: 이벤트 생성 완료 → Distribution Service 호출 - - Distribution: 다중 채널 배포 시작 (Circuit Breaker 적용) - * 우리동네TV API (영상 업로드) - * 링고비즈 API (연결음 업데이트) - * 지니TV API (광고 등록) - * SNS APIs (Instagram, Naver, Kakao 자동 포스팅) - - 배포 완료: 대시보드로 이동 -``` - -### 3.2 고객 참여 플로우 - -``` -1. [Participation] 15-이벤트참여 - - 외부 채널 (SNS/TV/연결음) → 이벤트 발견 - - 클라이언트 → API Gateway → Participation Service - - Participation: 중복 참여 체크 (전화번호 기반) - - 참여 접수 완료 → 응모 번호 발급 -``` - -### 3.3 성과 분석 플로우 - -``` -1. [Analytics] 17-실시간대시보드 - - 클라이언트 → API Gateway → Analytics Service - - Analytics: 캐시 확인 (TTL 5분) - * 캐시 HIT: 즉시 반환 (0.5초) - * 캐시 MISS: 다중 데이터 소스 통합 - - Participation Service: 참여자 데이터 - - Distribution Service: 채널별 노출 수 - - 외부 APIs: 우리동네TV, 지니TV, SNS 통계 - - POS 시스템: 매출 데이터 (선택) - * 결과 캐싱 (TTL 5분) - - 실시간 차트/그래프 렌더링 -``` - ---- - -## 4. 데이터 흐름 및 캐싱 전략 - -### 4.1 데이터 흐름 - -#### 읽기 플로우 (Cache-Aside 패턴) -``` -1. Application → Cache 확인 - - Cache HIT: 캐시된 데이터 즉시 반환 - - Cache MISS: - 2. Application → Database/External API 조회 - 3. Database/External API → Application 데이터 반환 - 4. Application → Cache 데이터 저장 (TTL 설정) - 5. Application → Client 데이터 반환 -``` - -#### 쓰기 플로우 (Write-Through 패턴) -``` -1. Application → Database 쓰기 -2. Database → Application 성공 응답 -3. Application → Cache 무효화 또는 업데이트 -4. Application → Client 성공 응답 -``` - -### 4.2 캐싱 전략 - -#### Redis 캐시 구조 - -| 서비스 | 캐시 키 패턴 | 데이터 타입 | TTL | 예상 크기 | 히트율 목표 | -|--------|-------------|-----------|-----|----------|-----------| -| User | `user:session:{token}` | String | 7일 | 1KB | - | -| User | `user:business:{사업자번호}` | String | 7일 | 0.5KB | 90% | -| AI | `ai:recommendation:{업종}:{지역}:{목적}` | Hash | 24시간 | 10KB | 80% | -| Content | `content:image:{이벤트ID}:{스타일}` | String | 7일 | 0.2KB (URL) | 80% | -| Analytics | `analytics:dashboard:{이벤트ID}` | Hash | 5분 | 5KB | 95% | -| AI | `job:{jobId}` | Hash | 1시간 | 1KB | - | -| Content | `job:{jobId}` | Hash | 1시간 | 1KB | - | - -#### Redis 메모리 산정 -- **예상 동시 사용자**: 100명 -- **예상 이벤트 수**: 50개 -- **예상 캐시 항목 수**: 10,000개 -- **예상 총 메모리**: 약 50MB (운영 환경 2GB 할당) - -#### 캐시 무효화 전략 -- **TTL 기반 자동 만료**: 대부분의 캐시 -- **수동 무효화**: 이벤트 수정/삭제 시 관련 캐시 삭제 -- **Lazy 무효화**: 데이터 변경 시 다음 조회 시점에 갱신 - -### 4.3 데이터베이스 전략 - -#### 서비스별 독립 데이터베이스 -- **User DB**: users, stores -- **Event DB**: events, event_objectives, event_prizes, distribution_logs -- **Participation DB**: participants, winners -- **Analytics DB**: event_stats, channel_stats - -#### 데이터 일관성 전략 -- **Eventual Consistency**: 서비스 간 데이터는 최종 일관성 보장 -- **Strong Consistency**: 서비스 내부 트랜잭션은 강한 일관성 보장 -- **Saga 패턴**: 이벤트 생성 플로우 (보상 트랜잭션) - ---- - -## 5. 확장성 및 성능 고려사항 - -### 5.1 수평 확장 전략 - -#### 서비스별 확장 전략 -| 서비스 | 초기 인스턴스 | 확장 조건 | 최대 인스턴스 | Auto-scaling 메트릭 | -|--------|-------------|----------|-------------|-------------------| -| User | 2 | CPU > 70% | 5 | CPU, 메모리 | -| Event | 2 | CPU > 70% | 10 | CPU, 메모리 | -| AI | 1 | Job Queue > 10 | 3 | Queue 길이 | -| Content | 1 | Job Queue > 10 | 3 | Queue 길이 | -| Distribution | 2 | CPU > 70% | 5 | CPU, 메모리 | -| Participation | 1 | CPU > 70% | 3 | CPU, 메모리 | -| Analytics | 1 | CPU > 70% | 3 | CPU, 메모리 | - -#### Redis Cluster -- **초기 구성**: 3 노드 (Master 3, Replica 3) -- **확장**: 노드 추가를 통한 수평 확장 -- **HA**: Redis Sentinel을 통한 자동 Failover - -#### Database Replication -- **Primary-Replica 구조**: 읽기 부하 분산 -- **읽기 확장**: Read Replica 추가 (필요 시) -- **쓰기 확장**: Sharding (Phase 2 이후) - -### 5.2 성능 목표 - -#### 응답 시간 목표 -| 기능 | 목표 시간 | 캐시 HIT | 캐시 MISS | -|------|----------|---------|----------| -| 로그인 | 0.5초 | - | - | -| 이벤트 목록 조회 | 0.3초 | - | - | -| AI 트렌드 분석 + 추천 | 0.1초 | ✅ | 10초 (비동기) | -| SNS 이미지 생성 | 0.1초 | ✅ | 5초 (비동기) | -| 다중 채널 배포 | 1분 | - | - | -| 대시보드 로딩 | 0.5초 | ✅ | 3초 | - -#### 처리량 목표 -- **동시 사용자**: 100명 (MVP 목표) -- **API 요청**: 1,000 req/min -- **AI 작업**: 10 jobs/min -- **이미지 생성**: 10 jobs/min - -### 5.3 성능 최적화 기법 - -#### Frontend 최적화 -- **Code Splitting**: 페이지별 번들 분할 -- **Lazy Loading**: 차트 라이브러리 지연 로딩 -- **CDN**: 정적 자산 CDN 배포 -- **Compression**: Gzip/Brotli 압축 - -#### Backend 최적화 -- **Connection Pooling**: 데이터베이스 연결 풀 관리 -- **Query Optimization**: 인덱스 최적화, N+1 쿼리 방지 -- **Batch Processing**: 대량 데이터 일괄 처리 -- **Pagination**: 목록 조회 페이지네이션 - -#### Cache 최적화 -- **Multi-Level Caching**: Browser Cache → CDN → Redis → Database -- **Cache Warming**: 자주 사용되는 데이터 사전 로딩 -- **Cache Preloading**: 피크 시간 전 캐시 준비 - ---- - -## 6. 보안 고려사항 - -### 6.1 인증 및 인가 - -#### JWT 기반 인증 -- **토큰 발급**: User Service에서 로그인 시 JWT 토큰 발급 -- **토큰 검증**: API Gateway에서 모든 요청의 JWT 토큰 검증 -- **토큰 저장**: Redis에 세션 정보 저장 (TTL 7일) -- **토큰 갱신**: Refresh Token 패턴 (선택) - -#### 역할 기반 접근 제어 (RBAC) -- **역할**: OWNER (매장 사장님), CUSTOMER (이벤트 참여자) -- **권한 관리**: API별 필요 역할 정의 -- **API Gateway 검증**: 요청자의 역할 확인 - -### 6.2 데이터 보안 - -#### 민감 정보 암호화 -- **비밀번호**: bcrypt 해싱 (Cost Factor: 10) -- **사업자번호**: AES-256 암호화 저장 -- **개인정보**: 전화번호 마스킹 (010-****-1234) - -#### 전송 보안 -- **HTTPS**: 모든 통신 TLS 1.3 암호화 -- **API Key**: 외부 API 호출 시 안전한 Key 관리 (AWS Secrets Manager) - -#### 데이터 접근 통제 -- **Database**: 서비스별 독립 계정, 최소 권한 원칙 -- **Redis**: 비밀번호 설정, ACL 적용 -- **백업**: 암호화된 백업 저장 - -### 6.3 보안 모니터링 - -#### 위협 탐지 -- **Rate Limiting**: API Gateway에서 사용자당 100 req/min -- **Brute Force 방지**: 로그인 5회 실패 시 계정 잠금 (삭제됨, 향후 추가 가능) -- **SQL Injection 방지**: Prepared Statement 사용 -- **XSS 방지**: 입력 데이터 Sanitization - -#### 로깅 및 감사 -- **Access Log**: 모든 API 요청 로깅 -- **Audit Log**: 민감 작업 (로그인, 이벤트 생성, 당첨자 추첨) 감사 로그 -- **중앙집중식 로깅**: ELK Stack 또는 CloudWatch Logs - ---- - -## 7. 논리 아키텍처 다이어그램 - -논리 아키텍처 다이어그램은 별도 Mermaid 파일로 작성되었습니다. - -**파일 위치**: `logical-architecture.mmd` - -**다이어그램 확인 방법**: -1. https://mermaid.live/edit 접속 -2. `logical-architecture.mmd` 파일 내용 붙여넣기 -3. 다이어그램 시각적 확인 - -**다이어그램 구성**: -- Client Layer: Web/Mobile Client -- Gateway Layer: API Gateway -- Service Layer: 7개 마이크로서비스 -- Data Layer: Redis Cache, Message Queue, Databases -- External APIs: 7개 외부 API - -**의존성 표현**: -- 실선 화살표 (→): 동기적 의존성 -- 점선 화살표 (-.->): 비동기 의존성 또는 캐시 접근 -- 화살표 레이블: 의존성 목적 명시 - ---- - -## 부록 - -### A. 참고 문서 -- [유저스토리](../../userstory.md) -- [아키텍처 패턴](../../pattern/architecture-pattern.md) -- [UI/UX 설계서](../../uiux/uiux.md) -- [클라우드 디자인 패턴](../../../claude/cloud-design-patterns.md) - -### B. 주요 결정사항 -1. **Cache-Aside 패턴 채택**: AI 응답 시간 90% 개선 목표 -2. **Asynchronous Request-Reply 패턴 채택**: AI/이미지 생성 비동기 처리 -3. **Circuit Breaker 패턴 채택**: 외부 API 장애 격리 -4. **서비스별 독립 Database**: 마이크로서비스 독립성 보장 -5. **Redis 캐시 우선 전략**: 서비스 간 직접 의존성 최소화 - -### C. 향후 개선 방안 (Phase 2 이후) -1. **Saga 패턴**: 복잡한 분산 트랜잭션 관리 -2. **CQRS 패턴**: 읽기/쓰기 분리로 대시보드 성능 최적화 -3. **Event Sourcing**: 이벤트 변경 이력 추적 및 감사 -4. **Service Mesh**: Istio를 통한 고급 트래픽 관리 -5. **Database Sharding**: 쓰기 확장성 개선 - ---- - -**문서 버전**: 1.0 -**최종 수정일**: 2025-10-21 -**작성자**: System Architect diff --git a/design/backend/logical/backup/logical-architecture.mmd.backup b/design/backend/logical/backup/logical-architecture.mmd.backup deleted file mode 100644 index 5148b9a..0000000 --- a/design/backend/logical/backup/logical-architecture.mmd.backup +++ /dev/null @@ -1,48 +0,0 @@ -graph TB - %% KT AI 기반 소상공인 이벤트 자동 생성 서비스 - 논리 아키텍처 (간소화 버전) - - %% Service Layer - subgraph "Service Layer" - UserSvc["User Service
• 회원가입/로그인
• 프로필 관리
• 사업자번호 검증"] - EventSvc["Event Service
• 이벤트 CRUD
• 플로우 오케스트레이션
• 상태 관리"] - AISvc["AI Service
• 트렌드 분석
• 3가지 이벤트 추천
• 비동기 Job 처리"] - ContentSvc["Content Service
• SNS 이미지 생성
• 3가지 스타일
• 비동기 Job 처리"] - DistSvc["Distribution Service
• 다중 채널 배포
• Circuit Breaker
• 배포 모니터링"] - PartSvc["Participation Service
• 이벤트 참여
• 참여자 관리
• 당첨자 추첨"] - AnalSvc["Analytics Service
• 실시간 대시보드
• 채널별 성과
• ROI 분석"] - end - - %% Message Queue - Queue["Message Queue
• AI 작업 큐
• 이미지 생성 큐
• 배포 작업 큐"] - - %% External System - External["외부시스템
• 국세청 API
• AI API
• 이미지 생성 API
• 배포 채널 APIs"] - - %% Service to Queue - EventSvc -.->|AI 추천 요청| Queue - EventSvc -.->|이미지 생성 요청| Queue - Queue -.->|비동기 작업 처리| AISvc - Queue -.->|비동기 작업 처리| ContentSvc - - %% Service to Service - EventSvc -->|배포 시작| DistSvc - PartSvc -->|이벤트 정보 조회| EventSvc - AnalSvc -->|이벤트 정보| EventSvc - AnalSvc -->|참여자 데이터| PartSvc - AnalSvc -->|배포 통계| DistSvc - - %% Service to External - UserSvc -->|사업자번호 검증| External - AISvc -->|트렌드 분석/추천| External - ContentSvc -->|이미지 생성| External - DistSvc -->|다중 채널 배포| External - AnalSvc -->|채널별 통계| External - - %% Styling - classDef service fill:#4ECDC4,stroke:#14B8A6,stroke-width:2px - classDef queue fill:#FB923C,stroke:#EA580C,stroke-width:2px - classDef external fill:#E5E7EB,stroke:#9CA3AF,stroke-width:2px - - class UserSvc,EventSvc,AISvc,ContentSvc,DistSvc,PartSvc,AnalSvc service - class Queue queue - class External external diff --git a/design/backend/sequence/inner/README-USER.md b/design/backend/sequence/inner/README-USER.md deleted file mode 100644 index 3d81dc0..0000000 --- a/design/backend/sequence/inner/README-USER.md +++ /dev/null @@ -1,386 +0,0 @@ -# User Service 내부 시퀀스 설계서 - -## 문서 정보 -- **작성일**: 2025-10-22 -- **작성자**: System Architect -- **버전**: 1.0 -- **관련 문서**: - - [유저스토리](../../../userstory.md) - - [외부 시퀀스](../outer/사용자인증플로우.puml) - - [논리 아키텍처](../../logical/logical-architecture.md) - ---- - -## 개요 - -User Service의 4가지 주요 시나리오에 대한 내부 처리 흐름을 상세히 정의합니다. - -### 시나리오 목록 - -| 번호 | 파일명 | 유저스토리 | 주요 처리 내용 | -|------|--------|-----------|---------------| -| 1 | user-회원가입.puml | UFR-USER-010 | 기본 정보 검증, 사업자번호 검증(국세청 API), 트랜잭션 처리, JWT 발급 | -| 2 | user-로그인.puml | UFR-USER-020 | 비밀번호 검증(bcrypt), JWT 발급, 세션 저장, 최종 로그인 시각 업데이트 | -| 3 | user-프로필수정.puml | UFR-USER-030 | 기본 정보 수정, 매장 정보 수정, 비밀번호 변경, 트랜잭션 처리 | -| 4 | user-로그아웃.puml | UFR-USER-040 | JWT 검증, 세션 삭제, Blacklist 추가 | - ---- - -## 아키텍처 구조 - -### Layered Architecture -``` -┌─────────────────────────────────────┐ -│ API Layer (Controller) │ - HTTP 요청/응답 처리 -│ │ - DTO 변환 및 검증 -└─────────────────────────────────────┘ - ↓ -┌─────────────────────────────────────┐ -│ Business Layer (Service) │ - 비즈니스 로직 처리 -│ - UserService │ - 트랜잭션 관리 -│ - AuthenticationService │ - 외부 API 연동 -│ - BusinessValidator │ -└─────────────────────────────────────┘ - ↓ -┌─────────────────────────────────────┐ -│ Data Layer (Repository) │ - 데이터베이스 접근 -│ - UserRepository │ - JPA/MyBatis -│ - StoreRepository │ -└─────────────────────────────────────┘ - ↓ -┌─────────────────────────────────────┐ -│ External Systems │ - 국세청 API -│ │ - Redis Cache -│ │ - PostgreSQL DB -└─────────────────────────────────────┘ -``` - -### 주요 컴포넌트 - -#### API Layer -- **UserController**: 사용자 관련 REST API 엔드포인트 - - `POST /api/users/register`: 회원가입 - - `POST /api/users/login`: 로그인 - - `PUT /api/users/profile`: 프로필 수정 - - `POST /api/users/logout`: 로그아웃 - -#### Business Layer -- **UserService**: 사용자 정보 관리 비즈니스 로직 -- **AuthenticationService**: 인증 및 세션 관리 로직 -- **BusinessValidator**: 사업자번호 검증 로직 (Circuit Breaker 적용) - -#### Data Layer -- **UserRepository**: users 테이블 CRUD -- **StoreRepository**: stores 테이블 CRUD - -#### Utility -- **PasswordEncoder**: bcrypt 해싱 (Cost Factor 10) -- **JwtTokenProvider**: JWT 토큰 생성/검증 (만료 7일) - ---- - -## 시나리오별 상세 설명 - -### 1. 회원가입 (user-회원가입.puml) - -#### 처리 단계 -1. **입력 검증**: `@Valid` 어노테이션으로 DTO 검증 -2. **중복 사용자 확인**: 전화번호 기반 중복 체크 -3. **사업자번호 검증**: - - Redis 캐시 확인 (TTL 7일) - - 캐시 MISS: 국세청 API 호출 (Circuit Breaker 적용) - - 캐시 HIT: 0.1초, MISS: 5초 -4. **비밀번호 해싱**: bcrypt (Cost Factor 10) -5. **사업자번호 암호화**: AES-256 -6. **데이터베이스 트랜잭션**: - - User INSERT - - Store INSERT - - COMMIT (실패 시 자동 Rollback) -7. **JWT 토큰 생성**: Claims(userId, role=OWNER, exp=7일) -8. **세션 저장**: Redis (TTL 7일) - -#### Resilience 패턴 -- **Circuit Breaker**: 국세청 API (실패율 50% 초과 시 Open) -- **Retry**: 최대 3회 (지수 백오프: 1초, 2초, 4초) -- **Timeout**: 5초 -- **Fallback**: 사업자번호 검증 스킵 (수동 확인 안내) - -#### 응답 시간 -- 캐시 HIT: 1초 이내 -- 캐시 MISS: 5초 이내 - ---- - -### 2. 로그인 (user-로그인.puml) - -#### 처리 단계 -1. **입력 검증**: 필수 필드 확인 -2. **사용자 조회**: 전화번호로 사용자 검색 -3. **비밀번호 검증**: bcrypt compare -4. **JWT 토큰 생성**: Claims(userId, role=OWNER, exp=7일) -5. **세션 저장**: Redis (TTL 7일) -6. **최종 로그인 시각 업데이트**: 비동기 처리 (`@Async`) - -#### 보안 처리 -- 에러 메시지: 전화번호/비밀번호 구분 없이 동일 메시지 반환 -- 비밀번호: bcrypt compare (원본 노출 안 됨) - -#### 성능 최적화 -- 최종 로그인 시각 업데이트: 비동기 처리로 응답 시간 단축 -- 응답 시간: 0.5초 목표 - ---- - -### 3. 프로필 수정 (user-프로필수정.puml) - -#### 처리 단계 -1. **JWT 인증**: `@AuthenticationPrincipal`로 userId 추출 -2. **사용자 조회**: userId로 기존 정보 조회 -3. **비밀번호 변경 처리** (선택적): - - 현재 비밀번호 검증 (bcrypt compare) - - 새 비밀번호 해싱 (bcrypt) -4. **기본 정보 업데이트**: 이름, 전화번호, 이메일 -5. **매장 정보 업데이트**: 매장명, 업종, 주소, 영업시간 -6. **데이터베이스 트랜잭션**: - - User UPDATE - - Store UPDATE - - COMMIT (실패 시 자동 Rollback) -7. **캐시 무효화**: 프로필 캐시 삭제 (선택적) - -#### 보안 처리 -- 비밀번호 변경: 현재 비밀번호 확인 필수 -- 권한 검증: 본인만 수정 가능 - -#### 향후 개선사항 -- 전화번호 변경: SMS/이메일 재인증 구현 -- 이메일 변경: 이메일 인증 구현 - ---- - -### 4. 로그아웃 (user-로그아웃.puml) - -#### 처리 단계 -1. **JWT 인증**: `@AuthenticationPrincipal`로 userId 추출 -2. **JWT 토큰 검증**: 서명 및 만료 시간 확인 -3. **Redis 세션 삭제**: `DEL user:session:{token}` -4. **JWT Blacklist 추가** (선택적): - - 만료되지 않은 토큰 강제 무효화 - - Redis에 Blacklist 추가 (TTL: 남은 만료 시간) -5. **로그아웃 로그 기록**: userId, timestamp - -#### 보안 처리 -- JWT Blacklist: 만료 전 토큰 강제 무효화 -- 멱등성 보장: 중복 로그아웃 요청에 안전 - -#### 클라이언트 측 처리 -- LocalStorage 또는 Cookie에서 JWT 토큰 삭제 -- 로그인 화면으로 리다이렉트 - -#### 성능 최적화 -- Redis 삭제 연산: O(1) 시간 복잡도 -- 응답 시간: 0.1초 이내 - ---- - -## 데이터 모델 - -### User Entity -```java -@Entity -@Table(name = "users") -public class User { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long userId; - - @Column(nullable = false, length = 100) - private String name; - - @Column(nullable = false, unique = true, length = 20) - private String phoneNumber; - - @Column(nullable = false, unique = true, length = 255) - private String email; - - @Column(nullable = false, length = 60) - private String passwordHash; // bcrypt hash - - @Enumerated(EnumType.STRING) - @Column(nullable = false, length = 20) - private UserRole role; // OWNER, CUSTOMER - - @Column(name = "last_login_at") - private LocalDateTime lastLoginAt; - - @Column(name = "created_at", nullable = false) - private LocalDateTime createdAt; - - @Column(name = "updated_at") - private LocalDateTime updatedAt; -} -``` - -### Store Entity -```java -@Entity -@Table(name = "stores") -public class Store { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long storeId; - - @Column(name = "user_id", nullable = false) - private Long userId; - - @Column(nullable = false, length = 200) - private String storeName; - - @Column(length = 100) - private String industry; - - @Column(columnDefinition = "TEXT") - private String address; - - @Column(name = "business_number_encrypted", length = 255) - private String businessNumberEncrypted; // AES-256 encrypted - - @Column(name = "business_hours", length = 500) - private String businessHours; - - @Column(name = "created_at", nullable = false) - private LocalDateTime createdAt; - - @Column(name = "updated_at") - private LocalDateTime updatedAt; -} -``` - ---- - -## 캐싱 전략 - -### Redis 캐시 키 구조 - -| 캐시 키 패턴 | 데이터 타입 | TTL | 용도 | -|------------|-----------|-----|------| -| `user:session:{token}` | String (JSON) | 7일 | JWT 세션 정보 (userId, role) | -| `user:business:{사업자번호}` | String (JSON) | 7일 | 사업자번호 검증 결과 (valid, status) | -| `jwt:blacklist:{token}` | String | 남은 만료 시간 | 로그아웃된 JWT 토큰 Blacklist | -| `user:profile:{userId}` | String (JSON) | 1시간 | 사용자 프로필 정보 (선택적) | - -### Cache-Aside 패턴 -1. Application → Redis 확인 (Cache HIT/MISS) -2. Cache MISS → Database/External API 조회 -3. Database/External API → Redis 캐싱 (TTL 설정) -4. Redis → Application 반환 - ---- - -## 에러 처리 - -### 주요 예외 클래스 - -| 예외 클래스 | HTTP 상태 | 발생 시점 | -|-----------|---------|----------| -| `DuplicateUserException` | 400 | 이미 가입된 전화번호 | -| `BusinessNumberInvalidException` | 400 | 사업자번호 검증 실패 | -| `AuthenticationFailedException` | 401 | 로그인 실패 (전화번호/비밀번호 불일치) | -| `InvalidTokenException` | 401 | JWT 토큰 무효 | -| `UserNotFoundException` | 404 | 사용자 없음 | -| `InvalidPasswordException` | 400 | 현재 비밀번호 불일치 (프로필 수정) | - -### 에러 응답 형식 -```json -{ - "error": "에러 메시지", - "code": "ERROR_CODE", - "timestamp": "2025-10-22T10:30:00Z" -} -``` - ---- - -## 보안 고려사항 - -### 1. 비밀번호 보안 -- **해싱 알고리즘**: bcrypt (Cost Factor 10) -- **원본 노출 방지**: 비밀번호는 해시로만 저장, 평문 로깅 금지 -- **에러 메시지**: 전화번호/비밀번호 구분 없이 동일 메시지 반환 (보안 강화) - -### 2. JWT 보안 -- **만료 시간**: 7일 (Refresh Token 별도 구현 가능) -- **서명 알고리즘**: HS256 또는 RS256 -- **Blacklist 관리**: 로그아웃 시 Redis Blacklist에 추가 - -### 3. 민감 정보 암호화 -- **사업자번호**: AES-256 암호화 저장 -- **전송 보안**: HTTPS 강제 적용 - -### 4. 세션 관리 -- **세션 저장**: Redis (서버 재시작에도 유지) -- **세션 만료**: 7일 후 자동 삭제 (TTL) -- **동시 세션**: 동일 사용자 다중 세션 허용 (필요 시 제한 가능) - ---- - -## 성능 최적화 - -### 1. 캐싱 효과 -- **사업자번호 검증**: 5초 → 0.1초 (98% 개선) -- **세션 조회**: Redis 사용으로 DB 부하 감소 - -### 2. 비동기 처리 -- **최종 로그인 시각 업데이트**: `@Async`로 비동기 처리 -- **응답 시간 개선**: 0.5초 목표 달성 - -### 3. 데이터베이스 최적화 -- **인덱스**: `phone_number`, `email` 컬럼에 Unique Index -- **Connection Pool**: HikariCP 사용 (최소 10개, 최대 50개) - ---- - -## 테스트 전략 - -### Unit Test -- UserService, AuthenticationService 단위 테스트 -- Mock 객체: UserRepository, Redis, 국세청 API - -### Integration Test -- Controller → Service → Repository 통합 테스트 -- 실제 Redis 및 PostgreSQL 사용 (Testcontainers) - -### E2E Test -- Postman 또는 REST Assured로 전체 플로우 테스트 -- 회원가입 → 로그인 → 프로필 수정 → 로그아웃 - ---- - -## 향후 개선사항 - -### Phase 2 -1. **Refresh Token 구현**: Access Token 만료 시 갱신 메커니즘 -2. **소셜 로그인**: 카카오, 네이버, 구글 OAuth 2.0 연동 -3. **2FA (Two-Factor Authentication)**: SMS 또는 TOTP 기반 2단계 인증 -4. **비밀번호 재설정**: 이메일/SMS를 통한 비밀번호 재설정 기능 - -### Phase 3 -1. **계정 잠금 정책**: 로그인 5회 실패 시 계정 잠금 -2. **세션 관리 고도화**: 동시 세션 수 제한, 세션 활성 기록 -3. **감사 로그**: 민감 작업(로그인, 비밀번호 변경) 감사 로그 저장 -4. **Rate Limiting**: 로그인 API에 Rate Limiting 적용 (사용자당 5회/분) - ---- - -## 참고 문서 -- [유저스토리](../../../userstory.md) -- [외부 시퀀스](../outer/사용자인증플로우.puml) -- [논리 아키텍처](../../logical/logical-architecture.md) -- [공통설계원칙](../../../common-principles.md) -- [내부시퀀스설계가이드](../../../../claude/sequence-inner-design.md) - ---- - -**문서 버전**: 1.0 -**최종 수정일**: 2025-10-22 -**작성자**: System Architect -**변경 사항**: User Service 내부 시퀀스 4개 시나리오 초안 작성 완료 diff --git a/design/backend/sequence/inner/README-event-sequences.md b/design/backend/sequence/inner/README-event-sequences.md deleted file mode 100644 index ba93e86..0000000 --- a/design/backend/sequence/inner/README-event-sequences.md +++ /dev/null @@ -1,263 +0,0 @@ -# Event Service - 내부 시퀀스 설계 완료 - -## 문서 정보 -- **작성일**: 2025-10-22 -- **작성자**: System Architect -- **관련 문서**: - - [유저스토리](../../../userstory.md) - - [외부 시퀀스 - 이벤트생성플로우](../outer/이벤트생성플로우.puml) - - [논리 아키텍처](../../logical/logical-architecture.md) - ---- - -## 작성 완료 시나리오 (10개) - -### 1. event-목적선택.puml -- **유저스토리**: UFR-EVENT-020 -- **기능**: 이벤트 목적 선택 및 저장 -- **주요 흐름**: - - POST /api/events/purposes - - EventService → EventRepository → Event DB 저장 - - Redis 캐시 저장 (TTL 30분) - - Kafka EventCreated 이벤트 발행 -- **특징**: 캐시 히트 시 DB 조회 생략 - -### 2. event-AI추천요청.puml -- **유저스토리**: UFR-EVENT-030 -- **기능**: AI 추천 요청 (Kafka Job 발행) -- **주요 흐름**: - - POST /api/events/{id}/ai-recommendations - - EventService → JobService - - Kafka ai-job 토픽 발행 - - Job ID 즉시 반환 (202 Accepted) -- **특징**: 비동기 처리, AI Service는 백그라운드에서 Kafka 구독 - -### 3. event-추천결과조회.puml -- **유저스토리**: UFR-EVENT-030 (결과 조회) -- **기능**: AI 추천 결과 폴링 조회 -- **주요 흐름**: - - GET /api/jobs/{jobId}/status - - JobService → Redis 캐시 조회 - - Job 상태에 따라 응답 (COMPLETED/PROCESSING/FAILED) -- **특징**: 최대 30초 동안 폴링 (2초 간격) - -### 4. event-이미지생성요청.puml -- **유저스토리**: UFR-CONT-010 -- **기능**: 이미지 생성 요청 (Kafka Job 발행) -- **주요 흐름**: - - POST /api/events/{id}/content-generation - - EventService → JobService - - Kafka image-job 토픽 발행 - - Job ID 즉시 반환 (202 Accepted) -- **특징**: Content Service는 백그라운드에서 3가지 스타일 생성 - -### 5. event-이미지결과조회.puml -- **유저스토리**: UFR-CONT-010 (결과 조회) -- **기능**: 이미지 생성 결과 폴링 조회 -- **주요 흐름**: - - GET /api/jobs/{jobId}/status - - JobService → Redis 캐시 조회 - - 완료 시 3가지 스타일 이미지 URL 반환 -- **특징**: 최대 30초 동안 폴링 (3초 간격) - -### 6. event-콘텐츠선택.puml -- **유저스토리**: UFR-CONT-020 -- **기능**: 선택한 콘텐츠 저장 -- **주요 흐름**: - - PUT /api/events/drafts/{id}/content - - EventService → EventRepository - - 선택한 이미지 URL 및 편집 내용 저장 - - 캐시 무효화 -- **특징**: 텍스트, 색상 편집 내용 적용 - -### 7. event-최종승인및배포.puml -- **유저스토리**: UFR-EVENT-050 -- **기능**: 최종 승인 및 Distribution Service 동기 호출 -- **주요 흐름**: - - POST /api/events/{id}/publish - - 이벤트 상태 변경 (DRAFT → APPROVED) - - Kafka EventCreated 이벤트 발행 - - Distribution Service 동기 호출 (POST /api/distribution/distribute) - - 배포 완료 후 상태 변경 (APPROVED → ACTIVE) -- **특징**: Circuit Breaker 적용, Timeout 70초 - -### 8. event-상세조회.puml -- **유저스토리**: UFR-EVENT-060 -- **기능**: 이벤트 상세 정보 조회 -- **주요 흐름**: - - GET /api/events/{id} - - Redis 캐시 확인 (TTL 5분) - - 캐시 미스 시 DB 조회 (JOIN으로 경품, 배포 이력 포함) - - 사용자 권한 검증 -- **특징**: JOIN 쿼리로 관련 데이터 한 번에 조회 - -### 9. event-목록조회.puml -- **유저스토리**: UFR-EVENT-070 -- **기능**: 이벤트 목록 조회 (필터/검색) -- **주요 흐름**: - - GET /api/events?status={status}&keyword={keyword} - - Redis 캐시 확인 (TTL 1분) - - 캐시 미스 시 DB 조회 (필터/검색 조건 적용) - - 페이지네이션 (20개/페이지) -- **특징**: 인덱스 활용 (user_id, status, created_at) - -### 10. event-대시보드조회.puml -- **유저스토리**: UFR-EVENT-010 -- **기능**: 대시보드 이벤트 목록 -- **주요 흐름**: - - GET /api/events/dashboard - - Redis 캐시 확인 (TTL 1분) - - 캐시 미스 시 병렬 조회 (진행중/예정/종료) - - 각 섹션 최대 5개 표시 -- **특징**: 병렬 쿼리로 성능 최적화 - ---- - -## 설계 원칙 준수 사항 - -### 1. 공통설계원칙 준수 -- ✅ 모든 레이어 표시 (Controller → Service → Repository) -- ✅ 외부 시스템/인프라 `<>` 표시 -- ✅ 캐시 접근 명시 (Redis) -- ✅ DB 접근 명시 (PostgreSQL) -- ✅ Kafka 이벤트/Job 발행 표시 - -### 2. 내부시퀀스설계 가이드 준수 -- ✅ 각 시나리오별 독립 파일 생성 -- ✅ PlantUML `!theme mono` 적용 -- ✅ 명확한 타이틀 (서비스명 + 시나리오 + 유저스토리) -- ✅ 참여자 타입 표시 (<>, <>, <>, <>) -- ✅ 데이터베이스 쿼리 표시 -- ✅ 캐싱 전략 표시 (Cache-Aside) -- ✅ 비동기 처리 흐름 표시 (Kafka) - -### 3. Event-Driven 아키텍처 반영 -- ✅ Kafka Event Topics 발행 (EventCreated) -- ✅ Kafka Job Topics 발행 (ai-job, image-job) -- ✅ 비동기 작업 Job ID 즉시 반환 (202 Accepted) -- ✅ 폴링 방식 결과 조회 (GET /api/jobs/{jobId}/status) - -### 4. Resilience 패턴 명시 -- ✅ Circuit Breaker 적용 표시 (Distribution Service 호출) -- ✅ Timeout 설정 표시 (70초) -- ✅ 캐싱 전략 표시 (TTL 설정) - ---- - -## 검증 체크리스트 - -### 유저스토리 매칭 -- [x] UFR-EVENT-010: 대시보드 이벤트 목록 → event-대시보드조회.puml -- [x] UFR-EVENT-020: 이벤트 목적 선택 → event-목적선택.puml -- [x] UFR-EVENT-030: AI 이벤트 추천 → event-AI추천요청.puml, event-추천결과조회.puml -- [x] UFR-EVENT-040: 배포 채널 선택 → (최종승인에 포함) -- [x] UFR-EVENT-050: 최종 승인 및 배포 → event-최종승인및배포.puml -- [x] UFR-EVENT-060: 이벤트 상세 조회 → event-상세조회.puml -- [x] UFR-EVENT-070: 이벤트 목록 관리 → event-목록조회.puml -- [x] UFR-CONT-010: SNS 이미지 생성 → event-이미지생성요청.puml, event-이미지결과조회.puml -- [x] UFR-CONT-020: 콘텐츠 편집 → event-콘텐츠선택.puml - -### 외부 시퀀스 일치성 -- [x] Kafka Job 발행 (AI 추천) - ai-job 토픽 -- [x] Kafka Job 발행 (이미지 생성) - image-job 토픽 -- [x] Kafka Event 발행 (EventCreated) - event-topic -- [x] Distribution Service 동기 호출 (REST API) -- [x] Redis 캐싱 전략 (Cache-Aside) -- [x] Job 폴링 방식 (5초 간격 AI, 3초 간격 이미지) - -### 논리 아키텍처 일치성 -- [x] Event Service 책임 범위 -- [x] Kafka 통합 메시징 플랫폼 -- [x] Redis 캐시 키 패턴 -- [x] Database-per-Service 원칙 -- [x] Resilience 패턴 적용 - ---- - -## 파일 위치 - -``` -design/backend/sequence/inner/ -├── event-목적선택.puml -├── event-AI추천요청.puml -├── event-추천결과조회.puml -├── event-이미지생성요청.puml -├── event-이미지결과조회.puml -├── event-콘텐츠선택.puml -├── event-최종승인및배포.puml -├── event-상세조회.puml -├── event-목록조회.puml -└── event-대시보드조회.puml -``` - ---- - -## 다이어그램 확인 방법 - -### PlantUML 렌더링 -1. https://www.plantuml.com/plantuml/uml/ 접속 -2. 각 `.puml` 파일 내용 붙여넣기 -3. 다이어그램 시각적 확인 - -### 로컬 렌더링 (IntelliJ/VS Code) -- IntelliJ: PlantUML Integration 플러그인 설치 -- VS Code: PlantUML 확장 설치 - ---- - -## 주요 설계 결정사항 - -### 1. 비동기 처리 전략 -- **AI 추천**: Kafka ai-job 토픽 발행 → 비동기 처리 → Job 폴링 -- **이미지 생성**: Kafka image-job 토픽 발행 → 비동기 처리 → Job 폴링 -- **이유**: 장시간 작업 (10초, 5초)을 동기로 처리 시 사용자 경험 저하 - -### 2. 배포 동기 처리 -- **Distribution Service**: REST API 동기 호출 (POST /api/distribution/distribute) -- **이유**: 배포 완료 여부를 즉시 확인하고 사용자에게 피드백 제공 -- **Resilience**: Circuit Breaker + Timeout 70초 - -### 3. 캐싱 전략 -- **목적 선택**: TTL 30분 (임시 저장 성격) -- **상세 조회**: TTL 5분 (자주 조회, 실시간성 중요) -- **목록/대시보드**: TTL 1분 (실시간 업데이트) -- **이유**: 조회 빈도와 실시간성 요구사항에 따라 차등 적용 - -### 4. Job 상태 관리 -- **Redis 캐시**: Job 상태 및 결과 저장 (TTL 1시간) -- **폴링 방식**: 클라이언트가 주기적으로 Job 상태 확인 -- **이유**: 간단한 구현, WebSocket 대비 낮은 복잡도 - ---- - -## 성능 최적화 포인트 - -### 1. 캐시 히트율 -- 목적 선택: 90% 예상 (재방문 시 캐시 활용) -- 상세 조회: 95% 예상 (자주 조회) -- 목록/대시보드: 90% 예상 (1분 TTL로 대부분 캐시 활용) - -### 2. 데이터베이스 최적화 -- 인덱스: user_id, status, created_at -- JOIN 최적화: 상세 조회 시 관련 데이터 한 번에 조회 -- 페이지네이션: 20개/페이지로 쿼리 부하 감소 - -### 3. 병렬 처리 -- 대시보드 조회: 진행중/예정/종료 병렬 쿼리 -- 이미지 생성: 3가지 스타일 병렬 생성 (Content Service에서) - ---- - -## 향후 개선 방안 - -### Phase 2 이후 -1. **WebSocket 실시간 푸시**: Job 폴링을 WebSocket으로 전환 -2. **Event Sourcing**: 모든 상태 변경을 이벤트로 저장 -3. **GraphQL**: 클라이언트 맞춤형 데이터 조회 -4. **Database Read Replica**: 읽기 부하 분산 - ---- - -**문서 작성 완료일**: 2025-10-22 -**작성자**: System Architect -**상태**: ✅ 완료 (10개 시나리오 모두 작성) diff --git a/design/backend/sequence/외부내부시퀀스일관성분석.md b/design/backend/sequence/외부내부시퀀스일관성분석.md deleted file mode 100644 index bad8780..0000000 --- a/design/backend/sequence/외부내부시퀀스일관성분석.md +++ /dev/null @@ -1,505 +0,0 @@ -# 외부/내부 시퀀스 설계 일관성 분석 결과 - -**분석 일시**: 2025-10-22 -**분석 대상**: 외부 시퀀스 4개, 내부 시퀀스 25개 - ---- - -## 📋 Executive Summary - -### 전체 평가: ✅ **수정 완료** - -- ✅ **일치율**: 100% (전체 시퀀스 일치) -- ✅ **수정 완료**: 2건의 중대 불일치 모두 해결 -- ⚠️ **개선 사항**: 3건 (충돌 아님, 구현 향상) - ---- - -## 1. API 일관성 분석 - -### ✅ 일치하는 항목 - -#### 사용자 인증 플로우 -| 기능 | 외부 API | 내부 API | 상태 | -|------|----------|----------|------| -| 회원가입 | POST /api/users/register | POST /api/users/register | ✅ | -| 로그인 | POST /api/users/login | POST /api/users/login | ✅ | -| 로그아웃 | POST /api/users/logout | POST /api/users/logout | ✅ | - -#### 이벤트 생성 플로우 -| 기능 | 외부 API | 내부 API | 상태 | -|------|----------|----------|------| -| 목적 선택 | POST /events/purposes | POST /api/events/purposes | ✅ | -| AI 추천 요청 | POST /api/events/{id}/ai-recommendations | POST /api/events/{id}/ai-recommendations | ✅ | -| 이미지 생성 요청 | POST /api/events/{id}/content-generation | POST /api/events/{id}/content-generation | ✅ | -| 최종 승인 | POST /api/events/{id}/publish | POST /api/events/{id}/publish | ✅ | -| Job 상태 조회 | GET /jobs/{jobId}/status | GET /api/jobs/{jobId}/status | ✅ | - -#### 참여자 플로우 -| 기능 | 외부 API | 내부 API | 상태 | -|------|----------|----------|------| -| 이벤트 참여 | POST /api/v1/participations | POST /participations/register | ✅ | - -#### 성과 분석 플로우 -| 기능 | 외부 API | 내부 API | 상태 | -|------|----------|----------|------| -| 대시보드 조회 | GET /api/events/{id}/analytics | GET /api/events/{id}/analytics | ✅ | - ---- - -### ✅ 수정 완료 - -#### **이전 CRITICAL #1: 당첨자 추첨 API 엔드포인트 불일치 → ✅ 해결** - -**수정 내용** (2025-10-22): -- **외부 설계** 수정 완료 (고객참여플로우.puml, line 91): - ``` - 변경 전: POST /api/v1/participations/draw - 변경 후: POST /api/v1/events/{eventId}/draw-winners ✅ - ``` - -- **내부 구현** (participation-당첨자추첨.puml, line 17): - ``` - POST /api/v1/events/{eventId}/draw-winners ✅ - ``` - -**결과**: ✅ 외부/내부 API 엔드포인트 완전 일치 - ---- - -## 2. 서비스 간 호출 흐름 분석 - -### ✅ 일치하는 항목 - -#### 동기/비동기 처리 패턴 - -| 플로우 | 외부 설계 | 내부 구현 | 일치 여부 | -|--------|----------|-----------|-----------| -| 회원가입 - 사업자번호 검증 | 동기 (Circuit Breaker) | 동기 (Circuit Breaker) | ✅ | -| AI 추천 생성 | 비동기 (Kafka Job) | 비동기 (Kafka Job) | ✅ | -| 이미지 생성 | 비동기 (Kafka Job) | 비동기 (Kafka Job) | ✅ | -| 다중 채널 배포 | 동기 (REST API) | 동기 (REST API) | ✅ | -| 참여자 등록 | 동기 | 동기 | ✅ | -| 당첨자 추첨 | 동기 | 동기 | ✅ | - -#### 서비스 간 호출 순서 - -**이벤트 최종 승인 및 배포 플로우**: -``` -외부: -Event Service → Distribution Service (동기 REST) → Kafka DistributionCompleted - -내부: -Event Service → Distribution Service (동기 REST) → Kafka DistributionCompleted -``` -✅ **완벽 일치** - ---- - -### ❌ 불일치하는 항목 - -**없음** - 서비스 간 호출 흐름은 모두 일치 - ---- - -## 3. 데이터 흐름 분석 - -### ✅ 일치하는 항목 - -#### 회원가입 데이터 흐름 - -| 항목 | 외부 | 내부 | 일치 | -|------|------|------|------| -| 사업자번호 검증 캐시 | Redis, TTL 7일 | Redis, TTL 7일 | ✅ | -| 비밀번호 해싱 | bcrypt, Cost Factor 10 | bcrypt, Cost Factor 10 | ✅ | -| 사업자번호 암호화 | AES-256 | AES-256-GCM | ✅ | -| 트랜잭션 처리 | BEGIN → INSERT users, stores → COMMIT | BEGIN → INSERT users, stores → COMMIT | ✅ | -| JWT 토큰 | exp=7일 | exp=7일 | ✅ | -| Redis 세션 | TTL 7일 | TTL 7일 | ✅ | - -#### 참여자 등록 데이터 흐름 - -| 항목 | 외부 | 내부 | 일치 | -|------|------|------|------| -| 중복 체크 | DB 조회 | Redis 캐시 + DB 조회 | ⚠️ 향상 | -| 응모번호 생성 | UUID/시퀀스 | UUID: EVT-{timestamp}-{random} | ✅ | -| 참여 데이터 저장 | INSERT participants | INSERT participants | ✅ | -| 중복 체크 캐싱 | (없음) | Redis, TTL 7일 | ⚠️ 향상 | - -#### Analytics 대시보드 데이터 흐름 - -| 항목 | 외부 | 내부 | 일치 | -|------|------|------|------| -| Cache-Aside 패턴 | TTL 5분 | TTL 300초 (5분) | ✅ | -| 외부 API 병렬 호출 | 우리동네TV, 지니TV, SNS | 우리동네TV, 지니TV, SNS | ✅ | -| Circuit Breaker | 50% 실패율, 10초 Timeout | 50% 실패율, 10초 Timeout | ✅ | -| ROI 계산 | (수익 - 비용) / 비용 × 100 | (수익 - 비용) / 비용 × 100 | ✅ | - ---- - -### ❌ 불일치하는 항목 - -**없음** - 데이터 흐름 로직은 모두 일치 (일부 향상 포함) - ---- - -## 4. 이벤트 메시징 일관성 - -### ✅ 일치하는 항목 - -#### Kafka 이벤트 발행 - -| 이벤트 | 외부 Topic | 내부 Topic | 발행 서비스 | 일치 | -|--------|-----------|-----------|------------|------| -| EventCreated | event-topic | event-topic | Event Service | ✅ | -| ParticipantRegistered | participant-events | participant-events | Participation Service | ✅ | -| DistributionCompleted | event-topic | event-topic | Distribution Service | ✅ | -| EventDraftCreated | event-topic | event-topic | Event Service | ✅ | -| EventRecommended | event-topic | event-topic | AI Service (optional) | ✅ | -| ContentCreated | (폴링 방식) | (폴링 방식) | Content Service | ✅ | - -#### Kafka 이벤트 구독 - -| 이벤트 | 구독 서비스 | 외부 설계 | 내부 구현 | 일치 | -|--------|------------|----------|-----------|------| -| EventCreated | Analytics Service | ✅ 초기화 | ✅ 초기화 | ✅ | -| ParticipantRegistered | Analytics Service | ✅ participant_count 증가 | ✅ participant_count 증가 | ✅ | -| DistributionCompleted | Analytics Service | ✅ channel_stats 저장 | ✅ channel_stats 저장 | ✅ | -| ai-job | AI Service | ✅ 추천 생성 | ✅ 추천 생성 | ✅ | -| image-job | Content Service | ✅ 이미지 생성 | ✅ 이미지 생성 | ✅ | - ---- - -### ✅ 수정 완료 - -#### **이전 CRITICAL #2: WinnerSelected 이벤트 불일치 → ✅ 해결** - -**수정 내용** (2025-10-22): -- **외부 설계** 수정 완료 (고객참여플로우.puml, lines 121-139): - ``` - 변경 전: Kafka 이벤트 발행 및 Analytics 구독 포함 - 변경 후: Kafka 이벤트 발행 제거 ✅ - ``` - -- **내부 구현** (participation-당첨자추첨.puml): - ``` - Kafka 이벤트 발행 없음 (DB 저장만 수행) ✅ - ``` - -**설계 결정**: -- 당첨자 추첨은 실시간 이벤트 발행 없이 DB 저장만 수행 -- Analytics Service는 대시보드 조회 시 DB에서 당첨자 정보 조회 -- 실시간 업데이트 불필요 (추첨은 일회성 작업) - -**결과**: ✅ 외부/내부 Kafka 이벤트 처리 로직 완전 일치 - ---- - -## 5. 오류 처리 일관성 - -### ✅ 일치하는 항목 - -#### Circuit Breaker 설정 - -| 서비스 | 외부 API | 외부 설정 | 내부 설정 | 일치 | -|--------|---------|-----------|-----------|------| -| User Service | 국세청 API | 50% 실패율, 5초 Timeout | 50% 실패율, 5초 Timeout | ✅ | -| Analytics Service | 우리동네TV, 지니TV, SNS | 50% 실패율, 10초 Timeout | 50% 실패율, 10초 Timeout | ✅ | -| AI Service | External AI API | 50% 실패율, 30초 Timeout | 50% 실패율, 30초 Timeout | ✅ | -| Content Service | Stable Diffusion API | 50% 실패율, 20초 Timeout | 50% 실패율, 20초 Timeout | ✅ | - -#### Retry 정책 - -| 서비스 | 외부 설계 | 내부 구현 | 일치 | -|--------|----------|-----------|------| -| User Service (국세청) | 최대 3회, 지수 백오프 (1s, 2s, 4s) | 최대 3회, 지수 백오프 (1s, 2s, 4s) | ✅ | -| Analytics Service | 없음 (Circuit Breaker만) | 없음 (Circuit Breaker만) | ✅ | - -#### Fallback 전략 - -| 서비스 | 외부 Fallback | 내부 Fallback | 일치 | -|--------|--------------|--------------|------| -| User Service | 사업자번호 검증 스킵 (수동 확인 안내) | 사업자번호 검증 스킵 (수동 확인 안내) | ✅ | -| Analytics Service | 캐시된 이전 데이터 또는 기본값 (0) | 캐시된 이전 데이터 또는 기본값 (0) | ✅ | -| AI Service | 기본 트렌드 템플릿 사용 | 기본 트렌드 템플릿 사용 | ✅ | -| Content Service | DALL-E API → 기본 템플릿 | DALL-E API → 기본 템플릿 | ✅ | - -#### HTTP 상태 코드 - -| 상황 | 외부 | 내부 | 일치 | -|------|------|------|------| -| 중복 참여 | 409 Conflict | 409 Conflict | ✅ | -| 인증 실패 | 401 Unauthorized | 401 Unauthorized | ✅ | -| 사용자 없음 | 404 Not Found | 404 Not Found | ✅ | -| 유효성 오류 | 400 Bad Request | 400 Bad Request | ✅ | -| Job 생성 | 202 Accepted | 202 Accepted | ✅ | -| 성공 | 200 OK / 201 Created | 200 OK / 201 Created | ✅ | - ---- - -### ❌ 불일치하는 항목 - -**없음** - 오류 처리 정책은 모두 일치 - ---- - -## 6. 발견된 충돌 및 불일치 사항 요약 - -### ✅ 모든 불일치 수정 완료 (2025-10-22) - -#### 1. 당첨자 추첨 API 엔드포인트 불일치 → ✅ 해결 - -**파일**: -- 외부: `design/backend/sequence/outer/고객참여플로우.puml` -- 내부: `design/backend/sequence/inner/participation-당첨자추첨.puml` - -**수정 내용**: -``` -✅ 외부: POST /api/v1/events/{eventId}/draw-winners -✅ 내부: POST /api/v1/events/{eventId}/draw-winners -``` - -**결과**: 완전 일치 - ---- - -#### 2. WinnerSelected Kafka 이벤트 불일치 → ✅ 해결 - -**파일**: -- 외부: `design/backend/sequence/outer/고객참여플로우.puml` (lines 121-139 삭제됨) -- 내부: `design/backend/sequence/inner/participation-당첨자추첨.puml` - -**수정 내용**: -``` -✅ 외부: Kafka 이벤트 발행 제거 -✅ 내부: Kafka 이벤트 발행 없음 (DB 저장만) -``` - -**설계 결정**: -- 당첨자 추첨은 실시간 이벤트 불필요 (일회성 작업) -- Analytics는 대시보드 조회 시 DB에서 조회 - -**결과**: 완전 일치 - ---- - -### ⚠️ ENHANCEMENT - 충돌 아님, 구현 향상 (3건) - -#### 1. 로그아웃 시 JWT Blacklist 패턴 추가 - -**파일**: `design/backend/sequence/inner/user-로그아웃.puml` - -**향상 내용**: -- 외부: Redis 세션 삭제만 -- 내부: Redis 세션 삭제 + JWT Blacklist 추가 (TTL: 남은 만료 시간) - -**평가**: ✅ 보안 강화, 충돌 아님 - ---- - -#### 2. 참여자 중복 체크 Redis 캐싱 추가 - -**파일**: `design/backend/sequence/inner/participation-이벤트참여.puml` - -**향상 내용**: -- 외부: DB 조회만 -- 내부: Redis 캐시 조회 → 캐시 MISS 시 DB 조회 → 캐시 저장 (TTL 7일) - -**평가**: ✅ 성능 향상, 충돌 아님 - ---- - -#### 3. 멱등성 처리 강화 (모든 Kafka Consumer) - -**파일**: -- `analytics-이벤트생성구독.puml` -- `analytics-참여자등록구독.puml` -- `analytics-배포완료구독.puml` - -**향상 내용**: -- 외부: 멱등성 언급 없음 -- 내부: Redis Set으로 중복 처리 방지 (SISMEMBER 체크) - -**평가**: ✅ 안정성 향상, 충돌 아님 - ---- - -## 7. 개선 권장 사항 - -### ✅ 완료된 조치 (2025-10-22) - -1. **API 엔드포인트 통일** ✅ - - 외부 설계 수정 완료: `POST /api/v1/events/{eventId}/draw-winners` - - Frontend 호출 코드는 개발 시 반영 필요 - - API 문서 업데이트 필요 - -2. **WinnerSelected 이벤트 정렬** ✅ - - 외부 설계에서 Kafka 이벤트 발행 제거 - - 내부 구현 (DB 저장만)과 일치 - - 설계 일관성 확보 - ---- - -### 🟡 단기 개선 (우선순위 2) - -1. **외부 시퀀스에 구현 향상 사항 반영** - - 로그아웃 JWT Blacklist 패턴 문서화 - - 참여자 중복 체크 캐싱 전략 문서화 - - 멱등성 처리 패턴 명시 - -2. **일관성 검증 자동화** - - PlantUML 파싱 스크립트 작성 - - API 엔드포인트 자동 비교 도구 - - Kafka 이벤트 매핑 검증 도구 - ---- - -### 🟢 장기 개선 (우선순위 3) - -1. **설계 문서 동기화 프로세스** - - 외부 → 내부 설계 변경 시 상호 검토 필수화 - - 설계 변경 체크리스트 도입 - - 주기적 일관성 검증 (Sprint 종료 시) - -2. **테스트 자동화** - - API Contract Testing (Pact, Spring Cloud Contract) - - Kafka Event Schema Registry 도입 - - E2E 통합 테스트 강화 - ---- - -## 8. 종합 평가 - -### ✅ 긍정적 측면 (수정 후) - -1. ✅ **완벽한 일관성**: 전체 100% 일치율 달성 -2. ✅ **견고한 Resilience 패턴**: Circuit Breaker, Retry, Fallback 일관성 -3. ✅ **명확한 데이터 흐름**: 캐시 전략, 트랜잭션 처리 일관성 -4. ✅ **이벤트 주도 아키텍처**: 모든 Kafka 이벤트 완전 일치 -5. ✅ **보안 강화**: 내부 구현이 외부 설계보다 보안 강화 -6. ✅ **신속한 문제 해결**: 발견된 불일치 사항 즉시 수정 완료 - -### ⚠️ 주의 사항 - -1. ⚠️ **Frontend 개발 시**: 수정된 API 엔드포인트 반영 필요 - - `POST /api/v1/events/{eventId}/draw-winners` -2. ⚠️ **문서 동기화**: 구현 향상 사항을 외부 설계에 반영 권장 -3. ⚠️ **지속적 검증**: 설계 변경 시 상호 검토 프로세스 필요 - -### 최종 권고사항 - -1. **✅ 완료**: 2건의 CRITICAL 이슈 모두 해결 완료 - - 소요 시간: 1시간 - - 담당: System Architect - -2. **🟡 진행 중**: 문서 업데이트 및 개발 반영 - - Frontend 개발 시 수정된 API 엔드포인트 사용 - - API 명세서 업데이트 필요 - -3. **🟢 장기 과제**: 검증 자동화 도구 도입 - - 예상 소요 시간: 1주 - - 담당: DevOps Team - ---- - -## 9. 체크리스트 - -### ✅ 완료된 수정 (2025-10-22) - -- [x] **외부 설계 수정**: 고객참여플로우.puml - API 엔드포인트 변경 ✅ -- [x] **외부 설계 수정**: 고객참여플로우.puml - WinnerSelected Kafka 이벤트 제거 ✅ -- [x] **PlantUML 문법 검사**: 외부 시퀀스 파일 문법 검증 완료 ✅ -- [x] **일관성 분석 문서**: 수정 내용 반영 완료 ✅ - -### ⏳ 개발 시 반영 필요 - -- [ ] **Frontend 코드**: 당첨자 추첨 API 호출 엔드포인트 변경 - - 기존: `POST /api/v1/participations/draw` - - 신규: `POST /api/v1/events/{eventId}/draw-winners` -- [ ] **API 문서**: 당첨자 추첨 API 엔드포인트 문서 업데이트 -- [ ] **통합 테스트**: 수정된 API 엔드포인트 E2E 테스트 - -### 검증 체크리스트 - -- [ ] **API 엔드포인트**: 외부/내부 일치 확인 -- [ ] **Kafka 이벤트**: 모든 발행/구독 매핑 확인 -- [ ] **데이터 흐름**: 캐시, DB, 외부 API 호출 일관성 확인 -- [ ] **오류 처리**: Circuit Breaker, Retry, Fallback 일치 확인 -- [ ] **통합 테스트**: E2E 시나리오 실행 및 검증 - ---- - -## 부록 - -### A. 분석 대상 파일 목록 - -#### 외부 시퀀스 (4개) -1. `design/backend/sequence/outer/고객참여플로우.puml` -2. `design/backend/sequence/outer/사용자인증플로우.puml` -3. `design/backend/sequence/outer/성과분석플로우.puml` -4. `design/backend/sequence/outer/이벤트생성플로우.puml` - -#### 내부 시퀀스 (25개) -1. `user-로그인.puml` -2. `user-로그아웃.puml` -3. `user-회원가입.puml` -4. `user-프로필수정.puml` -5. `event-목적선택.puml` -6. `event-AI추천요청.puml` -7. `event-추천결과조회.puml` -8. `event-이미지생성요청.puml` -9. `event-이미지결과조회.puml` -10. `event-콘텐츠선택.puml` -11. `event-최종승인및배포.puml` -12. `event-상세조회.puml` -13. `event-목록조회.puml` -14. `event-대시보드조회.puml` -15. `participation-이벤트참여.puml` -16. `participation-당첨자추첨.puml` -17. `participation-참여자목록조회.puml` -18. `analytics-대시보드조회.puml` -19. `analytics-이벤트생성구독.puml` -20. `analytics-참여자등록구독.puml` -21. `analytics-배포완료구독.puml` -22. `distribution-다중채널배포.puml` -23. `distribution-배포상태조회.puml` -24. `content-이미지생성.puml` -25. `ai-트렌드분석및추천.puml` - -### B. Kafka 이벤트 매핑표 - -| 이벤트 | Topic | Publisher | Subscriber | 외부 | 내부 | -|--------|-------|-----------|-----------|------|------| -| EventCreated | event-topic | Event Service | Analytics Service | ✅ | ✅ | -| ParticipantRegistered | participant-events | Participation Service | Analytics Service | ✅ | ✅ | -| DistributionCompleted | event-topic | Distribution Service | Analytics Service | ✅ | ✅ | -| ~~WinnerSelected~~ | ~~participant-events~~ | ~~Participation Service~~ | ~~Analytics Service~~ | ~~제거됨~~ | ~~없음~~ | -| EventDraftCreated | event-topic | Event Service | (optional) | ✅ | ✅ | -| EventRecommended | event-topic | AI Service | (optional) | ✅ | ✅ | - -**비고**: WinnerSelected 이벤트는 설계 결정에 따라 외부 설계에서 제거되었습니다. 당첨자 정보는 DB 저장 후 대시보드 조회 시 확인 가능합니다. - -### C. API 엔드포인트 전체 목록 - -| 서비스 | 메서드 | 엔드포인트 | 외부 | 내부 | -|--------|--------|-----------|------|------| -| User | POST | /api/users/register | ✅ | ✅ | -| User | POST | /api/users/login | ✅ | ✅ | -| User | POST | /api/users/logout | ✅ | ✅ | -| Event | POST | /api/events/purposes | ✅ | ✅ | -| Event | POST | /api/events/{id}/ai-recommendations | ✅ | ✅ | -| Event | POST | /api/events/{id}/content-generation | ✅ | ✅ | -| Event | POST | /api/events/{id}/publish | ✅ | ✅ | -| Event | GET | /api/jobs/{jobId}/status | ✅ | ✅ | -| Participation | POST | /api/v1/participations | ✅ | ✅ | -| Participation | POST | /api/v1/events/{eventId}/draw-winners | ✅ | ✅ | -| Analytics | GET | /api/events/{id}/analytics | ✅ | ✅ | -| Distribution | POST | /api/distribution/distribute | ✅ | ✅ | - -**비고**: 당첨자 추첨 API 엔드포인트가 `/api/v1/events/{eventId}/draw-winners`로 통일되었습니다 (2025-10-22). - ---- - -**작성자**: System Architect -**검토자**: Backend Team Lead, Frontend Team Lead -**승인자**: PO, Scrum Master From 74d03fd4bf99fd335063cb644722253144b467d7 Mon Sep 17 00:00:00 2001 From: wonho Date: Thu, 23 Oct 2025 17:17:53 +0900 Subject: [PATCH 2/2] =?UTF-8?q?User=20Service=20API=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EC=82=AC=EC=97=85=EC=9E=90=EB=93=B1=EB=A1=9D=EB=B2=88=ED=98=B8?= =?UTF-8?q?=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 회원가입 API에서 businessNumber 필드 제거 - API 설명에서 사업자번호 검증 관련 내용 제거 - RegisterRequest 스키마에서 businessNumber required 및 property 제거 - 회원가입 예시에서 businessNumber 제거 - 사업자번호 검증 실패 에러 케이스 제거 - USER_002 에러 코드 제거 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- design/backend/api/user-service-api.yaml | 27 ++++-------------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/design/backend/api/user-service-api.yaml b/design/backend/api/user-service-api.yaml index 75832d1..4bf6415 100644 --- a/design/backend/api/user-service-api.yaml +++ b/design/backend/api/user-service-api.yaml @@ -7,7 +7,7 @@ info: 사용자 인증 및 매장정보 관리를 담당하는 마이크로서비스 **주요 기능:** - - 회원가입 (사업자번호 검증 포함) + - 회원가입 - 로그인/로그아웃 - 프로필 조회 및 수정 - 비밀번호 변경 @@ -15,7 +15,6 @@ info: **보안:** - JWT Bearer 토큰 기반 인증 - bcrypt 비밀번호 해싱 - - AES-256-GCM 사업자번호 암호화 version: 1.0.0 contact: name: Digital Garage Team @@ -48,17 +47,14 @@ paths: **주요 기능:** - 기본 정보 및 매장 정보 등록 - - 사업자번호 검증 (국세청 API 연동) - 비밀번호 bcrypt 해싱 - JWT 토큰 자동 발급 **처리 흐름:** 1. 중복 사용자 확인 (전화번호 기반) - 2. 사업자번호 검증 (국세청 API, Circuit Breaker 패턴) - 3. 비밀번호 해싱 (bcrypt) - 4. 사업자번호 암호화 (AES-256-GCM) - 5. User/Store 데이터베이스 트랜잭션 처리 - 6. JWT 토큰 생성 및 세션 저장 (Redis) + 2. 비밀번호 해싱 (bcrypt) + 3. User/Store 데이터베이스 트랜잭션 처리 + 4. JWT 토큰 생성 및 세션 저장 (Redis) operationId: registerUser x-user-story: UFR-USER-010 x-controller: UserController @@ -80,7 +76,6 @@ paths: industry: 음식점 address: 서울시 강남구 테헤란로 123 businessHours: "월-금 11:00-22:00, 토-일 12:00-21:00" - businessNumber: "1234567890" cafe: summary: 카페 회원가입 예시 value: @@ -92,7 +87,6 @@ paths: industry: 카페 address: 서울시 서초구 서초대로 456 businessHours: "매일 09:00-20:00" - businessNumber: "9876543210" responses: '201': description: 회원가입 성공 @@ -122,12 +116,6 @@ paths: code: USER_001 message: 이미 가입된 전화번호입니다 timestamp: 2025-10-22T10:30:00Z - invalidBusinessNumber: - summary: 사업자번호 검증 실패 - value: - code: USER_002 - message: 유효하지 않은 사업자번호입니다. 휴폐업 여부를 확인해주세요. - timestamp: 2025-10-22T10:30:00Z validationError: summary: 입력 검증 오류 value: @@ -610,7 +598,6 @@ components: - storeName - industry - address - - businessNumber properties: name: type: string @@ -657,11 +644,6 @@ components: maxLength: 200 description: 영업시간 (선택 사항) example: "월-금 11:00-22:00, 토-일 12:00-21:00" - businessNumber: - type: string - pattern: '^\d{10}$' - description: 사업자번호 (10자리 숫자) - example: "1234567890" RegisterResponse: type: object @@ -990,7 +972,6 @@ components: example: USER_001 enum: - USER_001 # 중복 사용자 - - USER_002 # 사업자번호 검증 실패 - USER_003 # 사용자 없음 - USER_004 # 현재 비밀번호 불일치 - USER_005 # 동시성 충돌