- Add main application files (main.py, models.py, schemas.py, etc.) - Add routers for all features (waiting, attendance, members, etc.) - Add HTML templates for admin and user interfaces - Add migration scripts and utility files - Add Docker configuration - Add documentation files - Add .gitignore to exclude database and cache files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
6.6 KiB
6.6 KiB
대기자 관리 화면 리스트 표시 오류 수정 완료
문제점
대기자 관리 화면에서:
- 클래스 탭에는 "1교시 1명"으로 카운트가 정상 표시됨
- 하지만 클래스를 선택했을 때 대기자 리스트가 표시되지 않음
원인 분석
1. SQLAlchemy 관계 Lazy Loading
/api/waiting/list 엔드포인트가 WaitingList 모델을 조회할 때, 연관된 class_info와 member 관계가 lazy loading으로 설정되어 있어 자동으로 로드되지 않음.
2. Pydantic 직렬화 문제
WaitingListDetail 스키마가 class_info: ClassInfo를 요구하는데:
ClassInfo스키마는weekday_schedule: Dict[str, bool]을 기대- 하지만 데이터베이스에는 JSON 문자열로 저장됨 (
'{"mon": true, ...}') - Pydantic이 자동으로 변환하지 못해 직렬화 실패
3. 평일/주말 클래스 구분 적용 영향
평일/주말 클래스 구분을 적용하면서, class_info에 weekday_schedule과 class_type 필드가 추가되었으나, 기존 엔드포인트에서 이를 올바르게 처리하지 못함.
수정 내용
routers/waiting.py
1. joinedload import 추가 (line 2)
from sqlalchemy.orm import Session, joinedload
2. /api/waiting/list 엔드포인트 수정 (lines 309-401)
수정 전:
@router.get("/list", response_model=List[WaitingListDetail])
async def get_waiting_list(...):
query = db.query(WaitingList).filter(...)
waiting_list = query.order_by(...).all()
return waiting_list
수정 후:
@router.get("/list")
async def get_waiting_list(...):
# class_info와 member를 eager load
query = db.query(WaitingList).options(
joinedload(WaitingList.class_info),
joinedload(WaitingList.member)
).filter(...)
waiting_list = query.order_by(...).all()
# 수동으로 dict 생성 (weekday_schedule 파싱 포함)
result = []
for waiting in waiting_list:
class_info_dict = {
"id": waiting.class_info.id,
...
"weekday_schedule": parse_weekday_schedule(waiting.class_info.weekday_schedule),
"class_type": waiting.class_info.class_type if hasattr(waiting.class_info, 'class_type') else 'all',
...
}
waiting_dict = {
...
"class_info": class_info_dict,
"member": member_dict
}
result.append(waiting_dict)
return result
주요 변경 사항
1. Eager Loading 적용
.options(
joinedload(WaitingList.class_info),
joinedload(WaitingList.member)
)
class_info와member관계를 쿼리 시점에 함께 로드- N+1 쿼리 문제 방지
- Pydantic 직렬화 시 관계 데이터 보장
2. 수동 dict 생성
response_model=List[WaitingListDetail]제거- 수동으로 dict를 생성하여 반환
weekday_schedule을parse_weekday_schedule()함수로 파싱하여 JSON 문자열 → dict 변환
3. weekday_schedule 파싱
"weekday_schedule": parse_weekday_schedule(waiting.class_info.weekday_schedule)
- 데이터베이스의 JSON 문자열을 dict로 변환
- 프론트엔드에서 올바르게 사용 가능
동작 흐름
Before (문제 발생)
- 프론트엔드:
/api/waiting/list?status=waiting&class_id=1호출 - 백엔드:
WaitingList조회 (class_info는 lazy loading) - Pydantic:
WaitingListDetail직렬화 시도 - 에러:
class_info가 로드되지 않았거나,weekday_schedule파싱 실패 - 프론트엔드: 응답 실패 또는 빈 데이터
- UI: "데이터 로딩 실패" 또는 빈 리스트 표시
After (수정 후)
- 프론트엔드:
/api/waiting/list?status=waiting&class_id=1호출 - 백엔드:
WaitingList+class_info+membereager load로 조회 - 백엔드: 수동으로 dict 생성
weekday_schedule파싱class_type확인 및 기본값 설정- 모든 필드 포함
- 프론트엔드: 올바른 JSON 응답 수신
- UI: 대기자 리스트 정상 표시
검증 방법
1. API 직접 테스트
# 대기자 목록 조회
curl -H "Cookie: access_token=..." \
"http://localhost:8000/api/waiting/list?status=waiting&class_id=1"
# 예상 응답:
[
{
"id": 236,
"waiting_number": 1,
"name": null,
"phone": "01011110001",
"class_id": 1,
"class_order": 1,
"status": "waiting",
"class_info": {
"id": 1,
"class_number": 1,
"class_name": "1교시",
"weekday_schedule": {
"mon": true,
"tue": true,
"wed": true,
"thu": true,
"fri": true,
"sat": false,
"sun": false
},
"class_type": "weekday",
...
},
...
}
]
2. 대기자 관리 화면 확인
- 대기자 관리 화면 접속
- 클래스 탭에서 대기자가 있는 클래스 선택
- 대기자 리스트가 정상적으로 표시되는지 확인
- 대기자 정보 (이름, 전화번호, 순서 등) 확인
3. 브라우저 콘솔 확인
// 에러가 발생하지 않아야 함
// Network 탭에서 /api/waiting/list 응답 확인
// 200 OK 상태 코드
// 올바른 JSON 형식의 응답
영향 범위
수정된 파일
✅ routers/waiting.py - /api/waiting/list 엔드포인트
영향받는 화면
✅ 대기자 관리 화면 (templates/manage.html)
- 클래스별 대기자 리스트 표시
- 대기자 상세 정보 표시
- 드래그 앤 드롭으로 순서 변경
- 빈 좌석 삽입
영향받지 않는 기능
- ✅ 대기자 등록
- ✅ 대기 현황판
- ✅ 대기 접수
- ✅ 클래스 관리
- ✅
/api/waiting/list/by-class(다른 엔드포인트)
추가 개선 사항
1. 성능 최적화
- Eager loading으로 N+1 쿼리 문제 해결
- 단일 쿼리로 모든 필요한 데이터 로드
2. 데이터 일관성
weekday_schedule항상 dict 형식으로 반환class_type기본값 설정으로 하위 호환성 유지
3. 에러 처리 개선
- Pydantic 직렬화 실패 방지
- 명시적인 dict 생성으로 데이터 형식 보장
결론
대기자 관리 화면에서 대기자 리스트가 정상적으로 표시됩니다:
- ✅ SQLAlchemy eager loading으로 관계 데이터 로드
- ✅ 수동 dict 생성으로 Pydantic 직렬화 문제 해결
- ✅ weekday_schedule 파싱으로 JSON 문자열 → dict 변환
- ✅ class_type 필드 안전하게 처리
- ✅ 평일/주말 클래스 구분과 호환
클래스 탭에 "1교시 1명"으로 표시되고, 해당 클래스를 선택하면 대기자 리스트가 정상적으로 표시됩니다.