1. 개요

안녕하세요! DoEatFit (v2.0) 프로젝트의 든든한 기술적 뼈대이자, 전체 인프라와 소프트웨어 계층 간의 유기적 통신 흐름을 설계도와 함께 친근하게 설명해 드리는 기술 아키텍처 가이드북입니다.

DoEatFit은 사용자의 식단(Diet)과 운동(Workout) 정보를 통합 분석하여 맞춤형 헬스케어 피드백을 제공하는 프리미엄 서비스예요. 모바일 PWA 환경과 분산 인프라 스트럭처의 강력한 시너지를 내기 위해, WAS 레이어뿐만 아니라 DNS 보안, 고성능 캐싱, 초고속 검색 엔진, 오브젝트 스토리지까지 다채롭고 견고한 모던 아키텍처를 도입했답니다. 이 가이드를 통해 복잡한 시스템 요소를 손쉽게 이해하고, 더욱 탄탄한 시스템 개발에 나설 수 있도록 도와드릴게요.


2. 핵심 내용

2-1. 🏛️ 전체 시스템 구성 및 핵심 인프라 요소

DoEatFit v2.0은 외부의 위협으로부터 서비스를 철벽 수호하고 글로벌 사용자에게 균일한 퍼포먼스를 제공하기 위해 Cloudflare CDN 및 봇 방어 레이어를 입구에 배치했으며, 각각의 인프라 환경을 독립적인 Proxmox LXC 컨테이너 환경으로 격리하여 운영 안정성을 확보했어요. 먼저 시스템 흐름을 직관적으로 보여주는 전체 시스템 아키텍처 설계도를 함께 살펴보실까요?

flowchart TD
     네트워크 보안 및 CDN 영역
    subgraph Cloudflare [🛡️ Cloudflare]
        DNS[DNS / SSL]
        CDN[Edge Caching]
        Turnstile[Turnstile Bot Protection]
    end

     데이터 저장소 및 캐싱 영역
    subgraph DataStorage [💾 Data Infrastructure]
        MySQL[(MySQL \nRDBMS)]
        Redis[(Redis \nCache & Token)]
        MinIO[(MinIO \nObject Storage)]
        Meilisearch[(Meilisearch \nSearch Engine)]
    end

     연결 관계
    User -->|웹 브라우저 접근| DNS
    DNS --> CDN
    CDN --> Client
    
    Client -->|API Request| Turnstile
    Turnstile -.->|인증 검증| API
    Client <==>|HTTPS / REST API| API
    
    API <-->|읽기/쓰기| MySQL
    API <-->|토큰/세션/캐시| Redis
    API <-->|이미지 업로드/다운로드| MinIO
    API <-->|초고속 전문 검색| Meilisearch
    
    API -->|메일 전송 요청| SMTP
    SMTP -.->|회원가입/비번찾기| User
    
    Batch -->|음식/영양소 동기화| OpenAPI
    OpenAPI -.->|Data| Batch
    Batch -->|인덱싱| Meilisearch

전체 시스템을 안전하게 구동해 주는 핵심 인프라 요소들의 기술 명세를 친절히 요약해 드릴게요.

  • Cloudflare (글로벌 보안 & CDN): 도메인(doeatfit.org)의 DNS 통제와 글로벌 엣지 캐싱 및 SSL 오프로딩을 지원해요. 특히 Turnstile 봇 방어 기술을 도입하여, 사용자에게 무겁고 짜증 나는 CAPTCHA 인증 과정을 요구하지 않으면서도 스팸 봇과 무차별 Brute-Force 공격을 지능적으로 차단하고 있답니다.
  • Next.js Frontend (BFF & PWA 레이어): 사용자에게 부드럽고 미려한 인터페이스를 전송해 주는 프론트엔드 계층이에요. React Query 기반 상태 캐싱을 탑재했으며, 뒤에서 다룰 JWT Access Token을 헤더에 탑재해 안전하게 API와 교신한답니다.
  • Spring Boot WAS (도메인 중심 비즈니스 API): 비즈니스 트랜잭션 무결성과 데이터의 영속성, 정밀한 권한 통제를 총괄하는 든든한 등대 같은 백엔드 계층이에요. Trace ID를 로그 전반에 주입하여 분산 인프라 디버깅이 무척 쾌적하게 구성되어 있죠.
  • MySQL & Redis (다중 계층 저장 인프라): 영구적인 회원 정보 및 코칭 데이터는 RDBMS인 MySQL 8.0에서 엄격히 영속화하고, 실시간 토큰 관리와 회원가입 시 TTL(만료 시간)이 필수적인 이메일 인증 코드는 메모리 기반 초고속 데이터 스토어인 Redis가 효율적으로 분담 처리하도록 나누었답니다.
  • Meilisearch & MinIO (검색 엔진 및 미디어 스토어): 수만 건의 식품 영양 데이터와 운동 목록을 밀리초 단위로 초고속 오타 교정 검색해 주는 Meilisearch와, 식단 사진 및 운동 가이드 영상을 S3 호환 규격으로 저장하고 관리하는 MinIO 오브젝트 스토리지가 백엔드의 성능 병목을 기적적으로 제거해 줍니다.

2-2. 🔄 프론트/백엔드 아키텍처 표준화 및 Facade 설계 사상

