Skip to content

Daily1Hour/PickMe-Reminder-Service

Repository files navigation

알림 서비스

API를 통해 알림 시간을 관리하고, 스케쥴러가 매시간 알림을 발송하는 서비스

GitHub release API Docs cicd codecov

🚩 목차

🛠️ 기술 스택

NestJS NodeJS
DynamoDB OneSignal OneSignal Axios
Docker Compose Docker
Jest ESLint Prettier TypeScript
Swagger Codecov TypeDoc
Github Actions

💡 주요 기능

  • NestJS 프레임워크

    • NestJS 애플리케이션 아키텍처를 활용하여 모듈과 공급자 간의 의존성 주입을 설정
    • NestJS의 전송 계층 마이크로서비스 기능을 사용하여 마이크로서비스 간 TCP 통신을 구현
  • MSA (마이크로서비스아키텍처)

    1. Notification 서비스
      • 알림 리소스를 관리하는 REST API 제공
      • 알림 데이터는 Key-Value 데이터베이스인 DynamoDB에 저장
      • DynamoDB의 TTL(Time to Live) 설정을 활용하여, 예약된 알림이 지나면 자동으로 삭제됨
    2. Worker 서비스
      • Cron 스케줄러를 사용하여 매시간 주기적인 작업 수행
      • Notification 서비스와 TCP 통신을 통해 알림 데이터를 조회
      • OneSignal 서비스를 통해 알림 메시지를 전송

📖 개발 문서

📄 API 명세서

프로젝트에서 사용되는 API 명세서입니다.
이 명세서는 매 릴리즈 업데이트 시 자동으로 최신 상태로 배포됩니다.

Swagger
   API 명세서 바로가기   

📘 타입 문서

프로젝트에서 사용되는 타입 정의를 문서화한 자료입니다.
이 타입 문서는 매 릴리즈 업데이트 시 자동으로 최신 상태로 배포됩니다.

TypeDoc
    타입 문서 바로가기   

🧪 테스트 리포트

테스트 통과 여부와 커버리지 현황은 시각적으로 제공되며, 매 릴리즈 시 자동으로 최신 상태로 반영됩니다.
커버리지는 Codecov를 통해 분석됩니다. codecov

Jest Codecov
테스트 리포트 바로가기 커버리지 대시보드 바로가기

📐 다이어그램

🔹 유즈케이스 다이어그램

usecase

  1. 사용자 (Actor)
    • 웹사이트 사용자: 이벤트를 등록하고 알림을 받는 사용자
    • 알림 워커: 정기적으로 메시지를 처리하고 전송하는 시스템
  2. 유즈케이스 (Use Case)
    • 알림 등록: 사용자가 새로운 이벤트 알림을 등록하는 기능
    • 알림 삭제: 사용자가 기존에 등록된 알림을 삭제하는 기능
    • 알림 확인: 사용자가 등록된 알림 목록을 확인하는 기능
    • 메시지 상태 확인:알림 워커가 이벤트를 읽는 기능
    • 메시지 전송: 알림 워커가 메시지를 사용자에게 전송하는 기능
  3. 상호작용 (Interaction)
    • 웹사이트 사용자 ↔ 알림 서비스: 웹사이트 사용자가 이벤트 정보를 입력하여 알림 등록을 요청
    • 알림 워커 ↔ 알림 서비스: 알림 워커가 알림 서비스에 등록된 이벤트 정보를 확인
    • 알림 워커 ↔ OneSignal: 알림 워커가 OneSignal을 통해 알림 메시지를 사용자에게 전송

🔀 데이터 흐름 다이어그램

flowchart LR
   Web["웹사이트"]
   click Web "https://github.com/Daily1Hour/PickMe-Calendar-Application"
   event@{ shape: bow-rect, label: "이벤트 정보" }

   Web --> event --> |REST/HTTP| Notification/server

   subgraph Reminder
      subgraph Worker
         Worker/Cron@{ shape: circle, label: "스케줄러" }
      end

      subgraph Notification
         Notification/server@{ shape: circle, label: "등록 서버" }
         Notification/db@{ shape: lin-cyl, label: "DynamoDB" }

         Notification/server <--> Notification/db
      end

      Worker/Cron <-.-> |TCP| Notification/server
   end

   Calendar
   click Calendar "https://github.com/Daily1Hour/PickMe-Calendar-Service"
   data@{ shape: bow-rect, label: "이벤트 상세 정보" }

   Calendar --> data --> Worker/Cron
   Worker/Cron --> |HTTP| message@{ shape: bow-rect, label: "메시지" } --> OneSignal
Loading
  1. 웹사이트에서 이벤트 정보를 Notification 서비스 등록 서버에 REST 방식으로 전송
  2. Notification 서비스는 데이터를 DynamoDB로 관리
  3. Worker 서비스의 스케줄러가 정기적으로 등록 서버에서 TCP 연결로 데이터 읽음
  4. 데이터가 존재하면 외부 Calendar 서비스에서 상세 정보를 가져옴
  5. 데이터를 통합하여 메시지로 만들어 OneSignal로 전송

