🔐
회원 / 인증 POST /auth/signup · /auth/login · /auth/refresh · /auth/logout · /auth/oauth/:provider
0 / 16
TC-001
HIGH
정상 회원가입 — 유효한 이메일·비밀번호 8자 이상·닉네임 2~50자
201 · accessToken/refreshToken 발급 · users.status=ACTIVE · role=USER
TC-002
MEDIUM
중복 이메일 가입 차단
409 EMAIL_ALREADY_EXISTS
TC-003
MEDIUM
비밀번호 8자 미만 차단 (7자 이하 입력)
422 VALIDATION_ERROR
TC-004
MEDIUM
닉네임 2자 미만 차단 (1자 입력)
422 VALIDATION_ERROR
TC-005
MEDIUM
닉네임 50자 초과 차단 (51자 입력)
422 VALIDATION_ERROR
TC-006
MEDIUM
이메일 형식 불일치 차단 (notanemail 입력)
422 VALIDATION_ERROR
TC-007
HIGH
카카오 소셜 로그인 — 유효한 인가 코드 전달
200 · accessToken/refreshToken · users.oauth_provider=KAKAO
TC-008
HIGH
구글 소셜 로그인 — 유효한 인가 코드 전달
200 · users.oauth_provider=GOOGLE
TC-009
HIGH
동일 소셜 계정 재로그인 → 신규 레코드 미생성
(oauth_provider, oauth_subject) UNIQUE 정합 · 기존 계정 조회 후 토큰 재발급
TC-010
HIGH
Access Token 만료 → Refresh Token으로 갱신
200 · 신규 accessToken/refreshToken 발급
TC-011
HIGH
유효하지 않은 Refresh Token → 갱신 차단
401 INVALID_REFRESH_TOKEN
TC-012
MEDIUM
로그아웃 — DELETE /api/v1/auth/logout
204 · 클라이언트 토큰 삭제 · JTI 무효화(v0.2.2)
TC-013
HIGH
만 19세 미만 가입 차단 — 18세 이하 birth_date 입력
422 UNDERAGE_USER
TC-014
HIGH
만 19세 이상 가입 허용 — 만 19세 정확히 도달한 birth_date
201 · 정상 가입
TC-015
MEDIUM
회원 탈퇴 — DELETE /api/v1/users/me
204 · users.status=WITHDRAWN · withdrawn_at 기록 · soft delete
TC-016
LOW
탈퇴 후 동일 이메일 재가입 — 구현 정책 확인
PRD 미결 항목 — 구현 정책 따름
🎯
매칭 POST /matchings · GET /matchings · POST /matchings/:id/requests · POST /users/me/submall
0 / 13
TC-017HIGH
HOST 서브몰 등록 → 역할 자동 승격200 · users.sub_mall_id 기록 · role: USER → HOST
TC-018MEDIUM
중복 서브몰 ID 등록 차단409 SUBMALL_ID_TAKEN
TC-019HIGH
HOST 역할 미등록 상태에서 매칭 등록 시도 (role=USER)403 FORBIDDEN
TC-020HIGH
매칭 등록 참여비 0원 차단 (entry_fee:0)422 VALIDATION_ERROR (D-16: 0원 불허)
TC-021MEDIUM
매칭 등록 참여비 1원201 · matchings.status=OPEN
TC-022HIGH
매칭 등록 정상 (entry_fee:10000, 전체 필드 유효)201 · matchings.status=OPEN 레코드 생성
TC-023MEDIUM
cursor 페이지네이션 — limit=10 → nextCursor → 다음 10건중복 없음 · nextCursor 연속 동작
TC-024LOW
카테고리 필터 — ?category=스포츠해당 카테고리 매칭만 반환
TC-025LOW
날짜 필터 — ?date=<날짜>해당 날짜 예정 매칭만 반환
TC-026LOW
키워드 검색 — ?keyword=풋살제목/설명에 "풋살" 포함 매칭만 반환
TC-027HIGH
자기 매칭 신청 차단 — HOST가 자신의 매칭에 신청403 FORBIDDEN
TC-028HIGH
중복 신청 차단 — 동일 USER·동일 매칭 2회 신청409 DUPLICATE_REQUEST
TC-029HIGH
ACCEPTED 존재 시 추가 신청 차단422 MATCHING_ALREADY_ACCEPTED
💬
채팅 Socket.IO /chat · /matching · GET /chat-rooms/:id/messages
0 / 11
TC-030HIGH
Socket.IO 연결 (JWT handshake)연결 성공 · connect 이벤트 수신
TC-031HIGH
유효하지 않은 JWT로 Socket.IO 연결 시도연결 거부 · connect_error 이벤트
TC-032HIGH
실시간 메시지 송수신 — HOST 전송 → USER 앱 실시간 수신chat:message-received 이벤트 수신 및 메시지 표시
TC-033MEDIUM
메시지 DB 영속성 — 전송 후 REST API로 조회GET /chat-rooms/:id/messages → DB에 메시지 기록 확인
TC-034MEDIUM
Socket.IO 재연결 후 누락 메시지 REST 보완 조회?after=<lastMessageId> → 누락 없이 모든 메시지 표시
TC-035CRITICAL
양측 확정 버튼 — HOST·USER 순서대로 확정matching_requests.status=ACCEPTED · matchings.status=CONFIRMED · matching:confirmed 양측 수신
TC-036HIGH
동시 확정 race condition — 동시에 확정 버튼 클릭ACCEPTED 전이 정확히 1회 · 나머지 4xx
TC-037HIGH
CONFIRMED 30분 미결제 → 자동 취소matchings.status=CANCELLED · matching_requests.status=CANCELLED_BY_TIMEOUT · SYSTEM 메시지 자동 삽입
TC-038MEDIUM
채팅 이미지 업로드 허용 형식 (JPEG/PNG/WebP · 5MB 이하)200 · image_url 반환 · chat_messages.type=IMAGE
TC-039MEDIUM
이미지 업로드 5MB 초과 차단422 FILE_TOO_LARGE
TC-040CRITICAL
이미지 magic bytes 불일치 차단 — 확장자 .jpg이나 JPEG magic bytes 불일치422 INVALID_FILE_TYPE (확장자만으로 통과 불가 · magic bytes 검증 필수)
💳
결제 / 에스크로 POST /payments · POST /payments/webhook · GET /payments/:id
0 / 6
TC-041CRITICAL
Sandbox 카드 결제 성공 → SUCCEEDED + HELDpayments.status=SUCCEEDED · escrow_holds.status=HELD · chat:escrow-held Socket.IO 이벤트
TC-042HIGH
결제 실패 → FAILEDpayments.status=FAILED · 채팅방 결제 실패 시스템 메시지
TC-043CRITICAL
Webhook 중복 수신 (동일 transmission-id) → 1회만 처리webhook_events 1건 · payments 상태 변경 1회 · escrow_holds 생성 1건
TC-044HIGH
EXPIRED 상태 결제에 늦은 성공 Webhook → SUCCEEDED 복귀payments.status: EXPIRED → SUCCEEDED · escrow_holds.status=HELD 생성
TC-045CRITICAL
Webhook 발신 IP 검증 실패 → 401허용 IP 화이트리스트 외 IP → 401 UNAUTHORIZED_WEBHOOK_IP
TC-046CRITICAL
결제 후 에스크로 APPROVED → 정산 PENDING → 7일 → PAIDCOMPLETED 처리 → escrow_holds: HELD→APPROVED · settlements: PENDING_HOLD → (7일 후) PAID
💰
정산 / 환불 / 분쟁 POST /refunds · POST /disputes · GET /settlements
0 / 9
TC-047HIGH
노쇼 환불율 0% — 참여자 노쇼 시 환불 요청refunds.amount=0 (위약금 전액)
TC-048HIGH
참여자 D-7 이전 취소 → 100% 환불refunds.amount=payment.amount
TC-049HIGH
참여자 D-3 이내 취소 → D-03 정책 환불율 적용D-03 확정값 기반 환불율 적용
TC-050HIGH
주최자 일방 취소 → 100% 환불refunds.amount=payment.amount
TC-051HIGH
PRE_SETTLEMENT 분쟁 → RESOLVED_REFUND 처리escrow_holds.status=CANCELLED · refunds INSERT · settlements 미생성 (원자적 취소)
TC-052HIGH
POST_SETTLEMENT 분쟁 7일 내 신청 → ON_HOLDsettlements.status: PENDING_HOLD → ON_HOLD
TC-053HIGH
POST_SETTLEMENT 분쟁 → 관리자 RESOLVED_REFUND → FAILEDsettlements.status=FAILED · post_settlement_refunds INSERT · escrow_holds 변경 없음
TC-054HIGH
POST_SETTLEMENT 분쟁 → 관리자 RESOLVED_RELEASE → PAIDsettlements.status=PAID (기각 결정)
TC-055HIGH
7일 보류 윈도우 경과 → 자동 PAIDhold_release_at 경과 · 분쟁 없으면 스케줄러 → settlements.status=PAID
🚩
신고 / 감사 로그 POST /reports · GET /reports/me · GET /admin/audit-logs
0 / 4
TC-056MEDIUM
일일 10건 초과 신고 → 차단 (L-05)11번째 신고 → 429 DAILY_REPORT_LIMIT_EXCEEDED 또는 422
TC-057MEDIUM
동일 대상 7일 내 중복 신고 → 차단409 DUPLICATE_REPORT
TC-058HIGH
관리자 처리 행위 → audit_logs 자동 기록actor_id · action · target_type · target_id · before_state · after_state 모두 채워짐
TC-059HIGH
SUPERADMIN 전용 audit_logs 조회 (ADMIN → 403)ADMIN 접근 → 403 FORBIDDEN · SUPERADMIN → 200
⭐
리뷰 POST /reviews · GET /reviews?userId=
0 / 6
TC-060HIGH
COMPLETED 매칭만 리뷰 가능 — 비완료 매칭에 리뷰 시도409 MATCHING_NOT_COMPLETED
TC-061MEDIUM
리뷰 14일 기한 초과 → 422 (L-04)completed_at + 14일 경과 후 리뷰 시도 → 422 REVIEW_PERIOD_EXPIRED
TC-062MEDIUM
중복 리뷰 작성 → 409동일 매칭·동일 사용자 2회 → 409 REVIEW_ALREADY_EXISTS
TC-063MEDIUM
별점 범위 검증 — 0 또는 6 입력400 VALIDATION_ERROR (허용 범위: 1~5)
TC-064MEDIUM
코멘트 500자 초과 → 400 (501자 입력)400 VALIDATION_ERROR
TC-065MEDIUM
정상 리뷰 작성 — COMPLETED · 14일 이내 · 별점 1~5 · 코멘트 ≤500자201 · reviews 테이블 레코드 생성
🛡️
관리자 웹 E2E Vue 3 · Chrome 최신 버전 기준
0 / 10
TC-066HIGH
관리자 로그인 → 대시보드 진입가입자 수·매칭 성사율·결제 총액·신고/분쟁 건수 정상 표시 · 기간 필터 동작
TC-067HIGH
인증 가드 — 미로그인 상태로 직접 URL 접근로그인 페이지로 리다이렉트
TC-068HIGH
회원 정지 → Flutter 앱 401 반환users.status=SUSPENDED → 해당 회원 API 요청 시 401 INACTIVE_ACCOUNT
TC-069HIGH
매칭 강제 취소 → 상태 변경matchings.status=CANCELLED · cancel_reason 기록 · 관리자 웹 목록 즉시 반영
TC-070MEDIUM
장소 승인/반려 — PENDING 장소 목록 → 승인/반려 클릭승인: places.status=APPROVED · 반려: places.status=REJECTED
TC-071HIGH
분쟁 처리 — decision + note 필수 검증decision 없이 저장 → 차단 · note 없이 저장 → 차단 · 모두 입력 후 저장 → 처리 완료
TC-072HIGH
SUPERADMIN 전용 메뉴 — ADMIN 로그인 시 감사 로그·관리자 계정 관리 미표시403 또는 메뉴 미표시
TC-073HIGH
SUPERADMIN 계정 정상 접근 — 감사 로그·관리자 계정 관리 정상 표시200 · 조회 가능
TC-074LOW
URL 쿼리 파라미터 ↔ 필터/검색 양방향 동기화필터 적용 → URL 반영 · 직접 URL 입력 → 동일 필터 복원
TC-075MEDIUM
TypeScript strict 모드 빌드 통과npm run type-check → 에러 0건 · npm run build → 빌드 성공
🔒
보안 패치 검증 v0.2.2 Task-078 — P0~P3 수정 항목 검증
0 / 10
TC-076CRITICAL
[P0-1] Webhook HMAC 타이밍 공격 방어 — crypto.timingSafeEqual 적용
유효한 HMAC signature → 200 · 위조된 signature → 401 (timing-safe 비교로 타이밍 공격 방어)
TC-077CRITICAL
[P0-2] POST_SETTLEMENT 분쟁 상태 범위 수정 — APPROVED/PAID/ON_HOLD/PENDING_HOLD 포함
settlements.status=APPROVED 또는 PAID 상태에서도 분쟁 신청 → PRE/POST 분류 정확
TC-078CRITICAL
[P0-3] CORS allowlist 강화 — ALLOWED_ORIGINS 환경변수 기반 명시적 허용
허용 origin → CORS 통과 · 미허용 origin (e.g. evil.com) → CORS 오류 (Access-Control-Allow-Origin 없음)
TC-079CRITICAL
[P0-4] 분쟁+에스크로 취소 원자적 처리 — 단일 Prisma $transaction
RESOLVED_REFUND 처리 시 dispute.update + escrow.cancel + refund.create 모두 단일 트랜잭션 · DB 중간 상태 없음
TC-080HIGH
[P1-1] 로그인 Rate Limit — 5회/15분 초과 시 차단
동일 IP에서 6번째 로그인 실패 시도 → 429 Too Many Requests
TC-081HIGH
[P1-2] JTI 기반 토큰 무효화 — 로그아웃 후 재사용 차단
로그아웃 후 동일 refreshToken으로 재발급 시도 → 401 INVALID_REFRESH_TOKEN (JTI 불일치)
TC-082HIGH
[P1-3] 이미지 URL 도메인 화이트리스트 — 외부 URL 주입 차단
허용 도메인 이미지 URL → 메시지 전송 성공 · 외부 임의 URL → 400/422 거부
TC-083CRITICAL
[P1-4] 부분 환불 PG 호출 선행 — 토스페이먼츠 실제 취소 후 DB 기록
refund 요청 시 토스페이먼츠 cancelPayment 호출 성공 후 refunds 테이블 INSERT (PG 실패 시 DB 기록 없음)
TC-084HIGH
[P2-1] WebView XSS 방어 — </script> 인젝션 차단
주문명에 </script> 포함 시 _jsString()이 <\/ 로 이스케이프 → WebView HTML XSS 불가
TC-085HIGH
[P2-2] PM2 스케줄러 분리 — match-scheduler 단일 프로세스 독립 실행
pm2 list → match-api (cluster 2) + match-scheduler (fork 1) 각각 실행 · 중복 스케줄 실행 없음