시스템 구조가 복잡해질수록 결합도(Coupling)를 낮추고 각 모듈의 자율성을 높이는 디자인 패턴이 매우 중요해집니다. DoEatFit v2.0은 이를 위해 프론트엔드와 백엔드 모두에 비즈니스 로직을 감싸 안는 Facade 패턴을 일관되게 활용하고 있습니다.

  • 백엔드 계층형 아키텍처와 Facade 패턴:
    • Controller Layer: @Valid 기반 요청 검증과 통일된 공통 포맷(ApiResponse) 반환을 전담해요.
    • Facade Service Layer: 복잡하고 거대한 비즈니스 시나리오는 Facade 패턴으로 감싸 처리한답니다. 예를 들어 운동 일지 기록 시 호출되는 WorkoutService는 단순 데이터 영속을 넘어 영상 미디어를 처리하는 S3Service, 검색 결과를 갱신하는 WorkoutSearchService(Meilisearch) 등 여러 결합된 하위 서비스를 총 조율하는 Facade 역할을 똑똑하게 수행해 줍니다.
    • Repository/Domain Layer: 엔티티 클래스와 QueryDSL 기반 복합 쿼리 저장소를 명확히 분리하여 무결성을 유지하죠.
  • 프론트엔드 폴더 컨벤션과 Custom Hook (Logic Facade):
    • apis/: 순수한 Axios API 호출 통신 함수들만 함수형으로 정의해 두는 곳이에요.
    • hooks/ (Logic Facade): 프론트엔드의 진정한 백미라고 할 수 있는 부분이에요. 복잡한 클라이언트 상태와 LocalStorage 임시 저장 관리, 비즈니스 데이터 정합성 체크와 같은 두터운 비즈니스 흐름을 Custom Hook이라는 거대한 Facade 껍질 내부에 캡슐화해 둔답니다. 덕분에 실제 UI 코드가 모여 있는 components/는 오직 선언적인 렌더링에만 순수하게 집중할 수 있게 되었어요.
  • 아키텍처 공통 철학:
    • UUID 외부 노출: DB 자동 생성 식별자(PK)를 외부에 그대로 노출하면 데이터의 규모가 유추되는 등 보안 리스크가 발생하므로, 외부 통신 및 라우팅 식별자로는 무조건 무작위 UUID 필드를 사용하도록 강제했어요.
    • TimeStampEntity 상속: 모든 영속 엔티티는 시간 감사(Audit) 필드를 지닌 base 엔티티를 상속받아 등록/수정 시간을 프레임워크 수준에서 안정적으로 기록합니다.

2-3. 🚀 차세대 기술 도입 제안 및 추천 라이브러리 검토

DoEatFit v2.0이 차세대 엔터프라이즈급 헬스케어 플랫폼으로 한 단계 더 성장하기 위해, 로드맵에 맞추어 도입을 면밀하게 검토할 만한 차세대 핵심 라이브러리 및 도구들을 솔직하게 소개해 드릴게요.

  1. Zod (런타임 타입 안정성 확보)
    • 평가 및 제안: TypeScript는 훌륭하지만 컴파일 단계에서만 정적 검증을 거칠 뿐, 실제 실행 중인(Runtime) 브라우저에 백엔드 API의 예기치 못한 스펙 변경이 안착하면 화면이 하얗게 굳어버리는 런타임 크래시를 유발해요. 클라이언트가 API 응답을 받는 즉시 Zod 스키마(z.object)로 타입 파싱을 해줌으로써 방어적인 방어막을 형성하길 강력히 제안해요.
  2. Zustand (초경량 상태 관리 및 오프라인 자동 복구)
    • 평가 및 제안: 기존의 Redux Toolkit은 보일러플레이트 코드가 너무 두터워 유지보수 생산성을 저하하는 아쉬움이 있어요. 단 한 줄의 보일러플레이트 없이도 간결한 코드로 스토어를 설계할 수 있는 Zustand 도입을 추천합니다. 특히 운동 세트 기록이나 타이머 작동 등 휘발성이 높지만 중간 저장이 필수인 데이터에 persist 미들웨어를 함께 가동해주면, 갑자기 네트워크가 끊겨 앱이 꺼지더라도 로컬 IndexedDB에서 기존 운동 기록을 유실 없이 자동으로 복구하는 오프라인 우선(Offline-First) 개발 환경을 눈부시게 이룩해 낼 수 있답니다.
  3. Firebase & Service Worker (PWA 통신 한계 극복)
    • 평가 및 제안: 웹 기반 PWA의 고질적인 약점인 “백그라운드 통신 불가 및 리마인더 차단”을 극복하기 위해 FCM(Firebase Cloud Messaging) 웹 푸시 수신기와 next-pwa 서비스 워커 결합을 추천해 드립니다. 체육관 지하철 등 전파 음영 지역에서 로컬 캐시 자원으로 화면을 즉각 로딩하고, 백그라운드 푸시 알람을 통해 주기적인 수분 섭취 알림 및 운동 리마인드를 사용자 브라우저에 직접 속사포로 쏠 수 있게 해주어 서비스 리텐션율을 획기적으로 상승시켜 준답니다.
  4. MapStruct & Resilience4j (백엔드 코드 품질 및 복원력 향상)
    • 평가 및 제안: 현재 수동으로 처리되고 있는 번거로운 Entity-to-DTO 클래스 매핑에 MapStruct 컴파일 어노테이션 프로세서를 도입하여 개발자 생산성을 올려보세요. 또한, Meilisearch 검색 엔진이나 MinIO 미디어 스토어가 예기치 않은 시스템 점검으로 잠시 응답을 멈출 때, 전체 WAS가 다 같이 죽어버리는 전파 장애(Cascading Failure)를 차단하기 위해 Resilience4j 서킷 브레이커를 도메인 경계면에 장착하여 복원력을 철벽 확보하시기를 적극 제안해 드립니다.