📦 배치 다이어그램

deployment

  1. NestJS 프레임워크를 사용해 백엔드 서비스 구축
  2. NestJS의 MicroService 모듈을 사용해 두 개의 마이크로서비스로 구현
  3. Notification 서비스
    • REST API 방식으로 외부 요청을 처리
    • DynamoDB를 사용해 데이터베이스 관리
  4. Worker 서비스
    • NestJS Schedule 라이브러리를 사용해 Cron Job 설정으로 주기 작업 처리
    • 마이크로서비스 간 TCP 연결을 통해 Notification 서비스에서 데이터 읽기
    • REST API로 외부 서비스 (Calendar 서비스)에서 데이터 요청
    • 데이터 통합하고 OneSignal를 통해 알림을 전송
  5. 각 마이크로 서비스는 Docker Image 생성하여 컨테이너화
  6. Docker Compose로 마이크로서비스와 관련 서비스(DB)를 관리하고 배포

🗺️ AWS 아키텍처 다이어그램

aws-architecture

  1. ECR(Elastic Container Registery) 에 Docker 이미지 업로드
  2. ECS(Elastic Container Service) Cluster 생성
    • 두 서비스 간의 연결을 위해 브릿지 모드 설정
  3. ECS의 용량 공급자EC2 인스턴스 생성 (Auto Scaling 적용)
  4. ECR 이미지를 기반으로 Task Definition 생성
  5. Task Definition을 바탕으로 ECS 서비스 생성
  6. ECS 서비스에서 태스크 실행 (Auto Scaling 적용)
  7. ALB(Application Load Balencer) 연결을 통해 외부 트래픽 라우팅

🚚 CI/CD 파이프라인

       GitHubActions GitHub Actions 바로가기

graph LR
    Tag[태그 푸시] ---> test-report & openapi

    subgraph test-report
        direction LR
        Test/Coverage[커버리지 측정] --> |🟢 통과|Test/Codecov[Codecov 퍼블리싱]
        Test/Execution[테스트 수행] --> |🟢 통과|Test/Report[리포트 생성]
    end

    subgraph openapi
        direction LR
        Docs[타입 문서화]
        OpenAPI/Define[명세서 생성] --> OpenAPI/Validate[검증] --> |🟢 통과|OpenAPI/Publish[API 문서 생성]
    end

    Test/Report & Docs & OpenAPI/Publish -.-> |📦 아티팩트|Artifact/Download

    subgraph deploy-document
        direction LR
        Artifact/Download[다운로드] --> Release[릴리즈 배포]
        Artifact/Download --> DeployGH[gh-pages 배포] --> |자동 워크플로 실행|pages-build-deployment[GitHub Pages 배포 완료]
    end

    click Test/Execution,Docs,OpenAPI/Define,DeployGH "https://github.com/Daily1Hour/PickMe-Reminder-Service/actions/workflows/document-hosting.yml"
    click pages-build-deployment "https://github.com/Daily1Hour/PickMe-Reminder-Service/actions/workflows/pages/pages-build-deployment"
Loading

📂 폴더 구조

열기

Monorepo + Microservice
Clean Architecture

