QA 테스트 결과
체크리스트 개발 가이드 테스트: 2026-05-24 · 72항목

QA 테스트 결과 보고서

6개 Critical 이슈 수정 후 재테스트 · curl + 소스코드 검증 방식 · 2026-05-24 수행

PASS 42 FAIL 7 SKIP 23 총 72항목

전체 통과율 58.3%

이전 결과(25 PASS / 17 FAIL / 30 SKIP, 34.7%) 대비 +23.6%p 개선

42
PASS
7
FAIL
23
SKIP

수정 완료된 6개 Critical 이슈 — 모두 PASS 전환

NEXTAUTH_URL 오타 수정
tire.habyyaps.com → tire.habyapps.com · 인증 리다이렉트 정상화
홈페이지 랜딩 교체
Next.js 기본 템플릿 → TireO2O 브랜드 랜딩 페이지 · 200 OK
/shops MapView 연결
빈 stub → MapView 컴포넌트 · 반경 슬라이더 렌더링 확인
GET /api/shops null 파라미터
400 → 200 OK · z.preprocess로 null 처리 수정
예약 폼 vehicleNumber 검증
Step 0 "다음" 버튼 trigger 추가 · 빈 차량번호 차단
billing PM2 interpreter
tsx/dist/cli.mjs 변경 후 정상 실행 · 0건 처리 후 정상 종료
역할별 진행률
🚗

소비자

비회원 예약 플로우

13 / 1872%FAIL 1
🏪

셀러

위젯 · 빌링

8 / 1457%FAIL 2
🔧

사장님

예약 관리 · 정산

10 / 1856%FAIL 2
🛡️

관리자

승인 · 빌링 제어

