**CareCode Interface (맘편한)**는 부모를 위한 통합 육아 지원 플랫폼으로, 전통적인 계층형 아키텍처 위에 도메인 주도 설계(DDD)와 AOP 기반 공통 모듈을 결합한 구조를 가지고 있습니다.
- 애플리케이션 계층 구조
- Presentation:
controller, 전역 예외 핸들러, API 응답 래퍼 - Application: 각 도메인의
facade/app패키지 (유스케이스 오케스트레이션) - Domain: 도메인 서비스, 엔티티, DTO, 도메인별 예외
- Infrastructure: JPA
repository, 외부 API 클라이언트, Redis, 설정(config)
- Presentation:
flowchart TB
Client[[Web / Mobile Client]]
subgraph Presentation["Presentation Layer"]
Controller["REST Controllers"]
GlobalException["Exception Handlers\n(ApiResponse / ErrorResponse)"]
end
subgraph Application["Application Layer"]
Facade["Facades / app 패키지\n(Use Case Orchestration)"]
end
subgraph Domain["Domain Layer"]
Services["Domain Services"]
Entities["Entities & Value Objects"]
DTOs["DTOs"]
DomainExceptions["Domain Exceptions"]
end
subgraph Infrastructure["Infrastructure Layer"]
Repos["JPA Repositories"]
ExternalApis["외부 API Clients\n(공공 데이터, OAuth2 등)"]
Redis["Redis (Cache / RateLimit)"]
Config["Config, Security, AOP, Util"]
end
subgraph Data["Data Stores"]
MariaDB[("MariaDB")]
RedisStore[("Redis")]
end
Client --> Controller
Controller --> Facade
Facade --> Services
Services --> Repos
Services --> ExternalApis
Repos --> MariaDB
Redis --> RedisStore
Services --> Redis
Services --> Config
GlobalException -. cross-cutting .- Controller
-
엔트리 포인트
com.carecode.CareCodeApplication- Spring Boot 3.3 기반 단일 모듈 API 서버
-
코어 공통 모듈 (
com.carecode.core)annotation:@LogExecutionTime,@RateLimit,@RequireAuthentication,@RequireAdminRole,@ValidateLocation,@ValidateChildAge,@CacheableResult등 공통 어노테이션aspect: 로깅, 캐싱, 인증, 검증, Rate Limiting을 AOP로 분리config:ApiConfig,ApiVersionConfig,AuditConfig,CacheConfig,CorsConfig,RedisConfig,SwaggerConfig,TransactionConfig,WebMvcConfig등 인프라/크로스컷팅 설정exception:CareCodeException,BusinessException, 도메인별 예외,ErrorCodeenumhandler:ApiResponse,ApiSuccess,ErrorResponse,CustomizedResponseEntityExceptionHandler등 전역 응답/예외 처리security: JWT 기반 인증,SecurityConfig,CustomUserDetailsService,JwtAuthenticationFilterutil:LoggingUtil,ValidationUtil,SortUtil,ChildAgeUtil,LocationUtil,RequestMapper,ResponseMapper등 재사용 유틸
-
도메인 계층 (
com.carecode.domain)user: 회원/자녀/알림 설정, 소셜 로그인, JWT 발급careFacility: 어린이집/유치원/돌봄시설 조회·예약·리뷰community: 게시글, 댓글, 태그, 좋아요, 북마크, 카테고리health: 건강 기록, 병원, 리뷰, 통계, 첨부파일policy: 육아 정책/카테고리/문서, 맞춤형 정책 추천notification: 알림 템플릿/이력/전략, 채널(이메일 등)chatbot: 세션, 메시지, 컨텍스트 기반 상담admin: 관리자용 사용자/콘텐츠/정책/통계 관리
각 도메인은 controller, app(또는 facade), service, repository, entity, dto로 구성되어 있어 도메인 경계를 기준으로 한 계층형 구조를 따릅니다.
-
클라이언트
- Web/Mobile 클라이언트가 HTTP/HTTPS로 Nginx에 접속
-
API 서버 (Spring Boot)
- 포트 8080에서 동작하며 Nginx 뒤에 배치
- JWT 기반 인증, 도메인별 REST API 제공
- SpringDoc OpenAPI를 이용한 Swagger UI 제공
-
데이터 저장소
- MariaDB: 핵심 비즈니스 데이터(사용자, 자녀, 건강 기록, 정책, 커뮤니티 등)
- Redis: 캐싱 + Rate Limiting을 위한 인메모리 저장소
-
외부 시스템
- 카카오/구글 OAuth2: 소셜 로그인
- 공공 데이터 API: 돌봄 시설/정책 정보
- 이메일 서비스: 인증 및 알림 메일 발송
Docker/Docker Compose로 MariaDB(3307), Redis(6380), Nginx, Spring Boot 애플리케이션을 하나의 스택으로 구성할 수 있도록 설계되어 있습니다.
flowchart LR
Client["Client\n(Web / Mobile)"]
Nginx["Nginx\n(80/443)"]
Api["Spring Boot API\n(8080)"]
MariaDB[("MariaDB\n3307")]
Redis[("Redis\n6380")]
subgraph External["External Services"]
Kakao["Kakao OAuth2"]
Google["Google OAuth2"]
PublicApi["공공 데이터 API\n(정책/돌봄 시설)"]
Mail["Email Service"]
end
Client --> Nginx --> Api
Api --> MariaDB
Api --> Redis
Api --> Kakao
Api --> Google
Api --> PublicApi
Api --> Mail
애플리케이션은 AWS EC2 위에서 Docker / Docker Compose를 사용해 실행되며, GitHub Actions를 통해 CI/CD가 구성되어 있습니다. 공공데이터 크롤러는 Redis를 인메모리 저장소로 사용하여 실시간으로 데이터를 갱신합니다.
flowchart TB
subgraph CI_CD["CI/CD (요약)"]
Dev["Developer"]
GitHub["GitHub Repo"]
Actions["GitHub Actions\nPipeline"]
Dev --> GitHub --> Actions --> EC2["EC2 (Docker Host)"]
end
subgraph Runtime["EC2 내 docker-compose Stack"]
Nginx["Nginx\n(리버스 프록시)"]
App["carecode-api\n(Spring Boot)"]
DB[("MariaDB")]
Redis[("Redis\n캐시 + 공공데이터 인메모리")]
Crawler["Public Data Crawler\n(공공데이터 수집)"]
end
Client["Clients\n(Web/Mobile)"] --> Nginx --> App
App --> DB
App --> Redis
PublicAPIs["공공데이터 API"] --> Crawler --> Redis
Redis -->|실시간 조회/캐시| App
프로젝트는 육아 서비스의 주요 영역을 기준으로 7+1개의 도메인으로 나뉩니다.
-
User 도메인
- 엔티티:
User,Child,EmailVerificationToken,NotificationSettings등 - 기능: 회원가입/로그인, 소셜 로그인, 토큰 갱신, 자녀 관리, 알림 설정
- 엔티티:
-
CareFacility 도메인
- 엔티티:
CareFacility,CareFacilityBooking,Review,FacilityType - 기능: 시설 검색(유형/지역/연령), 위치 기반 검색, 예약, 리뷰
- 엔티티:
-
Community 도메인
- 엔티티:
Post,Comment,Tag,PostLike,Bookmark,PostCategory등 - 기능: 게시글 CRUD, 댓글/대댓글, 태그, 좋아요/북마크, 익명 게시
- 엔티티:
-
Health 도메인
- 엔티티:
HealthRecord,HealthRecordAttachment,Hospital,HospitalReview,HospitalLike - 기능: 건강 기록/성장 추적, 병원 검색/리뷰, 통계/시각화
- 엔티티:
-
Policy 도메인
- 엔티티:
Policy,PolicyCategory,PolicyDocument - 기능: 정책 검색, 카테고리별 조회, 맞춤형 정책 추천, 공공 데이터 연동
- 엔티티:
-
Notification 도메인
- 엔티티:
Notification,NotificationTemplate,NotificationPreference,NotificationSettings - 기능: 실시간 알림, 다중 채널(이메일/푸시/SMS), 알림 이력/야간 모드
- 엔티티:
-
Chatbot 도메인
- 엔티티:
ChatSession,ChatMessage - 기능: 24/7 상담, 다중 세션, 히스토리 관리, 컨텍스트 기반 질의응답
- 엔티티:
-
Admin 도메인
- 기능: 사용자 관리, 시설/병원/정책 데이터 관리, 커뮤니티 모니터링, 대시보드
각 도메인은 자체 예외 타입, DTO, 서비스 로직을 가지며, 코어 모듈에서 제공하는 공통 인프라를 사용하도록 설계되어 있습니다.
flowchart TB
subgraph Core["Core (공통 인프라)"]
CoreAnnotation["annotation"]
CoreAspect["aspect"]
CoreConfig["config"]
CoreException["exception"]
CoreHandler["handler"]
CoreSecurity["security"]
CoreUtil["util"]
end
subgraph Domains["Domain Modules"]
User["user\n(사용자/자녀/알림 설정)"]
CareFacility["careFacility\n(돌봄 시설)"]
Community["community\n(커뮤니티)"]
Health["health\n(건강 관리)"]
Policy["policy\n(정책 정보)"]
Notification["notification\n(알림 시스템)"]
Chatbot["chatbot\n(AI 챗봇)"]
Admin["admin\n(관리자 기능)"]
end
Core --> User
Core --> CareFacility
Core --> Community
Core --> Health
Core --> Policy
Core --> Notification
Core --> Chatbot
Core --> Admin
- 어노테이션
@LogExecutionTime: 메서드 실행 시간을 측정하고 로깅
- Aspect
LoggingAspectStopWatch로 실행 시간 측정MDC에traceId,method,executionTime,error등을 기록warnThreshold초과 시 경고 로그- 인자 로깅 시 길이/민감정보를 일부 마스킹
이를 통해, 성능 모니터링과 문제 추적이 코드 침투 없이 가능하도록 구현되어 있습니다.
- 어노테이션
@RateLimit(requests, windowSeconds, perUser, message)
- Aspect
RateLimitingAspectConcurrentHashMap+AtomicInteger를 활용한 인메모리 Rate LimitingperUser=true일 경우 IP 기반 키 구성 (X-Forwarded-For 헤더 고려)- 윈도우 단위로 요청 수를 리셋하고, 초과 시
BusinessException발생
로그인 시도, 쓰기 API 등에서 간단하지만 실용적인 Rate Limiting을 제공하여 보안과 남용 방지에 기여합니다.
-
설정 (
RedisConfig)- 문자열 전용
RedisTemplate<String, String>: Rate Limiting, 단순 카운팅 등 - 객체 전용
RedisTemplate<String, Object>: JSON 직렬화를 통한 객체 캐싱
- 문자열 전용
-
어노테이션 & Aspect
@CacheableResult(cacheName, key, ttl)+CachingAspect- 메서드 시그니처/인자 기반으로 캐시 키 생성
- Redis에 JSON 문자열로 저장
- 리플렉션으로 메서드 반환 타입을 분석해 역직렬화
- 역직렬화 실패 시 캐시 삭제 후 재생성
기본 Spring Cache 추상화 외에, 세밀한 키/TTL 제어를 위한 커스텀 캐싱 레이어를 제공하는 것이 특징입니다.
-
예외 계층
CareCodeException(공통 베이스)- 도메인별 예외:
HealthRecordNotFoundException,ChildNotFoundException,HospitalNotFoundException등 ErrorCodeenum: 도메인별 코드와 기본 메시지를 보유
-
전역 핸들러
CustomizedResponseEntityExceptionHandlerCareCodeException을 일관된ErrorResponse로 변환- HTTP Status, 에러 코드, 메시지, 타임스탬프 등을 표준화
-
공통 응답 래퍼
ApiResponse<T>- 성공/실패 응답을 동일한 스키마(
code,message,data,timestamp)로 제공
- 성공/실패 응답을 동일한 스키마(
이를 통해, 클라이언트는 모든 도메인에서 동일한 에러/응답 포맷을 기대할 수 있으며, 모니터링/로깅 시스템과의 연계도 쉬워집니다.
-
환경별 설정 분리
application.yml: 공통 기본 설정 및 프로파일 설정application-dev.yml: 개발 환경 (상세 로그, H2 또는 개발 DB, 편의 옵션)application-prod.yml: 프로덕션 (최소 로그 레벨, 외부 DB, 보안 옵션)application-docker.yml: Docker Compose 환경용 설정
-
주요 설정 포인트
- 데이터베이스: MariaDB 연결 및 커넥션 풀
- 캐시:
CacheConfig를 통한 캐시 이름/TTL 정의 - 로깅:
logback-spring.xml+logstash-logback-encoder를 통한 JSON 로깅 - 모니터링: Actuator + Prometheus 엔드포인트 활성화
- API 버전 관리:
ApiVersion어노테이션 +ApiVersionConfig로 확장 가능 구조 마련
-
장점
- 도메인별로 잘 분리된 계층 구조와 공통 코어 모듈
- AOP 기반 로깅/캐싱/Rate Limiting으로 비즈니스 코드의 단순성 유지
- 일관된 예외/응답 포맷과 환경별 설정 분리로 운영/유지보수성 향상
-
유의 사항
- Health 도메인처럼 데이터가 많은 영역은 쿼리 최적화(JOIN FETCH, DTO Projection)와 캐싱 전략이 함께 설계되어 있어, 이 패턴을 다른 도메인에도 확장 적용하는 것이 좋습니다.
- 현재 Rate Limiting은 인메모리 방식이므로, 대규모 분산 환경에서는 Redis 기반 Rate Limiting으로 확장하는 것이 권장됩니다.