# #4220 개발계 QA 결과

> 이 문서는 2026-10-12~13 당시 배포 버전의 실행 증거입니다. 이후 구현의 기대값은 [추가 체크리스트](additional-checklist.md), 2026-10-13 실행 판정은 [추가 실행 기록](additional-execution.md)을 따릅니다. 당시 화면에서 `대상 계약 필수`와 `원계약 대상 제외`가 통과했던 사실은 보존하지만 최신 기대값은 계약 미선택 시 유지·현재 계약도 대상 목록 포함입니다. 같은 PG에서 연동정보를 비워 두면 기존값을 유지하며, 입력값 삭제는 검증 범위가 아닙니다.

- 일시: 2026-10-12 (Asia/Seoul)
- 환경: `https://admin-dev.biscuitpay.com`, `https://api-dev.biscuitpay.com/api`
- 역할: ADMIN / 테넌트 `11f0-5c83-7e840e98-b583-000000000001`
- 방법: TypeScript + Playwright 헤드리스 브라우저 및 인증된 API 재조회
- 최초 판정(2026-10-12): 백엔드 현행 규칙 기준 실패 없음, 통과 10개 범주, QA 기대값 불일치 1건.
- 최종 판정(2026-10-13): **합의한 QA 범위에서 실패 없음**. 배포 후 변경 요약, 계약 수정 화면 안내·재조회, 단건 정상 이동을 추가 통과.

## QA 기대값 정정: 같은 PG의 다른 계약에 존재하는 수기 MID 중복

| 구분 | 내용 |
| --- | --- |
| 전제 | 법인 `박재민_법인`의 루시페이먼츠 계약 `박재민루시페이먼츠`에 MID 4건이 있음. 같은 법인의 웰컴페이먼츠 계약 `PG계약터짐테스트`로 일괄 이동. |
| 입력 | 첫 MID `100410059`의 변경값을 같은 웰컴페이먼츠의 **다른 법인/계약**에 이미 존재하는 `반길현수기mid`로 지정하고, 대상 PG 필수 `API KEY`/`IV`를 입력해 저장. |
| 기존 QA 기대 | “PG사 기준 MID 중복 검증”으로 해석해 거절을 예상했으나, 백엔드 현행 규칙은 수기 MID를 **계약 단위**로 검사함. |
| 실제 | `PATCH /api/v1/pgmids/contracts`가 HTTP 200으로 성공. 네 MID가 모두 대상 계약으로 이동했고 첫 MID 값이 `반길현수기mid`가 됨. 이후 QA 과정에서 첫 MID를 `100410059-test`로 재변경하여 중복 상태는 해소함. |
| 분류 | **QA 기대값 불일치**. 현행 백엔드 코드상 수기/ISP MID는 대상 계약 안의 중복만 차단한다. 변경 대상이 단말기 MID일 때는 테넌트 전체의 **다른 단말기 MID**와도 충돌을 검사한다. 수기와 다른 계약의 단말기가 같은 값을 쓰는 것은 허용된다. PG 전체 유일성이나 유형을 가로지르는 유일성이 새 요구사항이라면 정책 변경으로 다뤄야 한다. |
| 코드 근거 | `ChangePgMidContractsService.validateDuplicateMids`는 요청 내 중복 및 `targetContract.mids`를 비교하고, 단말기만 `findTerminalMidCollision`으로 테넌트 전체를 검색함. `AddPgMidUseCase`와 `UpdatePgMidUseCase`도 같은 구분을 사용함. |
| 재현 기록 | `scripts/issue-4220-execute.ts`의 PG 중복 구간. 이 스크립트는 당시 상태를 전제로 한 일회성 실행 기록이므로 그대로 재실행하지 말 것. |

**판단의 경계:** 대상 *계약* 안에 이미 있는 MID로 변경하는 요청은 HTTP 400 `변경하려는 계약에 동일한 MID가 존재합니다.`로 거절됐고, 선택한 네 건 모두 변경되지 않았다. 따라서 일괄 처리의 원자성 실패로 분류하지 않는다.

## 통과 항목

| 범주 | 검증 결과 |
| --- | --- |
| 배포 확인 | 개발계 프론트 자산에 `기존 MID 유지`, `새 MID로 변경` UI가 존재하고 실제 계약 변경 API가 동작함. |
| 기본 선택 | 계약 변경 창에서 MID별 기존 값 유지가 기본 선택임. |
| 필수 입력 | 대상 계약, 변경 사유, 변경 MID, 다른 PG의 필수 API KEY/IV 미입력 시 클라이언트가 차단하고 PATCH를 보내지 않음. |
| 변경 MID 입력 | 빈값, 공백 포함 값, 현재 MID와 동일한 값이 차단됨. |
| 다른 PG 이동 | 루시페이먼츠 → 웰컴페이먼츠 일괄 4건 이동 및 필수 KEY/IV 입력이 저장·재조회됨. 최초 다른 계약의 수기 MID 중복 사례는 위 QA 기대값 정정 항목 참조. |
| 같은 PG 이동 | 웰컴페이먼츠 계약 간 4건 이동에서 2건만 MID 변경, 2건 유지. KEY/IV와 메모·상태·설정 정보가 유지됨. 원래 대상 계약으로 재이동한 뒤 최신 목록을 확인함. |
| KEY/IV 개별 수정 | 같은 PG 이동에서 KEY만 수정하면 IV 유지, IV만 수정하면 KEY 유지, 둘 다 수정 가능. 대상 변경 및 KEY 수정 취소 시 기존 값 유지. 각 단계 API 재조회. |
| 대상 계약 중복·원자성 | 대상 계약의 기존 MID `100410063`과 충돌하는 일괄 4건 변경은 HTTP 400; 4건 모두 기존 MID·계약 유지. |
| 선택·초기화 | 다른 법인의 MID 혼합 선택 차단, 원계약 대상 옵션 제외, 창 닫기 후 다시 열면 대상·사유·MID·KEY 임시값 초기화. |
| 단건 수정 중복 | 단건 수정에서 같은 대상 계약의 기존 MID `100410060`으로 저장 시 `PATCH /api/v1/pgmids/{id}` HTTP 400; 원래 MID·계약 유지. |

## 2026-10-13 배포 후 재검증

| 항목 | 결과 |
| --- | --- |
| 변경 요약 UI | **통과.** 개발계 목록의 계약 변경 창에서 1건 이동의 MID/연동정보 변경 건수가 입력에 따라 각각 0→1로 갱신됨. `입력 초기화` 후 모두 0으로 복귀. 임시 입력은 저장하지 않음. |
| 계약 수정 화면의 미저장 입력 안내·초기화 | **통과.** `현재 저장하지 않은 수정 내용은 초기화됩니다.` 경고를 확인. 계약명 임시 수정 후 MID 1건을 같은 PG 계약으로 이동하자 계약명이 저장값으로 돌아오고 원계약 MID 목록에서 사라짐. 목적 계약 재조회 후 원계약으로 복귀. |
| 단건 수정 정상 계약 이동 | **통과.** `100410062`를 단건 수정 화면에서 `웰컴_일`로 이동하고 같은 화면으로 `PG계약터짐테스트`에 복귀. 두 PATCH 모두 HTTP 200, MID/계약은 API 재조회로 확인. 기존 단건 수정 로직이 계약 이동 시 연동 회원을 해제해, QA 후 원래 회원 1명을 다시 연결함. 최종 상태는 정상·회원 1명·KEY/IV QA 테스트값. |

**합의에 따라 제외:** 선택 입력 항목의 삭제 처리, 실제 결제/PG 승인 호출. 이 둘은 미검증 결함으로 집계하지 않는다.

## 최종 개발계 데이터 상태

QA 중 실제 데이터를 수정했다. 2026-10-13 최종 API 재조회에서 네 건 모두 웰컴페이먼츠 `PG계약터짐테스트` 계약이며 API KEY와 IV는 각각 QA 테스트값으로 설정되어 있었다.

| MID ID 끝자리 | 최종 MID |
| --- | --- |
| `...0001` (`3da89a04`) | `100410059-test` |
| `...0001` (`3db9d815`) | `100410060` |
| `...0001` (`3dc8a526`) | `100410061-test` |
| `...0001` (`3dd6d5f7`) | `100410062` |

단건 수정 QA 뒤 `100410062`의 원래 연동 회원 1명을 다시 연결했고 정상 상태를 확인했다. 원래 루시페이먼츠 계약의 KEY/IV 원문은 보존하지 않았으므로 자동 복원하지 않았다. QA 대상 데이터의 계약과 인증값을 원상복구해야 한다면 원래 값의 확인이 필요하다.

## 재현 및 검증 파일

- 사전 확인: `scripts/issue-4220-preflight.ts`
- 최초 UI 검증·중복 관찰: `scripts/issue-4220-execute.ts` (일회성 기록)
- 같은 PG 이동 및 최신 목록: `scripts/issue-4220-continue.ts` (일회성 기록)
- 일괄 원자성·KEY/IV: `scripts/issue-4220-key-cases.ts` (데이터 변경 포함)
- 선택·초기화: `scripts/issue-4220-ui-regression.ts`
- 단건 중복: `scripts/issue-4220-single-duplicate.ts`
- 배포 후 요약·계약 화면: `scripts/issue-4220-post-deploy-qa.ts`
- 단건 정상 이동 및 연동 회원 복원: `scripts/issue-4220-single-normal.ts`
- 단건 최종 확인: `scripts/issue-4220-single-final-check.ts`
- 최종 상태: `scripts/issue-4220-final-audit.ts`
- 정적 검증: `./node_modules/.bin/tsc --noEmit` 성공.

이 문서는 2026-10-12~13 실제 실행 당시의 상세 기록이며, 이후 게시 절차는 정식 보고서에서 확인한다.
