# 대기자 관리 화면 리스트 표시 오류 수정 완료 ## 문제점 대기자 관리 화면에서: - 클래스 탭에는 "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](routers/waiting.py:1-401) #### 1. joinedload import 추가 (line 2) ```python from sqlalchemy.orm import Session, joinedload ``` #### 2. `/api/waiting/list` 엔드포인트 수정 (lines 309-401) **수정 전:** ```python @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 ``` **수정 후:** ```python @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 적용 ```python .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 파싱 ```python "weekday_schedule": parse_weekday_schedule(waiting.class_info.weekday_schedule) ``` - 데이터베이스의 JSON 문자열을 dict로 변환 - 프론트엔드에서 올바르게 사용 가능 ## 동작 흐름 ### Before (문제 발생) 1. 프론트엔드: `/api/waiting/list?status=waiting&class_id=1` 호출 2. 백엔드: `WaitingList` 조회 (class_info는 lazy loading) 3. Pydantic: `WaitingListDetail` 직렬화 시도 4. **에러**: `class_info`가 로드되지 않았거나, `weekday_schedule` 파싱 실패 5. 프론트엔드: 응답 실패 또는 빈 데이터 6. UI: "데이터 로딩 실패" 또는 빈 리스트 표시 ### After (수정 후) 1. 프론트엔드: `/api/waiting/list?status=waiting&class_id=1` 호출 2. 백엔드: `WaitingList` + `class_info` + `member` eager load로 조회 3. 백엔드: 수동으로 dict 생성 - `weekday_schedule` 파싱 - `class_type` 확인 및 기본값 설정 - 모든 필드 포함 4. 프론트엔드: 올바른 JSON 응답 수신 5. UI: 대기자 리스트 정상 표시 ## 검증 방법 ### 1. API 직접 테스트 ```bash # 대기자 목록 조회 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. 대기자 관리 화면 확인 1. 대기자 관리 화면 접속 2. 클래스 탭에서 대기자가 있는 클래스 선택 3. 대기자 리스트가 정상적으로 표시되는지 확인 4. 대기자 정보 (이름, 전화번호, 순서 등) 확인 ### 3. 브라우저 콘솔 확인 ```javascript // 에러가 발생하지 않아야 함 // 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 생성으로 데이터 형식 보장 ## 결론 **대기자 관리 화면에서 대기자 리스트가 정상적으로 표시됩니다:** 1. ✅ SQLAlchemy eager loading으로 관계 데이터 로드 2. ✅ 수동 dict 생성으로 Pydantic 직렬화 문제 해결 3. ✅ weekday_schedule 파싱으로 JSON 문자열 → dict 변환 4. ✅ class_type 필드 안전하게 처리 5. ✅ 평일/주말 클래스 구분과 호환 **클래스 탭에 "1교시 1명"으로 표시되고, 해당 클래스를 선택하면 대기자 리스트가 정상적으로 표시됩니다.**