# Phase 8. 검증 및 안정화 ## 1. 목표 `docs/plan/project-plan.md`의 `Phase 8. 검증 및 안정화`를 수행하기 위한 검증 항목과 실행 절차를 정리한다. Phase 8의 목표는 다음 항목을 확인하는 것이다. - 승인/취소/거절 API가 트랜잭션으로 처리되는지 확인 - 이미 처리된 신청을 재처리할 때 `409` 오류로 막히는지 확인 - 비인증 접근이 차단되는지 확인 - Synology NAS Docker 재시작 후 정상 동작하는지 확인 ## 2. 코드 검증 결과 ### 2-1. 연장 신청 처리 대상 파일: - `lib/extension-requests.ts` - `app/api/extension-requests/[id]/route.ts` 확인 내용: - 승인 처리는 `db.$transaction()` 안에서 실행된다. - 취소 처리는 `db.$transaction()` 안에서 실행된다. - 처리 대상 조회 시 `maestro_extension.Status`가 `REQUEST_STATUSES.REQUESTED`인지 확인한다. - 이미 처리된 건은 `ExtensionRequestActionError`를 던지고 API route에서 `409`로 응답한다. - API route는 `auth()` 세션이 없으면 `401`로 응답한다. ### 2-2. 업그레이드 신청 처리 대상 파일: - `lib/upgrade-requests.ts` - `app/api/upgrade-requests/[id]/route.ts` 확인 내용: - 승인 처리는 `db.$transaction()` 안에서 실행된다. - 거절 처리는 `db.$transaction()` 안에서 실행된다. - 처리 대상 조회 시 `maestro_upgrade.Status`가 `REQUEST_STATUSES.REQUESTED`인지 확인한다. - 이미 처리된 건은 `UpgradeRequestActionError`를 던지고 API route에서 `409`로 응답한다. - API route는 `auth()` 세션이 없으면 `401`로 응답한다. ### 2-3. 인증 프록시 대상 파일: - `proxy.ts` 확인 내용: - `/login`만 공개 경로로 둔다. - 비로그인 사용자가 관리자 경로에 접근하면 `/login?callbackUrl=...`로 이동한다. - HTTPS 배포 환경에서 Auth.js secure session cookie를 읽도록 `secureCookie`를 설정한다. ## 3. 실행 검증 절차 ### 3-1. 로컬 기본 검증 ```bash pnpm lint pnpm build pnpm db:check ``` ### 3-2. 비인증 접근 차단 확인 스테이지 도메인에서 비로그인 상태 또는 시크릿 창으로 확인한다. ```bash curl -I https://stage-chocoadmin.jinaju.com/maestros ``` 기대 결과: - `/login?callbackUrl=%2Fmaestros`로 리다이렉트된다. ### 3-3. 로그인 후 화면 확인 브라우저에서 확인한다. - `https://stage-chocoadmin.jinaju.com/login` - `/maestros` - `/extension-requests` - `/upgrade-requests` 로그인 후 `ERR_TOO_MANY_REDIRECTS`가 발생하면 다음을 확인한다. - `.env.stage`의 `AUTH_URL` - `.env.stage`의 `NEXTAUTH_URL` - Nginx Proxy Manager의 forward target - 브라우저 쿠키 삭제 여부 ### 3-4. 중복 처리 방지 확인 스테이지 DB에서 테스트 가능한 요청 건을 대상으로 진행한다. 1. `/extension-requests` 또는 `/upgrade-requests`에서 `요청` 상태 건을 선택한다. 2. 승인/취소/거절 중 하나를 실행한다. 3. 같은 요청에 같은 액션을 다시 실행한다. 4. 두 번째 요청이 실패하는지 확인한다. 기대 결과: - 첫 번째 요청은 성공한다. - 두 번째 요청은 `409` 상태와 `이미 처리된 ... 신청입니다.` 메시지로 실패한다. - 목록을 새로고침하면 상태가 변경되어 있다. - 관련 `maestro_log`가 1회만 생성된다. 주의: - 이 검증은 DB 데이터를 실제로 변경한다. - 운영 DB에서는 read-only 리허설 또는 별도 테스트 데이터를 사용한 뒤 진행한다. ### 3-5. Docker 재시작 확인 NAS에서 실행한다. ```bash cd /volume1/docker/service/jinaju/stage-chocoadmin docker compose -f docker-compose.stage.yml restart docker compose -f docker-compose.stage.yml ps docker compose -f docker-compose.stage.yml logs --tail=100 ``` 기대 결과: - `stage-chocoadmin` 컨테이너가 `Up` 상태다. - 로그에 Next.js ready 메시지가 출력된다. - 브라우저에서 로그인과 주요 목록 화면이 정상 동작한다. ## 4. 안정화 메모 - 스테이지는 `proxy-network`를 통해 Nginx Proxy Manager와 연결한다. - 스테이지 컨테이너는 host port `3000`을 직접 bind하지 않고 container port `3000`만 노출한다. - `AUTH_URL`과 `NEXTAUTH_URL`은 실제 외부 접속 URL과 scheme까지 정확히 일치해야 한다. - HTTPS 배포 환경의 로그인 루프는 secure cookie 이름 불일치가 원인일 수 있다.