🧭 시스템 아키텍처 개요
VivaSport 플랫폼은 Cloudflare의 Serverless 인프라(Workers)와 Edge DB(D1)를 척추로 삼아, 다중 프론트엔드 환경을 유기적으로 결합했습니다.
📱
소비자 React 앱
Vite + React + TS (app.vivaura.tech) 대회 탐색 및 신청, 마이페이지
🌐
퍼블릭 이벤트 허브
이벤트 및 뉴스 공유 허브 (event.vivaura.tech) Q&A 커뮤니티
🏢
어드민 콘솔 웹
테넌트 정산, 감사 로그 및 배너 관리, Q&A Abuse 차단 제어
⚙️
Serverless Workers API
Hono 프레임워크 기반 API 라우팅 및 비즈니스 미들웨어 검증
🗄️
D1 SQL Database
Cloudflare SQLite 기반 글로벌 데이터베이스 분산 쿼리
🔄 데이터 상호작용 및 보안 레이어 흐름
- 클라이언트 인증: Firebase Auth 토큰이 발급되면 모든 프론트엔드가 Hono API 호출 시
Authorization: Bearer [JWT]헤더를 첨부하여 보안 미들웨어 검증을 통과합니다. - 어드민 권한 제어: 어드민 콘솔은 전용 인증 토큰(JWT)과 역할(Role - Owner, Admin, Support) 테이블 매핑을 통해 리소스 접근 범위를 차단 및 통제합니다.
- 스팸(봇) 방지 (Cloudflare Turnstile): 대회 참가 신청, Q&A 의견 등록 및 신고 제출 시 봇 API 트래픽 공격을 완벽 차단하기 위해 Turnstile 사이트 키 검증이 선행됩니다.
🔑 인증 및 보안 처리
VivaSport API는 강력한 보안을 위해 Hono 미들웨어로 보호되며, 호출 유형에 따라 세 가지 인증 메커니즘을 사용합니다.
Firebase JWT Bearer Auth
일반 유저용 API(대회 참가, 내 정보 수정, 단체 개설 등) 호출 시, Firebase Auth에서 발행한 ID 토큰을 전송합니다.
Authorization: Bearer <Firebase_ID_Token>
Admin Console Auth Token
어드민용 API(정산 처리, 감사 로그 조회, 사용자 정지 등) 호출 시, 테넌트 검증이 완료된 Admin 전용 토큰을 전송합니다.
Authorization: Bearer <Admin_Access_Token>
⚡ API 엔드포인트 명세
| 유형 | 엔드포인트 | 설명 및 권한 수준 | 봇 방지 |
|---|---|---|---|
| GET | /api/events |
전체 대회 목록 조회 (비회원/소비자용) | - |
| POST | /api/events |
새로운 대회 개설 (요금제 구독 한도 필터 미들웨어 작동) | - |
| POST | /api/events/:id/feedbacks |
대회 Q&A 댓글/의견 신규 등록 (JWT optional) | Turnstile |
| POST | /api/reports |
댓글, 루트, 주최자 등 불편/스팸 신고 접수 | Turnstile |
| POST | /api/groups |
단체 개설 (소비자앱 또는 이벤트 허브에서 단체 생성) | - |
| GET | /api/groups/:code/members |
특정 단체 가입 신청 멤버 조회 (비밀번호 혹은 단체장 권한) | - |
| PATCH | /api/groups/:code/members/:id |
단체 신청 단체원 수락/반려 (단체장 검증 필수) | - |
| GET | /api/admin/reports |
접수된 신고 및 1:1 고객지원 목록 조회 (어드민 전용) | - |
| GET | /api/admin/feedbacks/:id |
신고 대상이 된 Q&A 피드백 댓글 원본 단건 상세 조회 | - |
| DELETE | /api/admin/feedbacks/:id |
신고된 스팸성 Q&A 댓글 영구 삭제 및 감사로그 기록 | - |
| PATCH | /api/admin/users/:id/status |
Abuse 악성 유저 차단(Blocked) 조치 (임시 provider 컬럼 매핑) | - |
📱 소비자 React 앱 기능 리스트
| 기능 명칭 | 상세 내용 | 상태 |
|---|---|---|
| 홈 (대회 카드 목록) | 대회 리스트 카드 및 실시간 진행률 애니메이션 바 적용 | ✓ 개발완료 |
| 대회 찾기 및 카테고리 필터 | 대회명 검색, 종목별 카테고리, 난이도 및 정렬 기능 연계 | ✓ 개발완료 |
| 이벤트 상세 정보 및 신청 | 상세 안내 정보 및 Firebase Auth 기반 다단계 참가 신청서 작성 | ✓ 개발완료 |
| 단체/팀 관리 (MyGroups) | 개설 단체 실시간 조회, 단체 코드 개설 및 단체원 승인/반려 (API 연계) | ✓ 개발완료 |
| 마이페이지 API 연동 | 신청 상태 실시간 동기화 및 마일리지 적립 조회 기능 | ✓ 개발완료 |
| GNB 모바일 안전 마진 | 노치가 없는 일반 화면에서도 GNB 레이블 텍스트 잘림 해결 | ✓ 개발완료 |
| 홈 타이틀 중복 수정 | 상단 네비게이션 헤더와 본문 타이틀의 'VivaSport' 이중 표시 교정 | ⚡ 개발대기 |
| 대회 생성 위자드 (4단계) | 대회 정보, Race 코스, 결제 방식, 포스터 업로드 4단계 마크업/API 연계 | ⚡ 개발대기 |
| 주최자 정산 관리 대시보드 | 대회 주최 기업/단체 대시보드 및 정산 이력 통계 연동 | ⚡ 개발대기 |
🌐 퍼블릭 이벤트 허브 기능 리스트
| 기능 명칭 | 상세 내용 | 상태 |
|---|---|---|
| 대회 소식 뉴스 카드 | 수집 봇이 물어온 공식 마라톤/대회 소식 리스트 카드화 | ✓ 개발완료 |
| 지도 앱 연동 & 주소 복사 | 개최지 정보의 클립보드 원클릭 복사 및 네이버/카카오 지도 연계 | ✓ 개발완료 |
| 모집율 실시간 카운터 | 모집율 정원 대비 비율 인디케이터 프로그레스 바 렌더링 | ✓ 개발완료 |
| 온오프믹스식 단체 참가 신청 | 대회 단체 가입 다이얼로그 검색, 단체 코드 클립보드 복사 모달 연동 | ✓ 개발완료 |
| Q&A 댓글/피드백 스팸 신고 | 댓글 옆 신고 버튼으로 팝업 다이얼로그 활성화 및 API 접수 연계 | ✓ 개발완료 |
| Turnstile 봇 방지 보호 | Q&A 댓글 작성과 신고 접수 시 악성 자동 도배 방지 캡차 위젯 탑재 | ✓ 개발완료 |
| 다국어 i18n 완전 지원 | 한국어, 영어 듀얼 렌더링 확장 리소스 추가 | ⚡ 개발대기 |
🏢 어드민 콘솔 웹 기능 리스트
| 기능 명칭 | 상세 내용 | 상태 |
|---|---|---|
| 로그인 락 스크린 & 우회 | 수동 토큰 입력란에 전용 키 주입을 통해 Mock 데이터 모드 완벽 진입 | ✓ 개발완료 |
| 정산 대장 목록 및 이력 | 참가비 총액, 수수료, 세금 및 주최자 실 수령액 정산 승인 프로세스 | ✓ 개발완료 |
| 감사 로그 (Audit Logs) | 관리자 행위에 따른 IP, 일시, 행위 내역 조회 및 탐색 대시보드 | ✓ 개발완료 |
| 배너 광고 슬롯 관리 | 홈 화면 메인 및 사이드 광고 배너 캠페인 생성, 승인, 기간 통제 | ✓ 개발완료 |
| 신고 관리 (Support / Abuse) | 일반 접수된 불편사항 및 문의 내역 승인, 기각 상태 조치 | ✓ 개발완료 |
| Q&A 원본 fetch & 삭제 조치 | 신고 내역 중 댓글/피드백 원본 조회 후 즉각 삭제 및 해당 신고 완료 처리 | ✓ 개발완료 |
| 작성자 계정 차단 (Block) | 신고 상세 창에서 작성자 계정을 즉시 정지 조치 연계 | ✓ 개발완료 |
| 라이트 모드 가독성 패치 | 인라인 white 색상으로 라이트 테마 전환 시 텍스트 묻히는 가독성 소실 해결 | ✓ 개발완료 |
| 가입 테넌트 타입 정리 | 회원가입 항목 내 부적절한 '개인' 타입을 배제하고 법인, 공공기관 등으로 통일 | ✓ 개발완료 |
| 정산 자동 이체 API (PG) | 정산 승인 시 실시간 계좌이체 자동 연동 API 개발 | ⚡ 개발대기 |
⚙️ Cloudflare Workers & DB 기능 리스트
| 기능 명칭 | 상세 내용 | 상태 |
|---|---|---|
| 요금제 구독 게이팅 미들웨어 | 무료 요금제 유저의 유료 대회 생성 차단, 등급별 월간 유료대회 개설 개수 제한 | ✓ 개발완료 |
| 단체/참가 신청 D1 테이블 스키마 | 단체명, 단체장 정보 및 신청자 정보를 D1 DB 영구 테이블로 런타임 자동 생성 | ✓ 개발완료 |
| 단체 및 가입신청 API 6종 | 내 단체 조회, 참가 신청, 가입자 승인/반려 등 Workers API 구축 | ✓ 개발완료 |
| Turnstile 검증 유연화 | 비회원 상태의 Q&A 피드백 작성 및 신고를 위한 Turnstile 봇 보호 API 추가 | ✓ 개발완료 |
| Google Auth CORS 우회 | Google API 연동 시 X-Viva-Bypass 헤더 중복 전입 방지 우회 조치 | ✓ 개발완료 |
| 스포츠 ODF 표준 코드 매핑 | 러닝->ATH, 사이클->CYC 등의 종목 코드를 저장 시 백엔드 단에서 자동 ODF 매핑 | ✓ 개발완료 |
| 유지보수 중 analytics 캡처 우회 | 점검 상태에서도 익명 분석 로그 수집 Endpoint(/api/analytics/collect) 정상 동작 | ✓ 개발완료 |
| 대규모 트래픽용 KV 캐싱 | D1 데이터베이스 쿼리 부하 분산을 위한 Workers KV 캐싱 캐시 레이어 도입 | ⚡ 개발대기 |
💡 도움말 & 문제해결
Q. 어드민 콘솔 웹에서 테스트를 위해 로그인 잠금(Lock Screen)을 푸는 방법은 무엇인가요?
+
어드민 콘솔 웹 우측 상단 로그인 영역에서 "수동 토큰 (Manual Token)" 탭을 클릭한 뒤, 입력창에 아래 토큰 키를 주입하면 잠금이 해제되고 로컬 Mock 데이터를 연동해 테스트할 수 있습니다.
viva-mock-2026
Q. 무료 요금제 사용자의 유료대회 개설 제한 정책은 어떻게 작동하나요?
+
유저의 등급이
등급별 월간 한도(Basic: 1건, Coach: 5건, Organizer: 무제한) 역시 백엔드 트랜잭션 수량 검증을 통해 엄격하게 차단됩니다.
plan-free인 경우, React 앱 대회 개설 폼에서 참가비 입력 칸이 비활성화되며 무조건 0원으로 고정됩니다. 강제로 API를 조작하여 0원 초과의 결제 금액을 보내더라도 Workers 백엔드 미들웨어 단에서 403 Forbidden을 반환하여 차단합니다.
등급별 월간 한도(Basic: 1건, Coach: 5건, Organizer: 무제한) 역시 백엔드 트랜잭션 수량 검증을 통해 엄격하게 차단됩니다.
Q. 이번에 새로 반영된 Q&A 스팸 제어 및 단체 승인 관리 프로세스는 무엇인가요?
+
Q&A 영역에 악성 도배글이나 욕설 등이 등록되는 것을 방지하기 위해 Cloudflare Turnstile을 연동하여 봇 방지를 수행합니다.
만약 우회해 스팸이 등록된 경우, 일반 유저의 🚨신고 버튼을 통해 어드민 Support 탭에 전달되며, 어드민은 신고 정보에서 원본 댓글을 비동기로 당겨와 직접 삭제하거나 작성자를 즉각 차단(Block)할 수 있습니다.