보장분석 PDF 로컬 E2E 런북

Runbook · 수동 E2E

보장분석 PDF 출력
로컬 수동 E2E

FE·BE 두 레포를 feat/pdf-output 브랜치로 맞추고 로컬 서버를 띄운 뒤, 결과 출력 화면의 병합 PDF 미리보기·다운로드를 개발계 실데이터로 통과시키는 절차입니다.

브랜치 feat/pdf-output DB trddev_v2 (개발계) APLUS_READONLY=1 · 쓰기 차단 FE :3000 · BE :8000 소요 약 15분
진행 0/0

사내망(또는 VPN)이 없으면 진행 불가. 개발 DB 192.168.252.229:3306 · 개발 EAI 192.168.252.216:8951 에 도달해야 합니다. 안 붙으면 로그인이 ReadTimeout 으로 죽고 모든 장표가 빈 페이지로 나옵니다.

nc -z -w2 192.168.252.229 3306 && nc -z -w2 192.168.252.216 8951
00

브랜치 체크아웃

FE·BE 둘 다 feat/pdf-output 에서 진행합니다.

FE

aplus-bojangplus-nextjs-frontend

cd aplus-bojangplus-nextjs-frontend
git checkout feat/pdf-output
pnpm install        # 브랜치 전환 시 필수 — ag-grid-enterprise 등 누락 방지
rm -rf .next        # 다른 브랜치의 스테일 .next 정리

npm·yarn 금지. preinstall 가드가 설치를 중단합니다. React 19 ↔ next-auth peer 충돌로 npm 은 애초에 설치가 안 됩니다.

BE

aplus-bojangplus-python-backend

cd ../aplus-bojangplus-python-backend
git checkout feat/pdf-output
uv venv && source .venv/bin/activate   # .venv 이미 있으면 source 만
uv pip install -e ".[dev]"
01

로컬 서버 기동

터미널 2개를 씁니다. BE 를 먼저 띄우세요.

A

BE — 포트 8000

cd aplus-bojangplus-python-backend
APLUS_ENV=local .venv/bin/uvicorn app.main:app --reload --port 8000
기대 신호 터미널에 Application startup complete. Swagger 는 http://localhost:8000/docs
B

FE — 포트 3000 (고정)

cd aplus-bojangplus-nextjs-frontend
NEXTAUTH_URL=http://localhost:3000/web-user/api/auth pnpm dev --port 3000
기대 신호 Ready in ... · 접속 http://localhost:3000/web-user/login

포트 3000 을 꼭 지켜주세요. BE .env.localAPLUS_CORS_ORIGINS=http://localhost:3000 이라 3434 등으로 띄우면 클라이언트 조회가 CORS 로 막힙니다. FE .env.local(팀 공용, 3434)은 수정하지 말고 위처럼 환경변수로만 덮으면 됩니다.

FE .env.localNEXT_PUBLIC_MOCK=0 · API_BASE=http://localhost:8000 인지 확인하세요. mock↔live 전환은 HMR 로 반영되지 않으니 값을 바꿨으면 pnpm dev 를 완전히 재시작합니다.

기동 확인 (선택)

curl -s -o /dev/null -w "BE:%{http_code}\n" http://localhost:8000/docs
curl -s -o /dev/null -w "FE:%{http_code}\n" http://localhost:3000/web-user/login

둘 다 200 이면 진행합니다. http://localhost:3000/ 가 404 인 건 정상 — basePath 가 /web-user 입니다.

02

수동 E2E 6단계

계정 80032273 / __dev__ · 검증 고객 2602089632(이천구, 39페이지)

1

로그인

http://localhost:3000/web-user/login → ID 80032273 · PW __dev__

기대 신호 /web-user/main 리다이렉트 + BE 터미널에 POST /auth/dev-login ... 200
2

결과 출력 진입

http://localhost:3000/web-user/analysis/2602089632/report-output
기대 신호 좌측 페이지 목록 로드 · 카운터 13/39 · 페이저 1 / 39

첫 진입 12~13초는 정상입니다. 네트워크 탭에서 proposal 응답 헤더 X-Manifest-Cache: miss 를 확인하세요. 같은 고객으로 재진입하면 hit 이고 2.2초로 떨어집니다.

전후비교 5행이 번호 · “출력 불가” 로 뜨는 것도 정상입니다 (이 고객은 전=후).

3

썸네일 클릭 → 우측 뷰어

좌측 목록에서 썸네일 아이콘을 클릭합니다.

기대 신호 우측 큰 뷰어의 캔버스가 그 페이지로 교체. 여러 페이지 장표는 1 / 2 페이지 배지로 구분
4

페이지 선택 → “선택 완료”

그래프 1장을 체크해 카운터가 13 → 14 로 오르는지 본 뒤 선택 완료 를 누릅니다.

기대 신호 미리보기 다이얼로그 헤드라인이 처음부터 “선택한 14페이지” (구 7→N 전환은 없어졌습니다)

300px 단위로 천천히 스크롤하세요. 크게 점프하면 IntersectionObserver(rootMargin 300px)가 스쳐 간 카드를 그리지 않아 빈 카드로 오판하게 됩니다 — 앱 버그가 아닙니다.

5

다운로드

