Files
waiting-system/대기자관리_리스트_표시_수정완료.md
Jun-dev f699a29a85 Add waiting system application files
- 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>
2025-12-14 00:29:39 +09:00

6.6 KiB

대기자 관리 화면 리스트 표시 오류 수정 완료

문제점

대기자 관리 화면에서:

  • 클래스 탭에는 "1교시 1명"으로 카운트가 정상 표시됨
  • 하지만 클래스를 선택했을 때 대기자 리스트가 표시되지 않음

원인 분석

1. SQLAlchemy 관계 Lazy Loading

/api/waiting/list 엔드포인트가 WaitingList 모델을 조회할 때, 연관된 class_infomember 관계가 lazy loading으로 설정되어 있어 자동으로 로드되지 않음.

2. Pydantic 직렬화 문제

WaitingListDetail 스키마가 class_info: ClassInfo를 요구하는데:

  • ClassInfo 스키마는 weekday_schedule: Dict[str, bool]을 기대
  • 하지만 데이터베이스에는 JSON 문자열로 저장됨 ('{"mon": true, ...}')
  • Pydantic이 자동으로 변환하지 못해 직렬화 실패

3. 평일/주말 클래스 구분 적용 영향

평일/주말 클래스 구분을 적용하면서, class_infoweekday_scheduleclass_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_infomember 관계를 쿼리 시점에 함께 로드
  • N+1 쿼리 문제 방지
  • Pydantic 직렬화 시 관계 데이터 보장

2. 수동 dict 생성

  • response_model=List[WaitingListDetail] 제거
  • 수동으로 dict를 생성하여 반환
  • weekday_scheduleparse_weekday_schedule() 함수로 파싱하여 JSON 문자열 → dict 변환

3. weekday_schedule 파싱

"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 직접 테스트

# 대기자 목록 조회
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. 브라우저 콘솔 확인

// 에러가 발생하지 않아야 함
// 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명"으로 표시되고, 해당 클래스를 선택하면 대기자 리스트가 정상적으로 표시됩니다.