PickMe-Reminder-Service
├─ .github
│  ├─ workflows # 깃헙액션 워크플로어
│  │  └─ document-hosting.yml # 스웨거 및 테스터 리포트 작성
│  └─ document-index.html # 깃헙 페이지 진입점
├─ .gitignore
├─ notification # 알림 마이크로서비스
│  ├─ src
│  │  ├─ main.ts # 서버 실행 진입점
│  │  │  └─ main.test.ts
│  │  ├─ module.ts # 의존성 주입 모듈
│  │  ├─ application # 유즈케이스 계층
│  │  │  ├─ dto.ts
│  │  │  └─ service.ts # 유즈케이스
│  │  │     └─ service.spec.ts
│  │  ├─ domain # 도메인 계층
│  │  │  ├─ entity.ts # 엔티티 객체
│  │  │  └─ repository.ts # 레포지토리 인터페이스
│  │  ├─ infrastructure # 인프라스트럭쳐 계층
│  │  │  ├─ auth
│  │  │  │  ├─ jwtInterceptor.ts # JWT 토큰 인터셉터
│  │  │  │  │  └─ jwtInterceptor.test.ts
│  │  │  │  └─ verifier.ts # Cognito로 토큰 인증
│  │  │  └─ dynamo # DynamoDB
│  │  │     ├─ model.ts # 스키마
│  │  │     │  └─ model.test.ts
│  │  │     ├─ provider.ts # 프로바이더 의존성
│  │  │     │  └─ provider.test.ts
│  │  │     └─ repository.ts # 레포지토리 구현체
│  │  │        └─ repository.test.ts
│  │  ├─ presentation # 프레임워크 계층
│  │  │  ├─ controllers
│  │  │  │  ├─ healthCheckController.ts # 헬스체크
│  │  │  │  │  └─ healthCheckController.spec.ts
│  │  │  │  ├─ httpController.ts # Http API
│  │  │  │  │  └─ httpController.spec.ts
│  │  │  │  └─ messageController.ts # TCP API
│  │  │  │     └─ messageController.test.ts
│  │  │  └─ dtos # 데이터 전송 객체
│  │  │     ├─ index.ts
│  │  │     ├─ CreateRequestDTO.ts
│  │  │     ├─ ParametersDTO.ts
│  │  │     ├─ ReadRequestDTO.ts
│  │  │     └─ UpdateRequestDTO.ts
│  │  └─ utility
│  │     ├─ decorators # 커스텀 데코레이터
│  │     │  ├─ index.ts
│  │     │  ├─ AtLeastOneOption.ts # 옵션 하나 이상 유효성 검사
│  │     │  │  └─ AtLeastOneOption.test.ts
│  │     │  ├─ IsTimeRange.ts # 시간 범위 유효성 검사
│  │     │  │  └─ IsTimeRange.test.ts
│  │     │  ├─ PayloadEX.test.ts
│  │     │  │  └─ PayloadEX.ts # Payload를 dto 변환하고 데코레이터 기반 유효성 검사
│  │     │  └─ TrimSeconds.ts # 시간 데이터의 분초 삭제 변환
│  │     │     └─ TrimSeconds.test.ts
│  │     ├─ downloadOpenAPI.ts # yaml 파일로 스웨거 문서 다운로드
│  │     │  └─ downloadOpenAPI.test.ts
│  │     └─ generatorSwagger.ts # 스웨거 문서 생성
│  │        └─ generatorSwagger.test.ts
│  ├─ test
│  │  └─ app.e2e-spec.ts # end to end 테스트
│  ├─ .env # 환경변수
│  ├─ package.json # 워크스페이스 의존성 관리
│  │  └─ jest.config.js # jest 테스트 설정
│  └─ tsconfig.json # typescript 설정
│     ├─ tsconfig.build.json
│     └─ global.d.ts # 환경변수 타입
├─ worker # 알림 워커 서비스
│  ├─ src
│  │  ├─ main.ts # 서버 실행 진입점
│  │  ├─ module.ts # 의존성 주입 모듈
│  │  ├─ application
│  │  │  ├─ dto.ts # 페이로드 DTO
│  │  │  ├─ ports # 인터페이스
│  │  │  │  ├─ index.ts
│  │  │  │  ├─ client.ts # 알림 저장 서비스
│  │  │  │  ├─ receiver.ts # 메시지 수신
│  │  │  │  └─ sender.ts # 메시지 발송
│  │  │  └─ usecases
│  │  │     ├─ cron.ts # 잡 스케줄러
│  │  │     │  └─ cron.test.ts
│  │  │     └─ service.ts # 알림 TCP 요청, 발송 처리, 완료 처리
│  │  │        └─ service.test.ts
│  │  └─ infrastructure
│  │     ├─ api # axios API 인터셉터
│  │     │  ├─ index.ts
│  │     │  ├─ calendarClient.ts
│  │     │  │  └─ calendarClient.test.ts
│  │     │  └─ onesignalClient.ts
│  │     │     └─ onesignalClient.test.ts
│  │     ├─ receivers
│  │     │  └─ calendarReceiver.ts # 캘린더 서비스 구현체
│  │     │     └─ calendarReceiver.test.ts
│  │     ├─ senders
│  │     │  └─ webSender.ts # 웹 메시지 발송 구현체
│  │     │     └─ webSender.test.ts
│  │     └─ clientImpl.ts # 마이크로서비스 호출 구현체
│  │        └─ clientImpl.test.ts
│  ├─ test
│  │  └─ app.e2e-spec.ts # end to end 테스트
│  ├─ .env # 환경변수
│  ├─ package.json # 워크스페이스 의존성 관리
│  │  └─ jest.config.js # jest 테스트 설정
│  └─ tsconfig.json # typescript 설정
│     ├─ tsconfig.build.json
│     └─ global.d.ts # 환경변수 타입
├─ test # 통합 테스트
│  └─ jest.config.js
├─ .env # 공용 환경변수
├─ docker-compose.yml # 도커컴포즈
│  ├─ Dockerfile.notification # 알림 마이크로서비스 도커파일
│  └─ Dockerfile.worker # 워커 마이크로서비스 도커파일
├─ package.json # 의존성 관리
│  ├─ package-lock.json
│  ├─ .eslintrc.js # eslint 린터 설정
│  ├─ .eslintignore # eslint 무시 설정
│  ├─ .prettierrc # 포맷터 설정
│  ├─ jest.config.js # jest 테스트 설정
│  └─ nest-cli.json # nestjs 모듈 구조 설정
└─ tsconfig.json # typescript 설정
   └─ typedoc.json # 문서 설정

🚀 실행 방법

도커환경

# build
$ docker-compose build

# run
$ docker-compose up -d

로컬환경

$ npm install

# build
$ npm run build

# development
$ npm run start

About

알림 마이크로 서비스

Topics

Resources

Stars

Watchers

Forks