Skip to content

[FE] 티켓팅 사이트의 실시간 트래픽 분석 그래프 #96#97

Open
flowersayo wants to merge 10 commits intodevfrom
#96
Open

[FE] 티켓팅 사이트의 실시간 트래픽 분석 그래프 #96#97
flowersayo wants to merge 10 commits intodevfrom
#96

Conversation

@flowersayo
Copy link
Collaborator

@flowersayo flowersayo commented Jan 26, 2026

🧭 Summary

예매 경쟁 강도 분석 기능을 구현했습니다. 티켓팅 사이트의 실시간 응답 지연, 에러율을 측정하여 예매 경쟁 강도를 0-100점으로 표시하고, 최근 24시간 추이를 차트로 시각화합니다.

image

🔗 Linked Issue

Closes: #96

🛠 개발 기능(작업 내용)

Frontend

  • TrafficChart 컴포넌트 구현

    • TrafficLineChart: Recharts 기반 라인 차트 구현
    • TrafficSummaryCards: 사이트별 현재 경쟁 강도 카드
    • TrafficStates: 로딩/에러/빈 데이터 상태 UI
    • trafficConfig: 사이트 설정 및 경쟁 강도 레벨 정의
  • 타입 시스템 구축

    • types/traffic.ts: CongestionScore, CongestionLevel, SiteMetrics 등 타입 정의
    • 경쟁 강도 레벨: LOW(0-25) / MEDIUM(25-50) / HIGH(50-75) / EXTREME(75-100)
  • React Query 연동

    • useTrafficData: API 호출 및 1분 간격 자동 갱신
    • useTraffic: Mock/Real API 전환 가능한 훅

Backend

  • CongestionModule 구현

    • 티켓팅 사이트(인터파크, YES24, 멜론티켓) 실시간 측정
    • 사이트별 5회 응답 시간 측정 후 평균 계산
    • 타임아웃율, 에러율, 큐 감지 기능
    • 가중치 기반 경쟁 강도 점수 산출
      • 응답 시간: 40%
      • 타임아웃율: 30%
      • 에러율: 20%
      • 큐 감지: 10%
  • API 엔드포인트

    • GET /api/congestion: 사이트별 경쟁 강도 데이터 제공

Infrastructure

  • 환경 변수 설정
    • NEXT_PUBLIC_USE_MOCK_TRAFFIC: Mock/Real API 전환 (기본값: false)
    • Mock 데이터: 티켓팅 오픈 시간(10시) 기준 급증 패턴 시뮬레이션

🧩 주요 고민과 해결 방법

1. 개념 변경: 트래픽 → 경쟁 강도

문제: 실시간 접속자 수는 외부 사이트에서 직접 측정 불가능
해결: 응답 지연, 타임아웃, 에러율을 측정하여 간접적으로 경쟁 강도 추정

  • 사이트 부하가 높을수록 응답이 느려지고 에러가 증가한다는 가정
  • 0-100점 척도로 정규화하여 직관적인 지표 제공

2. 실시간 측정의 정확성

문제: 네트워크 상태에 따라 측정값이 불안정할 수 있음
해결:

  • 사이트별 5회 측정 후 평균값 사용
  • 타임아웃 5초 설정으로 무한 대기 방지
  • fetch AbortController로 안전한 타임아웃 처리

3. Mock/Real API 전환

문제: 개발 환경에서 백엔드 DB 의존성 문제
해결: 환경 변수로 Mock/Real API 전환 가능하도록 구현

  • NEXT_PUBLIC_USE_MOCK_TRAFFIC=true: Mock 데이터 사용
  • NEXT_PUBLIC_USE_MOCK_TRAFFIC=false: 실제 API 사용 (기본값)

4. 컴포넌트 구조 설계

문제: 향후 사이트 추가, 측정 지표 변경 등 확장 가능성 고려 필요
해결:

  • 사이트 설정을 trafficConfig.ts에 집중 관리
  • 경쟁 강도 레벨 정의를 설정 파일로 분리
  • 각 서브 컴포넌트를 독립적으로 분리 (차트, 카드, 상태)

🔍 리뷰 포인트

  1. 백엔드 경쟁 강도 계산 로직 (congestion.service.ts:107-115)

    • 가중치(응답 시간 40%, 타임아웃 30%, 에러 20%, 큐 10%)가 적절한지 검토 필요
    • 실제 티켓팅 환경에서 테스트 후 조정 가능
  2. Mock 데이터 패턴 (mockData.ts:13-29)

    • 티켓팅 오픈 시간(10시) 기준 급증 패턴 시뮬레이션
    • 실제 데이터와 비교하여 현실성 검증 필요
  3. 경쟁 강도 레벨 기준 (trafficConfig.ts:25-50)

    • LOW(0-25) / MEDIUM(25-50) / HIGH(50-75) / EXTREME(75-100) 구간이 적절한지
    • 사용자 피드백 기반 조정 가능
  4. 환경 변수 기본값 (TrafficChart.tsx:16)

    • 현재 실제 API 사용이 기본값 (false)
    • 배포 환경에서 API 서버 정상 동작 확인 필요


📋 Code Review Priority Guideline

  • 🚨 P1: Request Change
    • 필수 반영: 꼭 반영해주시고, 적극적으로 고려해주세요 (수용 혹은 토론).
  • 💬 P2: Comment
    • 권장 반영: 웬만하면 반영해주세요.
  • 👍 P3: Approve
    • 선택 반영: 반영해도 좋고 넘어가도 좋습니다. 그냥 사소한 의견입니다.