11 / 2250%FAIL 2
소비자 테스트 — 18개 항목 · PASS 13 / FAIL 1 / SKIP 4
🗺️ 장착점 검색 (c1)
홈 → 장착점 검색 페이지 진입
GET / → 200, TireO2O 랜딩 · /shops 링크 존재 · GET /shops → 200
CriticalGET /shops
반경 슬라이더 렌더링 확인
/shops HTML에 input[type=range] · 반경 5km 초기값 · 사이드패널 렌더링 확인
HighGET /api/shops?lat&lng&radius
GPS 거부 시 주소 검색 폴백
브라우저 GPS 권한 거부 시나리오 — 클라이언트 인터랙션 필요
SKIP: Playwright 브라우저 없이 GPS 권한 시뮬레이션 불가
High
마커↔리스트 연동 구조 확인
MapView 컴포넌트 렌더링 확인 · SSR HTML에 MapView 모듈 참조 존재
Medium
🏪 장착점 상세 · 공임비 (c2)
장착점 상세 페이지 로드
GET /shops/cmph10jop0001hwpvbko8ldiu → 200 · 영업시간·리프트·평점·주소·공임비·국산·수입 키워드 존재
CriticalGET /api/shops/[id]
공임비 테이블 — feeTables 데이터 확인
API /api/shops/[id] → feeTables 배열 · DOMESTIC/IMPORTED · 14~19인치 단가 데이터 포함
CriticalGET /api/shops/[id]
예약 진행 CTA 버튼
상세 페이지 HTML에 "예약하기" 버튼 · /booking 링크 존재 · /booking → 200 BookingFlow 컴포넌트
High
📱 SMS OTP 인증 (c3)
OTP 발송 API 정상 응답
POST /api/sms/send {"phone":"01012345678"} → 200 {"success":true,"data":{"sent":true}}
CriticalPOST /api/sms/send
OTP 재발송 동작
동일 번호 연속 호출 → 각각 200 {"success":true} 응답 · 횟수 제한 이전 정상 발송
HighPOST /api/sms/send
OTP 5회 실패 시 차단
동일 번호 6회 verify 실패 → 6번째에 "인증 횟수를 초과했습니다" 오류 반환
HighPOST /api/sms/verify
Rate Limiting — 발송 3회 초과 차단
동일 번호 4번째 /sms/send → "잠시 후 다시 시도해주세요" 응답으로 차단
High
📅 예약 플로우 (c4)
예약 폼 유효성 검증 (vehicleNumber)
/booking → 200 · BookingFlow 컴포넌트 렌더링 · Step 0 trigger("vehicleNumber") 추가 확인
Critical
슬롯 조회 API
GET /api/bookings/slots?shopId=...&date=2026-05-30 → 200 · ["09:00","10:00",...] 시간 목록 반환
CriticalGET /api/bookings/slots
예약 확정 — OTP 토큰 검증 통합 테스트
POST /api/bookings에 otpToken 필드 필수 · 실 OTP 발급-인증-예약 E2E 불가
FAIL: curl 환경에서 Redis OTP 토큰 발급 없이 예약 확정 불가 · 401 "인증이 만료되었습니다" 반환
CriticalPOST /api/bookings
동시성 충돌 (슬롯 중복 예약)
동시 POST /api/bookings 두 요청 → 한 쪽 409 충돌 처리
SKIP: 동시성 시나리오는 부하 테스트 도구 필요
Medium
💬 알림톡 · 모바일 (c5)
카카오 알림톡 실수신 확인
예약 완료 시 알림톡 발송
SKIP: 외부 카카오 API 실발송 · 물리 기기 수신 확인 불가
Medium
모바일 뷰포트 메타태그
HTML head에 viewport meta · maximum-scale=1 · user-scalable=no 설정 확인
Medium
터치 제스처 인터랙션
모바일 swipe · pinch-zoom 동작
SKIP: 물리 디바이스 또는 Playwright mobile emulation 필요
Low
셀러 테스트 — 14개 항목 · PASS 8 / FAIL 2 / SKIP 4
🔐 셀러 로그인/인증 (s1)
셀러 로그인 페이지 표시
GET /seller/login → 200 · 이메일/비밀번호/로그인 폼 렌더링 확인
Critical
비인증 접근 → 로그인 리다이렉트
GET /seller/widget (비인증) → 302 → /seller/login 리다이렉트
Critical
세션 만료 시간 설정 확인
auth.config.ts: session.maxAge=1800s(30분), updateAge=900s(15분) 설정 확인
High
🧩 위젯 발급 (s2)
위젯 API 응답 정상
GET /api/widget/cmph10jvh001uhwpvtdcmhwbs → 200 · sellerId/storeName/widgetUrl 포함
CriticalGET /api/widget/[id]
셀러 위젯 페이지 접근 구조
GET /seller/widget (비인증) → 302 (인증 요구) · 로그인 후 접근 가능 구조 확인
High
위젯 코드 복사 기능
위젯 embed 코드 clipboard 복사
FAIL: NEXTAUTH_URL=도메인 설정으로 127.0.0.1 로그인 불가 → 인증 후 UI 테스트 불가
Medium
위젯 활성/비활성 토글
isActive 토글 PATCH API 테스트
SKIP: 인증 세션 없이 테스트 불가
Medium
💳 빌링키 · 정기결제 (s3)
billing callback API 라우트 존재
GET /api/billing/callback → 401 Unauthorized (인증 요구) · 라우트 존재 확인
CriticalPOST /api/billing/callback
토스 빌링키 발급 플로우
토스페이먼츠 카드 등록 → 빌링키 발급
FAIL: 토스 실결제 환경 불가 · TOSS_SECRET_KEY 미설정(.env.local 확인)
Critical
정기결제 자동 청구
월별 자동 청구 실행
SKIP: 실결제 수단 없음
High
결제 실패 시 재시도 로직
실패 후 billing-retry 재시도 확인
SKIP: 실결제 실패 시나리오 재현 불가
High
⚙️ BillingScheduler (s4)
tire-billing-scheduler PM2 정상 실행
PM2 logs: "[BillingScheduler] Found 0 due subscriptions" → 정상 종료 · interpreter tsx/dist/cli.mjs 수정 효과
Critical
tire-billing-retry PM2 정상 실행
PM2 logs: "[BillingRetry] Found 0 retries due" → 정상 종료 · 오류 없음
Critical
실제 청구 대상 구독건 처리
due 상태 구독건 존재 시 청구 처리 검증
SKIP: 현재 due 구독건 0건 · 실결제 없음
Medium
파트너/사장님 테스트 — 18개 항목 · PASS 10 / FAIL 2 / SKIP 6
🔐 파트너 로그인/대시보드 (p1)
파트너 로그인 페이지 표시
GET /partner/login → 200 · 이메일/비밀번호/파트너 로그인 폼 렌더링 확인
Critical
비인증 접근 → 로그인 리다이렉트
GET /partner/dashboard (비인증) → 302 → /partner/login 리다이렉트
Critical
RBAC: 다른 역할 접근 시 자신의 대시보드로 리다이렉트
auth.config.ts의 authorized 콜백 — role !== guard.role 시 ROLE_DASHBOARDS[role]로 리다이렉트 확인
Critical
📆 예약 캘린더 (p2)
파트너 예약 목록 페이지 접근 구조
GET /partner/bookings (비인증) → 302 리다이렉트 · 인증 필요 확인
Critical
예약 상태 변경 API 구조
PATCH /api/bookings/[id]/status API 라우트 존재 · 인증 필요 구조
HighPATCH /api/bookings/[id]/status
캘린더 일별 예약 뷰 렌더링
로그인 후 /partner/dashboard 캘린더 UI 렌더링
SKIP: 인증 세션 없이 테스트 불가
High
예약 승인/거절 인터랙션
예약 카드 클릭 → 상태 변경 모달 → 확인
SKIP: 인증 세션 없이 테스트 불가
Critical
🔔 SSE 실시간 알림 (p3)
SSE 스트림 엔드포인트 인증 요구
GET /api/notifications/stream (비인증) → 401 Unauthorized · 보호됨
CriticalGET /api/notifications/stream
RealtimeNotification 컴포넌트 존재
partner 레이아웃 HTML에 RealtimeNotification 모듈 참조 확인
High
SSE 신규 예약 실시간 수신
예약 생성 → SSE 이벤트 수신 → 토스트 알림
SKIP: 인증 세션 + EventSource 클라이언트 필요
High
연결 끊김 시 자동 재연결
SSE 연결 중단 후 재연결 동작 확인
SKIP: 클라이언트 사이드 인터랙션 필요
Medium
💰 정산 내역 (p4)
정산 API 인증 요구
GET /api/settlements (비인증) → 403 Forbidden {"success":false,"error":"권한 없음"}
CriticalGET /api/settlements
파트너 정산 페이지 접근 구조
GET /partner/settlements (비인증) → 302 리다이렉트 · 인증 필요
High
정산 내역 목록 조회
로그인 후 월별 정산 내역 렌더링
FAIL: NEXTAUTH_URL 도메인 설정으로 127.0.0.1 세션 로그인 불가 → 인증 후 테스트 불가
High
정산 상세 · CSV 다운로드
정산 상세 모달 · CSV 내보내기
SKIP: 인증 세션 없이 테스트 불가
Medium
🔒 세션/보안 (p5)
보안 쿠키 설정 확인
Set-Cookie: __Host-authjs.csrf-token · Secure · HttpOnly · SameSite=Lax 확인
Critical
세션 만료 후 자동 로그아웃
30분 세션 만료 → 재로그인 요구
FAIL: 시간 경과 시뮬레이션 불가 · 실 세션 만료 테스트 환경 없음
High
로그아웃 후 세션 무효화
로그아웃 → 쿠키 삭제 → 보호 경로 접근 차단
SKIP: 로그인 세션 없이 로그아웃 테스트 불가
Medium
관리자 테스트 — 22개 항목 · PASS 11 / FAIL 2 / SKIP 9
🛡️ 관리자 로그인/RBAC (a1)
관리자 로그인 페이지 표시
GET /admin/login → 200 · 관리자/이메일/비밀번호 폼 렌더링 확인
Critical
비인증 접근 → 관리자 로그인 리다이렉트
GET /admin/shops → 302 → https://tire.habyapps.com/admin/login 리다이렉트
Critical
API 레벨 RBAC — 관리자 API 403 차단
GET /api/admin/shops (비인증) → 403 {"success":false,"error":"Forbidden"} · GET /api/admin/sellers → 403
Critical
🏬 가맹점 승인 (a2)
가맹점 API 인증 및 구조
GET /api/admin/shops → 403 · /api/admin/shops/[id] 라우트 존재 · fee-table API 존재
CriticalGET /api/admin/shops
관리자 가맹점 페이지 접근 구조
GET /admin/shops → 302 · GET /admin/sellers → 302 · 모든 관리자 경로 인증 보호
High
가맹점 승인 처리 UI
관리자 로그인 후 /admin/shops 목록 · 승인 버튼 동작
FAIL: NEXTAUTH_URL 도메인 설정으로 127.0.0.1 로그인 불가 · 인증 후 UI 테스트 불가
Critical
공임비 테이블 수정
PATCH /api/admin/shops/[id]/fee-table 관리자 테스트
SKIP: 인증 세션 없이 테스트 불가
High
가맹점 비활성화
isActive 토글 → 소비자 검색 결과에서 제외
SKIP: 인증 세션 없이 테스트 불가
High
👤 셀러 승인/빌링 제어 (a3)
셀러 API 인증 및 구조
GET /api/admin/sellers → 403 · /api/admin/sellers/[id] · /api/admin/sellers/[id]/subscription · billing-attempts 라우트 확인
CriticalGET /api/admin/sellers
billing charge API 존재
POST /api/billing/charge → 405 Method Not Allowed (GET 접근) · 라우트 등록 확인
HighPOST /api/billing/charge
셀러 구독 강제 취소
관리자 구독 취소 → 위젯 비활성화
FAIL: 인증 세션 없이 관리자 UI 테스트 불가
High
셀러 활성/비활성 토글
isActive 변경 후 셀러 로그인 차단 확인
SKIP: 인증 세션 없이 테스트 불가
High
빌링 시도 내역 조회
GET /api/admin/sellers/[id]/billing-attempts 목록 확인
SKIP: 인증 세션 없이 테스트 불가
Medium
📊 정산 관리 (a4)
정산 API 접근 제어
GET /api/settlements (비인증) → 403 {"success":false,"error":"권한 없음"}
CriticalGET /api/settlements
관리자 정산 페이지 접근 구조
GET /admin/settlements → 302 리다이렉트 · 인증 보호 확인
High
정산 처리 상태 변경
정산 PENDING → PAID 상태 변경
SKIP: 인증 세션 없이 테스트 불가
High
🖥️ 인프라/모니터링 (a5)
Health Check API
GET /api/health → 200 {"status":"ok","timestamp":"2026-05-23T16:02:58.965Z"}
CriticalGET /api/health
보안 헤더 설정 확인
X-Content-Type-Options: nosniff · X-Frame-Options: DENY · X-XSS-Protection: 1; mode=block · Referrer-Policy: strict-origin-when-cross-origin 전 경로 적용
High
HSTS 헤더 (Strict-Transport-Security)
HTTPS 환경에서 HSTS 헤더 확인
SKIP: 로컬 HTTP(127.0.0.1) 환경 · HSTS는 HTTPS에서만 유효
Medium
Content-Security-Policy 헤더
CSP 헤더 적용 확인
SKIP: next.config.ts에 CSP 미설정 — 추가 필요
Medium
Sentry 에러 추적 확인
런타임 에러 발생 시 Sentry 캡처
SKIP: SENTRY_ORG/PROJECT 미설정 · 외부 Sentry 대시보드 접근 불가
Medium
PM2 프로세스 모니터링
tire-web 메모리/CPU 사용량 임계치 확인
SKIP: 관리자 모니터링 대시보드 없음 · PM2 웹 인터페이스 미설정
Low
잔여 이슈 및 권고사항
⚠️ FAIL 항목 분석 (7건)
[c4] 예약 확정 E2E — OTP 토큰 통합 흐름
POST /api/bookings에 otpToken 필수 · Redis OTP 토큰 발급 없이 curl만으로 완전한 예약 확정 불가 · Playwright E2E 테스트 필요
[s2] 위젯 코드 복사 UI / [s3] 토스 빌링키 발급
NEXTAUTH_URL=https://tire.habyapps.com 설정으로 127.0.0.1 CSRF 검증 실패 → 로그인 세션 획득 불가 · 로컬 테스트 시 NEXTAUTH_URL=http://127.0.0.1:3003 임시 설정 권장
[p4] 정산 내역 / [p5] 세션 만료 / [a2] 가맹점 승인 UI / [a3] 셀러 구독 취소
공통 원인: NEXTAUTH_URL 도메인 설정으로 로컬 127.0.0.1 인증 세션 획득 불가 · 실 도메인 환경(tire.habyapps.com)에서는 정상 동작 예상
📋 SKIP 항목 분류 (23건)
외부 서비스 의존 (4건)
카카오 알림톡 실발송 · 토스 실결제/빌링키 발급 · SMS 실수신 확인 · FCM 푸시
클라이언트 인터랙션 필요 (10건)
GPS 권한 제어 · 지도 마커 클릭 · 캘린더 UI · SSE 실시간 수신 · 로그아웃 플로우 · 인증 후 페이지 UI
인증 세션 의존 (9건)
NEXTAUTH_URL 도메인 설정으로 로컬 127.0.0.1 세션 로그인 불가 · 모든 로그인 후 UI/기능 테스트