Skip to content

DMUGradWork/schedule-query-service

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Schedule Query Service

스케줄 도메인의 조회 서비스 (이벤트 프로젝션 기반 일정 조회)

🔧 환경 설정

  • 포트: 8080 (기본값)
  • 데이터베이스: MongoDB (localhost:27017/schedule_query)
  • Kafka: localhost:9092
  • Consumer Group: schedule-query-service

📡 이벤트 스키마

CQRS Query Side로서 Command Service로부터 이벤트를 수신하여 MongoDB에 프로젝션

🔽 수신 이벤트 (Incoming Events from Command Service)

ScheduleCreated - Command Service로부터 수신

토픽: schedule.events

Record 클래스:

// 📁 event/schema/ScheduleCreated.java
public record ScheduleCreated(
    UUID scheduleId,
    UUID ownerId,
    String title,
    String description,
    LocalDateTime startAt,
    LocalDateTime endAt,
    String source,
    UUID studyGroupId,  // STUDY source용 필드 (nullable)
    UUID meetingId,     // STUDY source용 필드 (nullable)
    UUID datingMeetingUuid,  // DATING source용 필드 (nullable)
    long version,
    LocalDateTime occurredAt
) {}

예시 JSON:

{
  "scheduleId": "8f8e5d5e-63d7-4a4e-9d2f-1b93b9a1e0c7",
  "ownerId": "4c9d3e20-2fda-4ab0-8631-0c2f9b8c2d11",
  "title": "스터디 모임",
  "description": "자료 준비",
  "startAt": "2025-10-01T10:00:00",
  "endAt": "2025-10-01T12:00:00",
  "source": "CUSTOM",
  "version": 1,
  "occurredAt": "2025-09-24T15:15:30"
}
ScheduleUpdated - Command Service로부터 수신

토픽: schedule.events

Record 클래스:

// 📁 event/schema/ScheduleUpdated.java
public record ScheduleUpdated(
    UUID scheduleId,
    UUID ownerId,
    String title,
    String description,
    LocalDateTime startAt,
    LocalDateTime endAt,
    String source,
    UUID studyGroupId,  // STUDY source용 필드 (nullable)
    UUID meetingId,     // STUDY source용 필드 (nullable)
    UUID datingMeetingUuid,  // DATING source용 필드 (nullable)
    long version,
    LocalDateTime occurredAt
) {}

예시 JSON은 ScheduleCreated와 동일 구조입니다.

ScheduleDeleted - Command Service로부터 수신

토픽: schedule.events

Record 클래스:

// 📁 event/schema/ScheduleDeleted.java
public record ScheduleDeleted(
    UUID scheduleId,
    UUID ownerId,
    String source,
    long version,
    LocalDateTime occurredAt
) {}

예시 JSON:

{
  "scheduleId": "8f8e5d5e-63d7-4a4e-9d2f-1b93b9a1e0c7",
  "ownerId": "4c9d3e20-2fda-4ab0-8631-0c2f9b8c2d11",
  "source": "CUSTOM",
  "version": 3,
  "occurredAt": "2025-09-24T16:00:00"
}

처리 규칙

  • ScheduleCreated: MongoDB에 새로운 일정 문서 생성
  • ScheduleUpdated: 기존 일정 문서 업데이트 (버전 체크)
  • ScheduleDeleted: 일정 문서 삭제 (버전 체크)
  • 이벤트 버전 관리로 순서 보장 및 멱등성 확보

🚀 실행

./gradlew bootRun

📋 API 엔드포인트

일정 조회

  • GET /schedules/{scheduleId} — 일정 단건 조회

    • Header: X-Owner-Id: <UUID>
    • Response:
      • 200 OK: 일정 정보 반환
      • 404 NOT FOUND: "스케쥴이 없습니다"
  • GET /schedules — 특정 날짜의 일정 목록 조회 (페이징)

    • Header: X-Owner-Id: <UUID>
    • Query Param: day (required) - LocalDate (예: 2025-10-01)
    • Pagination: page, size, sort (기본 정렬: startAt)
    • Response: Page
  • GET /schedules/all — 사용자의 전체 일정 목록 조회 (페이징)

    • Header: X-Owner-Id: <UUID>
    • Pagination: page, size, sort (기본 정렬: startAt)
    • Response: Page

Response 예시

{
  "id": "8f8e5d5e-63d7-4a4e-9d2f-1b93b9a1e0c7",
  "ownerId": "4c9d3e20-2fda-4ab0-8631-0c2f9b8c2d11",
  "title": "스터디 모임",
  "description": "자료 준비",
  "startAt": "2025-10-01T10:00:00",
  "endAt": "2025-10-01T12:00:00",
  "source": "CUSTOM",
  "eventVersion": 1,
  "occurredAt": "2025-09-24T15:15:30",
  "updatedAt": "2025-09-24T15:15:30"
}

🏗️ 아키텍처

  • CQRS Query Side (읽기 전용)
  • Event-Driven Architecture (Kafka 기반 이벤트 수신)
  • Event Sourcing Projection (이벤트를 MongoDB로 프로젝션)
  • MongoDB (조회 성능 최적화를 위한 Document DB)

🔒 핵심 제약사항

  • Query Side는 데이터 수정 불가 (읽기 전용)
  • 모든 데이터 변경은 Command Service의 이벤트를 통해서만 반영
  • 이벤트 버전 관리로 중복 처리 방지 및 순서 보장
  • MongoDB 인덱스: ownerId + startAt 복합 인덱스로 조회 성능 최적화

📊 도메인 모델

  • ScheduleDocument
    • 식별자: id (scheduleId, UUID), ownerId (UUID)
    • 내용: title, description (nullable), startAt, endAt
    • 분류: source (CUSTOM/DATING/STUDY)
    • STUDY 필드: studyGroupId (nullable), meetingId (nullable)
    • DATING 필드: datingMeetingUuid (nullable)
    • 이벤트 추적: eventVersion, occurredAt, updatedAt
    • 인덱스: ownerId_startAt_idx (복합 인덱스)

🛠️ 기술 스택

  • Java 21, Spring Boot 3.5.6
  • Spring Web, Spring Data MongoDB, Spring Kafka
  • Lombok (제한: @Getter, @RequiredArgsConstructor)
  • Gradle

📝 참고사항

  • Command Service와의 통신은 Kafka 이벤트 기반으로만 수행
  • 조회 성능을 위해 MongoDB의 Document 모델 활용
  • 페이징 및 정렬 기능 제공으로 대용량 데이터 처리 지원

About

일정 관리 도메인의 명령 서비스(일정 조회)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages