1️⃣ 문제 상황
Spring Boot + JWT + Redis 기반 선착순 시스템을 구현하는 중,
다음과 같은 문제가 발생했다.
👉 대기열을 통과해서 입장권(ADMITTED)을 정상적으로 받은 상태인데도
/lectures/1/apply
페이지에 들어가면 아래 메시지가 출력됨:
"입장권이 없습니다. 상세 페이지에서 대기열부터 진행해주세요."
📌 이상한 점
Postman으로 확인했을 때는 정상이었다.
✅ API 결과
GET /api/lectures/1/queue/me
{
"status":"ADMITTED",
"lectureId":1
}
👉 즉, 서버에서는 분명히 입장권이 있다고 판단하고 있음
그런데 프론트에서는 “입장권 없음”이 뜨는 이상한 상황이었다.
2️⃣ 원인 분석
문제는 상태 값 통일 과정에서 발생한 프론트-백 불일치였다.
🔥 상태 변경 전
SUCCESS → 입장 가능
🔥 상태 변경 후
ADMITTED → 입장 가능
👉 서버는 SUCCESS -> ADMITTED 로 변경했는데
❌ apply.html 코드 (문제 코드)
if (data.status === "SUCCESS") {
tick();
setInterval(tick, 1000);
return true;
}
👉 여기서 아직도 SUCCESS를 보고 있었음
🚨 실제 동작 흐름
- 서버는 ADMITTED 반환
- 프론트는 SUCCESS만 체크
- 조건문 통과 못함
- 아래 코드 실행됨
showResult("fail","입장권이 없습니다...");
👉 그래서 입장권이 있는데도 없는 것처럼 보이는 버그 발생
3️⃣ 해결 방법
1) 상태값 통일
// 기존 (문제)
if (data.status==="SUCCESS") {
👉 변경
// 수정 (정상)
if (data.status==="ADMITTED") {
2) token.js 캐시 문제 해결 (추가 중요 포인트)
브라우저가 JS를 캐싱하면 이전 코드가 계속 실행될 수 있음
❌ 기존
<script src="/js/token.js"></script>
✅ 변경
<script th:src="@{/js/token.js(v=${#dates.createNow().time})}"></script>
👉 매번 다른 버전으로 로드해서 캐시 무력화
4️⃣ 최종 결과
- 입장권(ADMITTED) 상태에서 apply 페이지 진입 시
- 정상적으로 결제 타이머 실행
- 결제 버튼 활성화
👉 문제 해결 🎉
📌 배운 점 (중요)
1) 상태값은 반드시 백엔드-프론트 통일해야 한다
- SUCCESS / ADMITTED 혼용 → 버그 발생
- 상태값은 “약속”이다
2) API는 정상인데 UI가 이상하면 “조건문”을 의심하자
- 서버는 맞는데 화면이 틀리다?
- 👉 거의 90%는 프론트 분기 문제
3) JS 캐시 때문에 “고쳤는데 안 고쳐진 것처럼 보일 수 있다”
- 특히 token.js 같은 공통 스크립트
- 👉 반드시 캐시 무력화 필요
4) 상태 설계는 초기에 정리하는 게 중요하다
추천 상태:
QUEUED
ADMITTED
ENROLLED
NOT_IN_QUEUE
👉 이렇게 통일하면 유지보수 훨씬 쉬워짐
📌 한 줄 요약
👉 서버 상태값을 ADMITTED로 변경했는데, 프론트에서 SUCCESS를 계속 체크하고 있어서 발생한 버그였다.
'프로젝트 > 스프링 부트 3 백엔드 개발자 되기 Blog + 선착순 강의 프로젝트' 카테고리의 다른 글
| ⏰💡 관리자 기능 + UI (JWT Role기반) (0) | 2026.03.22 |
|---|---|
| ⏰💡 오픈 시간(openAt) 전에는 신청 버튼 막기 + 카운트다운 표시 (0) | 2026.03.07 |
| ⏰🚨 선착순 강의 신청에서 “이미 신청했는데 다시 신청 가능?” 문제 해결 (0) | 2026.03.06 |
| ⏰💡 선착순 강의 Redis 대기열(ZSET) + 입장권 원자화 + 소비(consume) 적용하기 (Lua 1개로 끝) (0) | 2026.02.26 |
| ⏰🚨 선착순 강의 신청 페이지에서 버튼이 동작하지 않던 문제 해결 (0) | 2026.02.23 |