DOCS/journey/troubleshooting/251216_bayesian_presentation_ballquiz_redesign.md
happybell80 bf205f8b52 docs: 베이지안 발표 입력 필드 UX 개선 및 리셋 버튼 수정 내용 추가
- 입력값 유실 문제 해결 (서버 상태 동기화)
- 입력 중 덮어쓰기 방지 (포커스 필드 보호)
- 자동 저장 구현 (debounce 300ms)
- 리셋 버튼 정상 작동 (로컬 상태 초기화)
2025-12-17 15:58:59 +09:00

5.6 KiB
Raw Blame History

베이지안 프레젠테이션 BallQuiz 페이지 리디자인

날짜: 2025-12-16 작성자: happybell80 관련 파일:

  • bayesian-presentation/frontend/src/pages/BallQuizPage.tsx
  • bayesian-presentation/backend/app/services/state_service.py
  • bayesian-presentation/backend/main.py

문제 상황

1. Section 구조 복잡성

  • Section 1(초기 확률 입력)과 Section 2(공 꺼내기)가 분리되어 불필요한 단계 추가
  • 발표자가 두 번에 나눠 입력해야 하는 불편함

2. 셀 수정 불가 문제

  • 초기 확률과 회차별 확률이 읽기 전용으로 표시되는 경우 발생
  • isRoundCompleted 조건으로 인해 일부 셀만 수정 가능

3. 포트 충돌

  • 백엔드를 포트 8000에서 실행하려고 시도
  • 포트 8000은 다른 서비스(goosefarminvestment)가 사용 중
  • nginx 설정은 포트 3001로 프록시 설정되어 있음

4. 기본 section 설정 오류

  • Section 1 제거 후에도 백엔드 기본 section이 1로 유지
  • 프론트엔드에서 section 2로 시작하도록 변경했으나 백엔드와 불일치

5. 입력 필드 UX 문제 (2025-12-17 추가)

  • 입력값 유실: 페이지 새로고침/재연결 시 입력한 확률이 사라짐 (서버에는 저장되지만 화면에 표시 안 됨)
  • 입력 중 덮어쓰기: 입력 중 서버 state_update가 오면 아직 저장되지 않은 입력값이 사라짐
  • 리셋 버튼 미작동: 리셋 후에도 테이블의 입력값이 그대로 남아있어 초기화되지 않음

해결 방안

Section 1 제거 및 통합

  • BallQuizPage.tsx: Section 1 렌더링 코드 제거 (141-259줄)
  • Section 2에 초기 확률과 회차별 확률 입력 통합
  • "시뮬레이션 시작" 버튼 제거

모든 셀 수정 가능하도록 변경

  • BallQuizPage.tsx:174-219: isRoundCompleted 조건 제거, 모든 회차 셀을 항상 input 필드로 표시
  • BallQuizPage.tsx:120-164: 초기 확률도 항상 input 필드로 표시
  • 사용자 입력값 우선 반영 로직 개선

포트 충돌 해결

  • main.py: 백엔드 실행 포트를 3001로 변경
  • nginx 설정 확인: /bayesian-api/http://localhost:3001/
  • 포트 8000은 다른 서비스 사용 중이므로 사용 불가

기본 section 설정

  • state_service.py:26: 기본 section을 1 → 2로 변경
  • state_service.py:207: reset_state에서도 section 2로 초기화
  • 프론트엔드와 백엔드 일치

입력 필드 UX 개선 (2025-12-17)

  • 서버 상태로 로컬 상태 동기화: BallQuizPage.tsx:25-86 - useEffect로 서버 state_update 수신 시 participantInputs 동기화
  • 입력 중 필드 보호: BallQuizPage.tsx:22 - focusedInputRef로 포커스 중인 필드는 서버 업데이트로 덮어쓰지 않음
  • 자동 저장: BallQuizPage.tsx:94-120 - useEffect + debounce(300ms)로 입력값 자동 저장
  • 리셋 시 로컬 상태 초기화: BallQuizPage.tsx:26-29 - estimates가 빈 객체일 때 participantInputs도 빈 객체로 초기화

구현 완료

  • Section 1 제거 완료
  • 42개 셀(7명 × 6컬럼) 모두 수정 가능
  • 포트 3001로 백엔드 실행
  • 기본 section 2로 통일
  • 입력 필드 UX 개선 완료 (2025-12-17)
    • 새로고침/재연결 시 입력값 유지
    • 입력 중 서버 업데이트로 덮어쓰기 방지
    • 자동 저장으로 입력값 유실 방지
    • 리셋 버튼 정상 작동

교훈

포트 사용 전 확인 필수

  • 원인: nginx 설정과 백엔드 포트를 확인하지 않고 포트 8000 사용 시도
  • 교훈:
    • 포트 사용 전 netstat 또는 ss 명령어로 사용 중인 포트 확인
    • nginx 설정 파일에서 프록시 포트 확인 (/etc/nginx/sites-enabled/default)
    • 다른 서비스와 충돌하지 않는 포트 사용
  • 원칙: 312_문서_작성_원칙.md - 확인된 사실만 기록

프론트엔드/백엔드 기본값 일치 확인

  • 원인: Section 1 제거 후 프론트엔드만 section 2로 변경, 백엔드는 section 1 유지
  • 교훈:
    • 상태 관련 기본값 변경 시 프론트엔드와 백엔드 모두 확인
    • state_service.py의 초기값과 프론트엔드 기본값 일치 확인
  • 원칙: 311_FastAPI_구조_원칙.md - 상태 관리 일관성

사용자 요구사항 명확히 이해

  • 원인: "엑셀처럼 수정 가능하게" 요구사항을 여러 번 반복 요청
  • 교훈:
    • 읽기 전용 셀(isRoundCompleted 조건)을 제거하고 모든 셀을 항상 input 필드로 표시
    • 사용자가 "엑셀처럼"이라고 표현할 때는 모든 셀을 클릭해서 바로 수정 가능해야 함
  • 원칙: 사용자 의도 파악 후 구현

브라우저 직접 확인 습관화

  • 원인: 코드 수정 후 브라우저에서 직접 확인하지 않고 가정으로 진행
  • 교훈:
    • Playwright를 사용한 자동화 테스트로 브라우저 상태 확인
    • 코드 변경 후 반드시 실제 브라우저에서 동작 확인
  • 원칙: AGENTS.md - 직접 확인 후 진행

서버 상태 리셋 시 로컬 상태도 초기화 필수

  • 원인: reset_state로 서버 estimates{}로 초기화되지만, 프론트엔드 useEffect 동기화 로직에서 빈 객체일 때 early return하여 participantInputs가 초기화되지 않음
  • 교훈:
    • 서버 상태가 빈 객체로 리셋될 때는 로컬 상태도 명시적으로 초기화해야 함
    • useEffect에서 early return 전에 빈 객체 체크 후 로컬 상태 초기화 로직 추가
  • 원칙: 313_React_구조_원칙.md:100-104 - 프론트엔드/백엔드 상태 동기화