기대 신호 보장분석리포트_2602089632.pdf 저장 · 페이지 수가 카운터와 동일 (약 4.87MB)
6

콘솔 확인

기대 신호 에러 0건
  • /web-user/api/v2/rpa/status 404 는 이 화면과 무관한 기존 잡음입니다.
  • dev 에서 PDF 가 2회 요청되는 건 React StrictMode 때문이고, AbortController 가 첫 요청을 실제로 끊습니다 (운영 빌드는 1회).
03

판정 기준

여기가 가장 자주 어긋나는 부분입니다.

바이트로 판정하지 않습니다. 표시본 캐시가 프로세스 로컬이라, BE 를 재기동하면 크기는 같아도(5,059,069 bytes) 바이트가 달라지고 renderId 도 바뀝니다. 배포 형태에 따라 의미가 달라지는 값은 회귀 판정에 쓸 수 없습니다.

판정 항목보는 법기대
페이지 수manifest totalPages vs pdf.js numPages (usePdfDocument)39 / 39
장표 매핑page ↔ chk 키가 밀리지 않았는지일치
텍스트 멀티셋미리보기 vs 다운로드 토큰 비교차이 0
renderId 대조판정에 쓰지 않음
바이트 / sha256판정에 쓰지 않음

실질 가드는 totalPages vs numPages 입니다 — 우리가 실제로 두려워하는 실패(page↔장표 매핑이 밀림)를 직접 검출하기 때문입니다.

04

전후비교까지 볼 경우

▼감소 · 무변동 · ▲증가 델타 확인

02 의 고객(이천구)은 countConsulting=0 이라 전=후 degenerate 입니다. 델타를 보려면 계정부터 바꿔야 합니다.

쓸 곳로그인 TFA고객 insuredSeq근거
결과 출력 E2E (기본)800322732602089632 이천구39페이지, chk11 정상
전후비교 델타800028881809216008 이길자계약수 6→4, 보장률 17.78→28.48, 월납 +50,500
전후비교 차선800028882308223840 서수현월납 +27,251, 보장률 34.46→38.14

__dev__ 는 fixture 에 있는 설계사만 열립니다. 실측: 80032273 · 80002888 · 99999052 = 200 / 80009991 · 99999032 = 404. fixture 밖 계정의 고객을 보려면 브라우저 대신 05 의 스크립트를 씁니다.

전후비교 게이트가 열린 (TFA, 고객) 조합은 개발계에 11건뿐입니다.

05

로그인 없이 PDF 만 뽑기

브라우저·로그인 없이 BE 렌더 서비스를 직접 호출합니다. 가장 빠른 경로.

cd aplus-bojangplus-python-backend
APLUS_ENV=local APLUS_READONLY=1 .venv/bin/python scripts/render_one.py "이천구" 80032273 chk03,chk04,chk07
# → scripts/out/보장분석Report_2602089632.pdf
  • 1번 인자가 이름이면 WORLD_CUST_ID 를 자동 조회하고, 숫자insuredSeq 를 직접 지정합니다(동명이인 회피).
  • APLUS_READONLY=1 그대로 안전합니다 — SELECT-only, DB 쓰기 없음.

insuredSeqtb_trd_cust.CUST_SEQ 가 아니라 WORLD_CUST_ID 입니다. 잘못 넘기면 조회가 0행이 되어 장표가 전부 빈 페이지로 렌더됩니다. 개발계에는 이 값이 NULL·빈값인 고객이 2,774명 있습니다.

자주 걸리는 것

증상 → 원인·해결

증상원인 · 해결
http://localhost:3000/ 가 404basePath /web-user 필요 — /web-user/login 으로 접속
__dev__ 로그인 404BE /auth/dev-login 미복원 — BE 패치 적용 필요
__dev__ 로그인 401개발 EAI 가 해당 컨설턴트 미인지(get_user_list 빈 결과) — fixture 계정 사용
BE 가 ReadTimeout / 멈춤APLUS_EAI_DEST 누락 — 개발 EAI 는 EAI-Dest 헤더 필수
JWT_SESSION_ERROR: decryption failedNEXTAUTH_SECRET 미설정·변동 + 스테일 쿠키 — 고정 시크릿 설정 후 사이트 데이터 클리어
type-check·빌드에 ag-grid-enterprise 오류다른 브랜치의 node_modules·.next 잔존 — pnpm install + rm -rf .next
NEXT_PUBLIC_MOCK 바꿨는데 반영 안 됨dev 서버 완전 재시작 (HMR 미반영)
첫 진입 스켈레톤이 10초 이상정상 — BE manifest 캐시 miss(실측 12~13s). 헤더 X-Manifest-Cache 로 확인
미리보기 카드 일부가 빈 플레이스홀더스크롤을 크게 점프한 경우 — 300px 단위로 천천히 스크롤하면 전부 렌더
다운로드가 미리보기와 바이트가 다름그 사이 BE 재기동·다른 워커. 애초에 바이트로 판정하지 않음 (03 참조)
chk11 에 다른 계약자 데이터운영 DB 한정 BE 데이터경로 블로커. 개발계에서는 재현되지 않습니다. FE 버그 아님
Live 미리보기 빈 화면 / 404BE DB 에 해당 고객 데이터 없음, 또는 API_BASE 오설정