어스아워 기간 동안 사용자가 소원을 남기고, 실시간으로 참여 현황과 통계를 확인할 수 있는 이벤트형 소원 플랫폼입니다.
이 저장소는 Frontend + Backend + Batch + AI를 분리한 멀티 모듈 구조로 구성되어 있으며, 대규모 이벤트 트래픽을 안정적으로 처리하기 위한 비동기 이벤트 처리와 실시간 집계 구조를 포함합니다.
- 서비스 주소: https://wishhour.org/
- 행사 기간:
2026.03.22MVP 테스트,2026.03.27최종 배포,2026.03.28어스아워 종료
Wish Hour는 "소원을 빌어보는 감성 경험"을 진입점으로 삼아, Earth Hour 공익 캠페인 참여를 유도하는 실시간 참여형 플랫폼입니다.
핵심 목표는 다음과 같습니다.
- 행사 기간 동안 자유롭게 소원을 등록할 수 있는 참여 경험 제공
- 연예인, 지인, 반려동물 등 특정 대상을 지정하는 인터랙티브 소원 작성 구조 제공
- 로그인 사용자의 개인 소원 페이지를 링크로 공유할 수 있는 바이럴 확산 구조 제공
- 실시간 참여 수, 대상별 집계, 시간대별 변화, 키워드 통계를 시각화
- 행사 종료 후 배치 기반 확정 통계 제공
- 비정상 입력, 중복 제출, 욕설/유해 표현을 사전 탐지하여 공익 프로젝트에 맞는 운영 환경 유지
- 대상 지정형 소원 작성
- 링크 기반 개인 소원 페이지 공유
- 로그인/비로그인 혼합 참여
Idempotency-Key기반 중복 제출 방지 인입 API
- SSE 기반 실시간 소원 스트림
- Redis 기반 현재 참여자 수 관리
- Redis 기반 실시간 카운터 집계
- 홈/어스아워/통계 페이지에서 실시간 데이터 노출
- 전체 참여 수, 국가/이벤트 단위 실시간 개요 조회
- 시간대별 타임라인 조회
- 대상별 랭킹 조회
- 키워드 추출 및 사용자/대상 기준 누적 통계
- 행사 종료 후 배치 기반 확정 통계 materialization
- KoGPT2 기반 욕설/유해 표현 분류 API
- 배치 기반 moderation 처리
- 중복 요청 방지
- 이메일 인증 코드/리프레시 토큰/블랙리스트 Redis 관리
WishHourFE: React/Vite 기반 사용자 웹WishHourBE: Spring Boot 기반 API, 인증, 소원 도메인, 실시간/SSE, Kafka outbox, 통계 조회WishHourBatch: Spring Batch 기반 확정 통계/키워드 집계/모더레이션 배치WishHourAI: Flask 기반 욕설 분류 및 키워드 추출 모델 서버exec: 덤프, 포팅 메뉴얼, 운영 참고 자료
- 사용자가 소원을 작성하면 BE가 요청을 수신합니다.
- 인입 단계에서
Idempotency-Key로 중복 제출을 방지합니다. - 소원 생성 시
OutboxEvent를 함께 적재합니다. OutboxPublisher가 Kafka로 이벤트를 발행합니다.- 소비자는 키워드 추출, 임베딩, 실시간 피드 반영 등 후속 처리를 수행합니다.
- 실시간 수치는 Redis에서 빠르게 조회하고, 확정 수치는 Batch가 PostgreSQL projection 테이블로 물질화합니다.
이 구조를 통해 이벤트 기간의 응답 속도와 데이터 정합성을 동시에 확보하도록 설계했습니다.
- 실시간 통계: Redis 카운터 기반 조회
- 확정 통계: Batch가 PostgreSQL 집계 테이블에 materialization
- 조회 API는 목적에 따라 실시간/확정 경로를 분리
즉, CQRS에 가까운 방식으로 "쓰기/실시간 반영"과 "확정 조회"를 분리해 조회 부하를 완화했습니다.
- React 19
- TypeScript
- Vite
- Zustand
- Axios
- SCSS/CSS
- Java 17
- Spring Boot 3.5.x
- Spring Data JPA
- Spring Security
- JWT
- Spring Kafka
- Spring Mail
- Micrometer + Prometheus
- Spring Batch
- JDBC
- PostgreSQL
- Flask
- TensorFlow
- KoGPT2 기반 욕설 분류 모델
- QLoRA 기반 키워드 추출 모델
- Transformers / PEFT / bitsandbytes
- PostgreSQL 16
- Redis
- Kafka
- Docker
- Docker Compose
- AWS EC2 / RDS
- Cloudflare
- GitLab CI/CD
주요 구현 포인트는 다음과 같습니다.
WishHourBE에 Kafka outbox 발행기와 consumer가 존재WishHourBE에 SSE 스트림, 참여자 presence, Redis 기반 실시간 집계가 존재WishHourBatch에 키워드 카운팅/확정 통계 materialization/모더레이션 배치가 존재WishHourAI에 욕설 분류 API와 별도 키워드 추출 API가 존재.gitlab-ci.yml기준develop브랜치에서 백엔드 빌드 및 프론트 배포 자동화가 구성- 2026년 3월 커밋 흐름에서 인증, SSE, 공유 링크, 실시간 통계, 배치, 키워드 추출, 분석/통계 화면이 단계적으로 완성됨
.
├─ WishHourFE/ # React 프론트엔드
├─ WishHourBE/ # Spring Boot API 서버
├─ WishHourBatch/ # Spring Batch 작업 서버
├─ WishHourAI/ # Flask AI 서버
├─ exec/ # 포팅 메뉴얼, dump, 운영 참고 자료
└─ .gitlab-ci.yml # GitLab CI/CD 파이프라인
주요 페이지
- 메인 홈
- 소원 작성/대상 검색
- 실시간 통계 페이지
- 분석 페이지
- 마이페이지
- 공유 링크 페이지
- 로그인/회원가입/비밀번호 재설정
- Earth Hour 전용 페이지 및 종료 페이지
구현 포인트
- React Router 기반 페이지 라우팅
- Vite 환경 분리
- 실시간 페이지 및 통계 페이지 분리 운영
- 공유 URL 접근 경로
/w/:token - 이미지 공유, 신고, 검색, 자동완성 UX 포함
주요 도메인
- Auth / User / Social Login
- Wish / WishRaw / ShareLink / Target / Event
- Stats / Realtime / Presence
- Report / Inquiry / Mail
- Keyword / Embedding / Moderation
구현 포인트
- JWT 기반 인증
- 카카오/네이버/구글 소셜 로그인
- 이메일 인증 및 비밀번호 재설정
- 대상 검색 및 자동완성
- 공유 링크 생성 및 링크 기반 소원 작성
- 실시간 소원 스트림 SSE
- Redis 기반 실시간 통계 및 참여자 수 관리
- Kafka + Outbox 기반 비동기 이벤트 처리
- 키워드 추출 후 후속 임베딩 이벤트 발행
배치 작업
- 키워드 카운팅 배치
- 통계 materialization 배치
- 키워드 추출 배치
- 모더레이션 배치
구현 포인트
- 스케줄 기반 정기 집계
- cutoff 시점을 둔 안정적인 통계 확정
- JDBC 기반 집계성 upsert
- 테스트용 배치 트리거 API 제공
구현 포인트
- Flask 서버로 독립 실행
/moderate/predict,/moderate/predict/batch제공/keywords/extract제공- 욕설 분류 모델과 키워드 추출 모델 분리
- GPU 기반 QLoRA 추론 경로 포함
- Node.js 20+
- Java 17
- Python 3.10+
- PostgreSQL
- Redis
- Kafka
cd WishHourFE
npm ci
npm run devcd WishHourBE
./mvnw spring-boot:run기본 개발 포트
- BE:
8989 - Redis:
6379 - Kafka:
9092
cd WishHourBatch
./mvnw spring-boot:runcd WishHourAI
pip install -r requirements.txt
python app.py키워드 추출 서버는 별도 진입점으로 실행합니다.
cd WishHourAI
python keyword_api.py실행에 필요한 주요 값은 각 모듈의 application*.properties, .env.production, Flask 환경 변수에서 주입됩니다.
대표 항목
DB_HOST,DB_PORT,DB_NAME,DB_USERNAME,DB_PASSWORDJWT_SECRETKAFKA_BOOTSTRAP_SERVERS_DEVML_SCORING_URL,ML_SCORING_BATCH_URLGMS_API_KEYKAKAO_*,NAVER_*,GOOGLE_*VITE_KAKAO_CLIENT_ID,VITE_KAKAO_REDIRECT_URI
GitLab CI/CD 파이프라인 기준:
develop브랜치 push 시 백엔드 빌드- 생성된 JAR 아티팩트를 사용해 서버 배포 스크립트 실행
- 프론트엔드는 빌드 후 별도 Nginx 서버로 업로드 및 릴리스 디렉토리 전환
배포 특징
- 프론트/백엔드 배포 분리
.env.production주입 후 프론트 빌드- Nginx 정적 배포 릴리스 구조
커밋 로그 기준, 아래 순서로 고도화되었습니다.
- 백엔드 기본 뼈대, Redis 통계 MVP, 공통 응답 포맷 구성
- 욕설 필터링 모델과 인증/회원 기능 추가
- 소원 생성/조회, 대상(Target), 공유 링크, 이벤트 도메인 구현
- SSE 기반 실시간 소원 피드와 실시간 참여자 처리 구현
- 프론트 초기 UI와 메인/로그인/마이페이지/소원 작성 화면 연결
- 실시간 통계 API 및 통계 페이지 구현
- Spring Batch 기반 확정 통계, 키워드 카운팅, 모더레이션 배치 추가
- QLoRA 기반 키워드 추출 모델과 분석 기능 보강
- 어스아워 일정 대응, 성능/가독성 개선, 자동완성 distinct 정리
행사 운영을 위한 실시간성, 정합성, 운영 편의성까지 후반부에 계속 보강된 형태입니다.
- FE: 노소연, 김희수, 이영은
- BE: 김민경, 김희수, 나경원, 기장선, 이영은
- Infra: 노소연
- AI: 나경원
- 이메일:
test@test.com - 비밀번호:
test1234
- 이벤트성 대량 트래픽을 고려한 비동기 이벤트 처리 구조
- 실시간 통계와 확정 통계를 분리한 운영 친화적 설계
- 멱등 처리와 outbox 기반 발행으로 정합성 보완
- Redis, Kafka, Batch, AI 서버를 역할별로 분리한 구조
- 공익 캠페인에 맞는 건전성 확보를 위한 moderation 파이프라인
- 감성적 UX와 데이터 기반 통계를 결합한 서비스 경험
저장소 내 참고 자료
exec/포팅 메뉴얼 및 덤프WishHourBE/docs/통계/검색/마이그레이션 문서WishHourBE/kaya/,WishHourFE/kaya/개발 가이드 및 내부 메모
Wish Hour는 "소원을 남기는 감성적 참여"와 "실시간 데이터 처리"를 결합한 Earth Hour 이벤트 플랫폼입니다.
이 저장소는 서비스 화면 구현뿐 아니라, 이벤트 운영에 필요한 실시간 스트리밍, 통계 집계, moderation, 배치 확정 처리까지 포함한 전체 시스템 구성을 담고 있습니다.