모뉴(MoNew) 는 다양한 뉴스 출처(Naver API, 한국경제, 조선일보, 연합뉴스 등)를 통합하여 관심사 기반으로 뉴스를 저장하는 뉴스 통합 관리 플랫폼입니다. 사용자는 관심 있는 주제를 구독하고, 해당 주제의 기사가 등록되면 실시간 알림을 받을 수 있습니다. 또한 댓글과 좋아요를 통해 다른 사용자와 의견을 나눌 수 있는 소셜 기능도 함께 제공됩니다. 🗞️💬

항목 | 내용 |
---|---|
📆 프로젝트 기간 | 2025.04.16 ~ 2025.05.11 |
🔗 배포 링크 | http://15.164.82.15/login |
🎬 시연 영상 | YouTube 시연 영상 보기 |
📋 협업 문서 | Notion 페이지 |
📊 칸반 보드 | GitHub Projects |
📘 API 문서 | Swagger v2.3.1 |
📑 발표 자료 | Canva 발표 자료 |
이름 | 역할 및 기여 |
---|---|
김태현(팀장) | • 프로젝트 관리(칸반보드 연동, 이슈 기반 브랜치 자동 생성, 이슈 템플릿) • CI 파이프라인 구축 • 기사 백업 & 복구 시스템 구현 • logback 롤링 정책 및 시스템, JVM 레벨 타임존 설정 • 댓글 관리 도메인 설계 • 인프라 관리(swap 파일, JVM 옵션 최적화로 OOM 문제 해결) • 릴리즈 버전 문서 관리 |
김주언 | • 사용자, 활동 내역 도메인 설계 • Fetch Join을 활용한 쿼리 성능 개선 • Spring Event를 활용한 클래스 간 결합도 감소 • MongoDB를 활용한 조회 최적화 • DB Schema, MongoDB 관리 |
연예림 | • Interest 도메인 설계 • Subscription 도메인 설계 • Swagger API 문서화(자동화 워크플로우 구축) • 공통 예외 처리 및 전역 핸들러 구현 • Fetch Join, Index를 활용한 쿼리 최적화 |
이소영 | • Notification 도메인 설계 • 오래된 알림 삭제 배치 작업 구현 • QueryDsl 기반 모든 도메인 커서 페이지네이션 구현 • AOP 기반 쿼리 추적 로그 시스템 • Spring Actuator 및 커스텀 메트릭 적용 • Spring Boot Admin Server 적용 및 모니터링 |
허지웅 | • Article 도메인 설계 • 기사 수집, 분류 및 저장 배치 프로세스 구현 • Template Method, Strategy 패턴을 통한 확장성 확보 • 인메모리 KeywordCache 도입 • CD 파이프라인 구축 • GIN 인덱스, tsvector를 활용한 Article 도메인 성능 개선 |
모뉴 시스템은 다음과 같은 아키텍처로 구성되어 있습니다.
- CI/CD 파이프라인
- GitHub을 통한 코드 관리
- GitHub Actions를 활용한 자동화된 테스트 및 배포
- AWS ECR을 통한 컨테이너 이미지 관리
- 백엔드 시스템
- Amazon EC2 인스턴스에서 애플리케이션 실행
- MongoDB와 PostgreSQL을 활용한 데이터 저장
- AWS S3를 활용한 로그 및 기사 백업 관리
- 데이터베이스 구조
- PostgreSQL: 관계형 데이터를 위한 주 데이터베이스
- MongoDB: 사용자 활동 내역과 같은 조회 최적화를 위한 비관계형 데이터베이스
monew/ # 루트 디렉토리
├── admin/ # Spring Boot Admin 애플리케이션
│ ├── Dockerfile # Admin 컨테이너화 설정
│ ├── build.gradle
│ └── src/
│ ├── main/java/.../monew/
│ │ └── AdminApplication.java # Admin 진입점
│ └── test/java/.../monew/
│ └── AdminApplicationTests.java
│
├── src/
│ ├── main/ # 메인 소스 코드
│ │ └── java/.../monew/
│ │ ├── config/ # 애플리케이션 설정
│ │ │ ├── JpaConfig.java # JPA 설정
│ │ │ ├── MongoDbConfig.java# MongoDB 설정
│ │ │ ├── WebConfig.java # 웹 관련 설정
│ │ │ ├── interceptor/ # 인터셉터
│ │ │ └── queryAspect/ # 쿼리 추적 AOP
│ │ │
│ │ └── module/ # 애플리케이션 모듈
│ │ ├── actuator/ # 모니터링 지표
│ │ ├── common/ # 공통 모듈 (예외 처리 등)
│ │ ├── domain/ # 도메인 모듈
│ │ │ ├── article/ # 기사 도메인
│ │ │ │ ├── backup/ # 기사 백업 & 복구
│ │ │ │ ├── batch/ # 기사 수집 배치
│ │ │ │ └── controller, dto, entity, repository, service...
│ │ │ │
│ │ │ ├── comment/ # 댓글 도메인
│ │ │ ├── interest/ # 관심사 도메인
│ │ │ ├── notification/ # 알림 도메인
│ │ │ ├── subscription/ # 구독 도메인
│ │ │ ├── user/ # 사용자 도메인
│ │ │ └── useractivity/ # 사용자 활동 도메인
│ │ │
│ │ └── log/ # 로그 관리
│ │
│ └── test/ # 테스트 소스 코드
│ └── java/.../monew/
│ ├── config/ # 설정 테스트
│ └── module/
│ ├── TestEntityFactory.java
│ ├── actuator/ # 모니터링 지표 테스트
│ ├── domain/ # 도메인별 테스트
│ │ ├── article/ # 기사 도메인 테스트
│ │ │ ├── backup/ # 백업 & 복구 테스트
│ │ │ ├── batch/ # 배치 테스트
│ │ │ ├── controller/
│ │ │ ├── repository/
│ │ │ └── service/
│ │ │
│ │ ├── comment/ # 댓글 도메인 테스트
│ │ ├── interest/ # 관심사 도메인 테스트
│ │ ├── notification/ # 알림 도메인 테스트
│ │ ├── subscription/ # 구독 도메인 테스트
│ │ ├── user/ # 사용자 도메인 테스트
│ │ └── useractivity/ # 사용자 활동 도메인 테스트
│ │
│ └── log/ # 로그 관리 테스트
│
├── docs/ # API 문서 및 관련 문서
├── logs/ # 로그 파일 디렉토리
├── gradle/
├── build.gradle
└── Dockerfile # 메인 애플리케이션 컨테이너화 설정


- 회원가입, 로그인, 닉네임 수정 기능
- 논리적 삭제 지원으로 데이터 무결성 유지
- 보안을 위한 비밀번호 암호화
- 관심사 등록, 수정, 삭제 기능
- 키워드 기반 관심사 설정
- 관심사 구독 시스템
- 유사도 기반 중복 관심사 방지
- 다양한 출처(Naver API, RSS 피드 등)를 통한 뉴스 기사 수집
- 관심사 키워드 기반 필터링
- 백업 및 복구 시스템 구현
- 조회수, 댓글 수 등 다양한 정렬 옵션
- 기사별 댓글 등록, 수정, 삭제
- 좋아요 기능
- 커서 기반 페이지네이션
- MongoDB를 활용한 사용자 활동 내역 조회 최적화
- 구독 중인 관심사, 최근 작성 댓글, 좋아요, 조회 기사 추적
- 관심사 관련 새 기사 알림
- 댓글 좋아요 알림
- 알림 확인 및 자동 삭제 배치 처리
- Fetch Join을 활용한 N+1 문제 해결
- 인덱스 전략 적용으로 조회 성능 개선
- GIN 인덱스 및 tsvector를 활용한 전문 검색 최적화
- 사용자 활동 내역을 위한 비정규화 모델 설계
- 조인 없이 빠른 조회가 가능한 문서 구조 설계
- 인메모리 KeywordCache 도입으로 기사 분류 성능 개선
- swap 공간 생성 및 JVM 옵션 최적화로 OOM 문제 해결
- Template Method, Strategy 패턴을 통한 확장성 있는 배치 구조
- 청크 기반 처리로 대용량 데이터 효율적 관리
- AOP를 활용한 HTTP 요청별 쿼리 실행 수와 시간 로깅
- 개발 환경에서 쿼리 최적화를 위한 도구로 활용
Query Statistics: URL = GET /api/interests, Query Count = 3, Query Time = 22(ms)
- Logback을 활용한 로그 롤링 정책 구현
- 로그 파일 압축 및 S3 업로드 자동화
- 일별 기사 S3 백업
![]() |
![]() |
![]() |
형식: 유형(범위): <설명> #이슈번호
- 브랜치의 첫 커밋과 마지막 커밋에는 #이슈번호 필수로 포함하기
- 작은 변경도 자주 커밋하여 기록하기
- 다른 이슈와 연관된 작업 시 커밋 예
- ex) refactor(A,B): 공통 코드 분리 #1#4
타입 | 사용 시나리오 |
---|---|
feat |
신기능 추가 |
fix |
버그 수정 |
refactor |
성능 개선 및 코드 리팩토링, 파일 또는 디렉토리명 수정, 경로 변경 |
test |
테스트 코드, 리팩토링 테스트 코드 추가 |
style |
코드 포멧팅 |
comment |
주석 추가 및 수정 |
docs |
문서 수정 |
remove |
파일 삭제 |
chore |
기타 변경 |
형식: [유형]/#[이슈번호]/[키워드]
라벨 유형 | 접두사 | 예시 | 비고 |
---|---|---|---|
feat |
feat |
feat/#123/login-modal |
신기능 개발 |
hotfix |
hotfix |
hotfix/#45/auth-error |
긴급 수정 |
refactor |
feat |
feat/#89/employee-search-refactor |
리팩토링 작업 |
etc. |
task |
task/#234/docs-update |
문서 작업 등 일반 작업 |
- 영문 소문자 사용 (employ-search ⭕ / EmploySearch ❌)
- 하이픈(-) 으로 단어 구분
- 이슈 번호는 #+숫자 형식
- 리팩토링 작업 시 기존 feat 브랜치명에 '-refactor' 접미사 추가
- 키워드 길이 20자 이내 권장