- 이슈.md 요구사항에 따라 실시간 트래픽 분석 컴포넌트 구현
- 3-4개 파일로 컴포넌트 분리 (확장 가능한 구조)
- 타입 정의 (types/traffic.ts)
- 사이트 설정 관리 (trafficConfig.ts)
- Mock 데이터 생성기 (백엔드 API 대기용)
- 로딩/에러/빈 데이터 상태 UI 구현
- 라인 차트 (TrafficLineChart.tsx)
- 현재 접속자 카드 (TrafficSummaryCards.tsx, 숫자 포맷팅 35200 → 35.2k)
- 커스텀 훅 (useTraffic.ts)
- recharts ^3.7.0 의존성 추가
- 메인 페이지(/)에 TrafficChart 추가
- 실시간 트래픽(접속자 수) → 예매 경쟁 강도(0-100점)로 개념 변경
- 응답 지연, 타임아웃, 에러율 기반 경쟁 강도 추정 시스템으로 재설계
- 타입 정의 변경: CongestionScore, CongestionLevel 추가
- 경쟁 강도 레벨: LOW/MEDIUM/HIGH/EXTREME (4단계)
- Mock 데이터: 티켓팅 오픈 시간(10시) 기준 급증 패턴 시뮬레이션
- UI 텍스트 변경: '실시간 트래픽 분석' → '예매 경쟁 강도 분석'
- 차트 Y축: k단위 → 0-100점 스케일
- 카드 표시: 접속자 수 → 경쟁 강도 점수 + 레벨 배지
- 백엔드: 경쟁 강도 측정 모듈 구현 (NestJS)
  - CongestionService: 사이트 응답 시간, 타임아웃, 에러율 측정
  - 측정 지표 기반 경쟁 강도 점수 계산 (0-100)
  - 티켓팅 사이트 실시간 측정 (인터파크, YES24, 멜론티켓)
  - GET /api/congestion 엔드포인트 추가

- 프론트엔드: Mock 데이터에서 실제 API 연동으로 전환
  - React Query 쿼리 작성 (useTrafficData)
  - useTraffic 훅 실제 API 사용하도록 변경
  - 1분 간격 자동 갱신 (refetchInterval: 60000ms)

- 측정 방식
  - 사이트별 5회 응답 시간 측정
  - 타임아웃/에러율 계산
  - 가중치 기반 경쟁 강도 점수 산출
- NEXT_PUBLIC_USE_MOCK_TRAFFIC 환경 변수 추가
- 기본값: true (Mock 데이터 사용)
- 백엔드 DB 의존성 문제로 인해 Mock 모드로 기본 설정
- 실제 API 사용 시: NEXT_PUBLIC_USE_MOCK_TRAFFIC=false 설정
- NEXT_PUBLIC_USE_MOCK_TRAFFIC 기본값: false (실제 API 사용)
- Mock 데이터 사용 시: NEXT_PUBLIC_USE_MOCK_TRAFFIC=true 설정
@coderabbitai
Copy link

coderabbitai bot commented Jan 26, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • 🔍 Trigger a full review

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'auto_pr'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch #96

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Collaborator

@ParkTjgus ParkTjgus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

너무 수고하셨습니다! 기술 검증과 고민해야 할 부분이 많은 작업이었는데, 해결 방법을 직접 고안해 내신 점이 정말 인상적이었습니다. 고생 많으셨습니다!

@@ -0,0 +1,48 @@
// 경쟁 강도 레벨
export type CongestionLevel = 'LOW' | 'MEDIUM' | 'HIGH' | 'EXTREME';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lint가 적용이 안되고 있는 것 같습니다! frontend는 모두 single quote로 작성되도록 해두었는데 확인부탁드립니다!


const SITE_CONFIGS: SiteConfig[] = [
{
site: 'INTERPARK',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

인터파크 관련된 내용은 전부 nol로 변경 부탁드립니다!

import { CongestionLevel } from '@/types/traffic';

export const SITE_COLORS = {
INTERPARK: {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 부분도 nol-ticket으로 변경 부탁드립니다!


export const SITE_COLORS = {
INTERPARK: {
displayName: '인터파크',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

display name은 #99 부분에서 공통 상수화해두어서 추후에 수정하면 편할 것 같습니다 :D

export const PLATFORM_DISPLAY_NAME: Record<TicketPlatform, string> = {
  "nol-ticket": "NOL티켓",
  yes24: "YES24",
  "melon-ticket": "멜론티켓",
};


export function TrafficChart() {
// 환경 변수로 Mock 데이터 사용 여부 결정 (기본값: false, 실제 API 사용)
const useMockData = process.env.NEXT_PUBLIC_USE_MOCK_TRAFFIC === 'true';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 부분은 env의 NEXT_PUBLIC_API_MODE=mock t설정에 따른 /mock PREFIX 설정으로 해두지 않고 따로 true, false로 설정하신 이유가 궁금합니다 :D

- pnpm-lock.yaml 등 전역 설정 변경 시 전체 서비스 빌드 로직 추가
- 백엔드 CI를 Matrix 전략으로 통합하여 코드 중복 최소화
- 모든 Job이 Skip될 경우 CI 결과가 실패로 뜨던 Summary 로직 수정
- CI 작업의 이름을 '⚙️ CI - ${{ matrix.service }}'에서 '⚙️ CI - Backend'로 변경
- CI 파이프라인에서 변경 감지 스크립트의 단계에 이름 추가
- CI 파이프라인에 Docker Buildx 설정 단계 추가
- 프론트엔드 및 백엔드 작업에서 Docker Buildx를 사용하도록 구성
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants