# #4220 개발계 추가 QA 체크리스트

- 작성일: 2026-10-13 (Asia/Seoul)
- 상태: **2026-10-13 최종 판정 — PASS 11 / FAIL 0 / 개인확인 1** (ADD-10 사용자 변경 기준 적용)
- 범위: ADMIN, TID/MID 관리 및 PG 계약 관리의 `MID 변경` 화면
- 과거 증거: [기존 보고서](../../report.md)와 [2026-10-12~13 실행 기록](qa-execution-notes.md). 기존 `PASS`는 당시 배포 버전에 대한 결과이며 아래 항목의 통과 근거가 아니다.
- 제외: 선택 입력 항목 삭제, 실제 PG 결제·승인, 대량 테스트 데이터 신규 생성.

## 수행 전 확인 상태

| 구분 | 2026-10-13 읽기 전용 확인 | 추가 수행 전 조치 |
| --- | --- | --- |
| 코드 | 백엔드 `bc171247c9`, `4216611f7f`는 로컬 `fix/issue-4220` 및 `origin/develop-rc`에 포함. 프론트 `06ee8a66d`는 `develop-rc`에 포함되지만 현재 로컬 `main-rc`에는 미포함. | 코드 포함만으로 실제 저장 동작의 배포나 통과를 판단하지 않는다. |
| 개발계 프론트 | 배포 자산 `PgMidManageTable-BqlFX4uB.js`에 `MID 변경`, `기존 계약 유지`, 계약 미선택 안내가 존재. | 모달에서 실제 입력·저장은 아래 항목 수행 시 확인. |
| 개발계 백엔드 | `GET /api/v1/pgcontracts/{sourceContractId}/change-targets` HTTP 200, `PG계약터짐테스트` 자신을 포함한 대상 계약 11개 반환. | `PATCH` 저장, 원자성, 동시성, 성능 및 배포된 정확한 백엔드 커밋은 미확인. |
| 기존 4건 | `100410059-test`, `100410060`, `100410061-test`, `100410062` 모두 `박재민_법인`의 `PG계약터짐테스트` 계약. | 과거 요청의 `100410059`·`100410061` 원문과 위치를 전제로 테스트하지 않는다. |
| 다른 계약 수기 MID | `박재민루시페이먼츠`에 `100410063` 존재. | 변경 전 계약·연동정보와 정산 상태를 재조회. |
| 대량 기존 계약 | 같은 법인의 `웰컴_일` 계약에 MID 2,006건 존재. | 안전하게 변경·복원할 소수 MID를 선정하고 사전 상태를 기록. |
| 추가 데이터 | 다른 계약의 단말기 MID `lucy-dan`이 존재. `100410062`에는 연결 사용자 1명이 존재. 연결 가맹점과 정산 조건 결손 대상 계약의 조합은 확인하지 않음. | ADD-05의 단말기 소유·값 재확인과 ADD-09의 연결/정산 조건 데이터 확보가 필요. 데이터가 없으면 통과 처리하지 않는다. |

전달받은 로컬 단위 테스트 70건과 H2 MID 1,000건에서 충돌 조회 1회·엔티티/컬렉션 로딩 0건이라는 결과는 구현 검증 자료다. 이 문서에서 재실행하지 않았으며 개발계 저장·동시성·성능 결과로 대체하지 않는다.

## 공통 실행 및 복원 규칙

1. 각 MID의 ID, 값, 유형, 계약/PG, 상태, 동적 연동정보의 항목 ID·필수 여부·저장값, 연결 사용자·가맹점, 정산 설정을 실행 직전 재조회한다. 민감한 연동정보의 원문은 공개 보고서에 쓰지 않고 접근 제한된 복원 기록에만 둔다.
2. 제안한 `QA4220-*` 값은 먼저 같은 범위의 기존 값과 충돌하지 않는지 검색한다. 충돌하거나 항목 형식에 맞지 않으면 실행 시 유효한 고유값을 정하고 실제 입력값을 기록한다.
3. 저장 요청과 화면 안내, 응답 코드, 재조회 결과를 분리해 기록한다. 화면에서 차단된 요청을 서버가 거절한 것으로 기록하지 않는다.
4. 성공한 변경은 테스트 후 원래 계약·MID·연동정보·사용자/가맹점 연결·정산 설정으로 복원하고 양쪽 관리 화면에서 재조회한다. 원래 값이나 복원 방법을 확보하지 못하면 해당 변경을 실행하지 않는다.
5. 같은 테스트 데이터를 쓰는 시나리오는 순차 실행한다. ADD-10의 두 브라우저 요청만 동시에 저장한다.

## 추가 시나리오 — 실행 결과는 [증거 기록](additional-execution.md) 참조

### ADD-01 같은 계약의 수기 MID 값 교환 — `PASS`

- **화면:** TID/MID 관리 → `PG계약터짐테스트`의 두 MID 선택 → `MID 변경`.
- **수행 단계:** `100410059-test`와 `100410060`을 선택한다. 계약을 선택하지 않은 채 두 MID 변경값을 서로 바꿔 입력하고 저장한다. 목록을 새로고침하고 두 상세를 재조회한다.
- **입력값:** 첫 MID → `100410060`, 둘째 MID → `100410059-test`; 변경 사유 `#4220 ADD-01 값 교환`.
- **기대 결과:** 한 요청에서 두 값이 정확히 교환되고 두 건 모두 `PG계약터짐테스트` 계약 유지. 다른 MID와 연결·정산·연동정보는 그대로다.

### ADD-02 선택하지 않은 MID 값과의 중복 거절 — `PASS`

- **화면:** TID/MID 관리 → 같은 계약 MID 두 건 선택 → `MID 변경`.
- **수행 단계:** `100410059-test`, `100410060`만 선택하고 첫 MID 변경값을 선택하지 않은 `100410061-test`로 입력해 저장한다. 안내와 세 MID의 재조회 결과를 확인한다.
- **입력값:** 첫 MID → `100410061-test`; 둘째 MID 변경 없음; 변경 사유 `#4220 ADD-02 미선택 중복`.
- **기대 결과:** 중복 안내와 저장 거절. 선택한 두 건 모두 MID·계약·연동정보 변경 없음. 미선택 MID도 그대로다.

### ADD-03 선택한 여러 MID의 최종값 중복 거절 — `PASS`

- **화면:** TID/MID 관리 → `PG계약터짐테스트` MID 두 건 선택 → `MID 변경`.
- **수행 단계:** 두 변경 MID에 같은 값을 입력하고 저장한다. 화면 안내와 재조회로 일괄 취소를 확인한다.
- **입력값:** `100410059-test`, `100410060` 모두 → `QA4220-DUP-01`; 변경 사유 `#4220 ADD-03 요청 내부 중복`.
- **기대 결과:** 중복 안내, 두 건 모두 값·계약·연동정보 변경 없음. 값의 사전 중복 여부를 확인해 다른 충돌과 구분한다.

### ADD-04 다른 계약의 수기 MID 동일값 허용 — `PASS`

- **화면:** TID/MID 관리 → 각 계약의 수기 MID를 차례로 `MID 변경`.
- **수행 단계:** `PG계약터짐테스트`의 `100410059-test`와 `박재민루시페이먼츠`의 `100410063`을 각각 계약 미선택 상태에서 동일한 새 MID로 저장한다. 두 계약 화면에서 재조회한다.
- **입력값:** 두 MID 모두 → `QA4220-CROSS-01`; 각 변경 사유 `#4220 ADD-04 계약별 수기 중복`.
- **기대 결과:** 각각 자기 계약을 유지하며 정상 저장. 수기 MID의 중복 기준은 계약 단위다. 첫 저장 후 두 번째 요청까지 포함해 확인하고 원래 값으로 복원한다.

### ADD-05 수기 MID와 다른 계약 단말기 MID의 동일값 허용 — `PASS` (기대값 정정)

- **화면:** TID/MID 관리 → 수기 MID 선택 → `MID 변경`; 비교 대상 단말기 MID는 목록/상세에서 확인.
- **수행 단계:** 다른 계약에 있는 단말기 MID의 실제 값과 계약을 먼저 기록한다. 수기 `100410059-test`의 변경값으로 그 값을 입력해 저장한다.
- **입력값:** 변경 MID → 다른 계약 `루시_테스트`의 단말기 후보 `lucy-dan`(실행 직전 재조회); 변경 사유 `#4220 ADD-05 단말기 중복`.
- **기존 QA 기대:** 계약이 달라도 단말기 MID 값과의 중복을 거절할 것으로 예상했다.
- **정정한 기대 결과:** 변경 대상이 수기(KEYIN)이고 비교 대상이 다른 계약의 단말기(TERMINAL)이면 허용한다. 계약 내 중복은 유형과 관계없이 거절하며, 테넌트 전체 단말기 중복 검사는 변경 대상이 단말기일 때 단말기끼리 적용된다. 저장 후 두 MID의 유형·계약·값을 재조회하고 수기 MID는 원본값으로 복원한다.

### ADD-06 이동 건과 대상 계약 기존 건 혼합 선택 — `PASS`

- **화면:** TID/MID 관리 → `박재민루시페이먼츠`와 `PG계약터짐테스트` MID 혼합 선택 → `MID 변경`.
- **수행 단계:** 다른 계약의 `100410063`, 대상 계약 기존 `100410059-test`, 변경하지 않을 `100410060`을 함께 선택한다. 대상에 `PG계약터짐테스트`를 지정하고 첫 건은 이동, 둘째 건은 MID 또는 동적 연동정보 변경, 셋째 건은 입력하지 않은 채 저장·재조회한다.
- **입력값:** 대상 계약 `PG계약터짐테스트`; `100410063` 값 유지·대상 PG의 필수 연동정보는 형식에 맞는 QA 값 입력; `100410059-test` → `QA4220-MIX-01` 또는 형식에 맞는 연동정보 QA 값; `100410060` 변경 없음; 사유 `#4220 ADD-06 혼합 선택`.
- **기대 결과:** `100410063`만 계약·관련 연결/정산 이동 대상. 이미 대상 계약인 건은 계약을 유지하면서 입력한 MID·연동정보만 저장. 변경 없는 선택 건은 그대로다. 세 건 전체의 원자성과 복원 상태를 확인한다.

### ADD-07 여러 건 중 필수 연동정보 누락 — `PASS`

- **화면:** TID/MID 관리 → PG가 다른 계약으로 여러 수기 MID 이동 → `MID 변경`.
- **수행 단계:** 실제 대상 PG의 동적 필수 연동정보를 확인한다. 한 건은 유효한 값을 입력하고 다른 한 건은 필수 항목 하나를 비운 뒤 저장을 시도한다. 화면에서 막히면 별도 서버 요청 검증이 가능한지 판단하고, 각각의 결과를 구분해 기록한다.
- **입력값:** `박재민루시페이먼츠`의 `100410063`, `100410064`를 대상 `PG계약터짐테스트`로 선택; 한 건의 필수 항목 = 형식에 맞는 QA 값, 다른 건의 필수 항목 1개 = 빈 값; 사유 `#4220 ADD-07 필수값 누락`.
- **기대 결과:** 화면에서는 필수 입력 오류 안내. 서버에 요청이 도달한 경우 서버도 전체 요청을 거절해야 한다. 어느 경로든 정상 입력 건까지 포함해 계약·MID·연동정보 변경이 없어야 한다. 화면 차단만 확인했으면 서버 거절은 미검증으로 남긴다.

### ADD-08 계약 유지 상태의 연동정보 수정·재수정 — `PASS`

- **화면:** TID/MID 관리와 PG 계약 관리의 MID 상세/`MID 변경`.
- **수행 단계:** 계약을 선택하지 않고 `100410062`의 동적 연동정보 한 항목만 수정해 저장한다. 상세를 재열어 저장값을 확인한 뒤 같은 항목을 다시 수정한다. 다른 항목은 비워 두어 기존값 유지 여부를 확인한다.
- **입력값:** 선택한 항목 → 형식에 맞는 `QA4220-META-01`, 재수정 → `QA4220-META-02`에 해당하는 유효값; 다른 항목은 미입력; 사유 `#4220 ADD-08 연동정보만 수정`.
- **기대 결과:** 계약·MID·사용자/가맹점 연결·정산 정보 유지. 입력한 항목만 저장되고 미입력 항목은 기존값 유지. 재열기 후 추가 수정도 최신 저장값을 기준으로 동작. 항목은 PG 설정에서 읽으며 `KEY`/`IV`로 고정하지 않는다.

### ADD-09 연결된 MID 이동과 조건부 정산 검증 — `개인확인`

- **화면:** TID/MID 관리, PG 계약 관리의 MID 연결 및 계약 정산 설정.
- **수행 단계:** 연결 가맹점·사용자가 있는 수기 MID와 이동 대상 계약의 정산 조건을 먼저 확인한다. 정상 조건의 대상 계약으로 이동해 연결과 적용 정산 정보를 재조회한다. 계약의 펌뱅킹 정보가 필요한 정산 설정에서는 필수 가맹/영업 펌뱅킹 정보가 빠진 대상 계약으로 저장을 시도한다.
- **입력값:** 연결 사용자 1명이 확인된 `100410062`를 후보로 삼되 가맹점 연결과 정산 상태를 재확인; 사전 확정한 `<정상 대상 계약>`, `<필수 펌뱅킹 정보 누락 대상 계약>`; 사유 `#4220 ADD-09 연결·정산`.
- **기대 결과:** 정상 이동에서는 사용자·가맹점 연결 유지, 대상 계약 조건에 따른 정산 설정 확인. 필수 정보가 필요한 설정에서 정보가 빠졌다면 전체 변경 거절. 이미 이관된 정산 설정 등에는 같은 거절 기대값을 일괄 적용하지 않고 실제 적용 조건을 기록한다. 적합한 데이터 조합이 확인되지 않아 현재 수행 준비 미완료.

### ADD-10 두 브라우저 동시 동일 MID 저장 — `PASS` (변경 기준)

- **화면:** 독립된 두 Playwright 브라우저의 TID/MID 관리 → 각각 `MID 변경` 모달.
- **수행 단계:** 같은 계약의 서로 다른 MID를 각 브라우저에서 선택한다. 계약을 선택하지 않고 동일한 새 MID를 입력한 뒤 두 저장을 동시에 시작한다. 응답·안내와 양쪽 상세를 재조회한다. 두 요청 모두 이번 MID 변경 모달 경로로 통일한다.
- **입력값:** 브라우저 A `100410059-test` → `QA4220-RACE-01`, 브라우저 B `100410060` → `QA4220-RACE-01`; 각 사유 `#4220 ADD-10 동시 저장`.
- **사용자 변경 판정 기준:** 한 요청만 정상 저장되고 다른 요청은 오류로 실패 처리된다. 재조회에서 같은 계약의 동일 MID 값은 1건이며 실패 건의 원래 MID·계약·메타데이터·연결 상태가 유지된다. 성공한 한 건도 원래 값으로 복원한다. 500 일반 오류 문구 자체는 ADD-10 실패 조건에 넣지 않는다.
- **실행 판정:** 최초 개발계에서는 수기 MID 두 건이 200/200으로 저장되어 실제 중복이 발생했다. 수정 배포 후 재QA 6회는 모두 200/500, 최종 동일값 1건, 실패 건 원본 유지로 변경 기준을 만족해 **PASS**로 정정했다. 실패 요청을 저장 성공으로 기록하지 않는다. `Unknown internal server error` 문구 관측과 최초 실패 이력은 보존한다. 409 안내 응답의 후속 수정은 사용자 요청으로 undo되어 배포하지 않는다. [실행 증거](additional-execution.md#add-10-배포-후-재qa--변경-기준-적용-pass)를 참조한다.

### ADD-11 두 관리 화면 재조회 일치 — `PASS`

- **화면:** TID/MID 관리와 PG 계약 관리의 MID 목록·상세 및 `MID 변경`.
- **수행 단계:** ADD-06 또는 ADD-08의 성공 저장 직후 두 화면을 각각 새로고침한다. 계약 위치, MID, 동적 연동정보를 동일 MID ID 기준으로 비교한다. 변경 창의 대상 목록에서 기존 계약도 선택 가능한지 확인한다.
- **입력값:** 직전 성공 항목의 실제 입력값 및 MID ID; 대상 목록에서 기존 계약 `PG계약터짐테스트` 또는 해당 MID의 현재 계약.
- **기대 결과:** 두 화면의 계약 위치·MID·연동정보가 일치하고 재열기에도 최신값 표시. 기존 계약이 대상 목록에 포함된다. 실제 저장 없이 목록만 본 경우 전체 항목 통과로 기록하지 않는다.

### ADD-12 MID가 많은 기존 계약에서 소수 건 저장 — `PASS`

- **화면:** TID/MID 관리 → `웰컴_일` 계약(현재 MID 2,006건) → `MID 변경`.
- **수행 단계:** 기존 MID 중 안전하게 복원할 1~2건을 선정하고 사전값을 기록한다. 계약 유지 상태에서 소수 건을 수정해 저장한다. 클릭부터 응답까지, 재조회 완료까지의 시간을 각각 기록하고 시간 초과 여부를 확인한다.
- **입력값:** 후보 단말기 MID `TEST0000`, `TEST0001` 중 사전 연결·정산 상태를 확인한 건 → 충돌 없는 `QA4220-PERF-01`/`QA4220-PERF-02` 등 유효한 값; 사유 `#4220 ADD-12 다량 계약 소수 변경`.
- **기대 결과:** 선택한 소수 건만 정상 저장·재조회되고 지연·시간 초과가 없으며 나머지 기존 MID는 유지. 실제 소요시간을 남긴다. 화면 체감 속도만으로 DB 부하 개선을 판정하지 않는다. 신규 대량 데이터는 만들지 않는다.

## 실행 결론

- 2026-10-13 ADMIN 계정으로 TypeScript/Playwright 헤드리스 브라우저 및 인증된 API 요청을 실행했다. 상세 HTTP 응답, 화면 관찰, 사전·사후 재조회와 복원 결과는 [추가 실행 기록](additional-execution.md)에 있다.
- 추가 12건 최종 판정은 PASS 11, FAIL 0, 개인확인 1. ADD-05는 수기와 단말기 유형별 중복 규칙을 확인해 QA 기대값을 정정했다. ADD-10의 최초 200/200 중복 저장은 실제 실패였고, 수정 배포 후 6회 실측은 사용자 변경 기준에서 PASS다. 200/500 및 일반 오류 문구는 그대로 기록한다. ADD-09는 정상 연결 이동은 통과했으며, 정산 이관 비활성 부서의 펌뱅킹 누락 거절 조건을 담당자가 개인확인한다.
- 선택 입력 항목 삭제, 실제 결제·PG 승인은 합의에 따라 검증 범위에서 제외했다.
