# P2P 잔여 처리 이력(remainder_resolution) + 종결 화면 표기 지침서

> 작성: 2026-07-18 · 배경: 관리자가 잔여를 취소하면 종결 화면이 "완료 · 29,520원 · 100% 진행바"로
> 보여 전액 수령처럼 오해됨(실제 받음 20,000원, 잔여 9,520원 취소). 종결 시 스냅샷·상태가 리셋되어
> UI가 표기할 이력 데이터도 없었음. 실사례: pwo_c67936dfe0f4 (id 37, CANCELLED 백필 완료).

## 0. DDL (운영 DB 적용 완료 — 2026-07-18 16:1x)

```sql
ALTER TABLE p2p_withdraw_orders
  ADD COLUMN remainder_resolution VARCHAR(20) NULL COMMENT '잔여 처리 방식: CONVERTED/CANCELLED/FORCE_SETTLED' AFTER usdt_convert_requested_usdt,
  ADD COLUMN remainder_krw BIGINT NULL COMMENT '종결 시 잔여 KRW 확정값' AFTER remainder_resolution,
  ADD COLUMN remainder_usdt DECIMAL(36,18) NULL COMMENT '종결 시 잔여 USDT 확정값' AFTER remainder_krw;
-- 백필: id 37 → CANCELLED / 9520 / 6.449864498644986449 (적용 완료)
```

`CRYPTOMENTS_V2_DDL.sql`의 p2p_withdraw_orders에 동일 컬럼 반영 + 이 파일 내용을
`v2-docs/migrations/P2P_REMAINDER_RESOLUTION_2026_07_18.sql`로 저장할 것.

## 1. 서버 변경 (backend repo)

### 1.1 common
- enum `P2pRemainderResolution` 신규: `CONVERTED, CANCELLED, FORCE_SETTLED` (JavaDoc 필수)
- `P2pWithdrawOrder` 엔티티에 3필드 추가 (`@XColumn`, remainder_resolution은 enum 타입)

### 1.2 core — `P2pWithdrawService` 종결 3경로에서 기록
잔여 Remainder(r) 계산 직후 공통 세팅:
- 강제 정산(forceSettle 상당, line ~268): `FORCE_SETTLED` + r.krw/r.usdt
- 잔여 취소(cancelRemainder 상당, line ~306): `CANCELLED` + r.krw/r.usdt
- 출금 전환(completeDirectWithdrawal, line ~389): `CONVERTED` + r.krw/r.usdt
- 기존 로직(스냅샷 리셋 포함) 변경 금지 — 필드 추가 세팅만. 잔여 0원 종결이어도 resolution은 기록(r=0).

### 1.3 open-api — 회원 페이지 노출
- `P2pPageOrderResponse`: `remainderResolution`(String), `remainderKrw`(Long), `remainderUsdt`(BigDecimal) 추가 (JavaDoc)
- `P2pWithdrawPageController` 상세 매핑에서 채움
- 대시보드 활성 주문엔 불필요(종결 건은 활성 목록에 없음) — 단, "끝난 거래" 목록 응답이 별도로 있으면 동일 3필드 추가

## 2. UI 변경 (cryptoments-admin repo, p2p-ui)

### 2.1 OrderDetailView — 종결(terminal) 분기 개편
- 헤드라인: **받음 금액** (`confirmed`), 라벨 "받은 금액"
- 서브라인: "총 판매 {krwAmount}원 · {usdtAmount} USDT"
- 잔여가 있고 resolution 존재 시:
  - 진행바: 받음(오렌지) + 잔여(회색 `#D8DCE4`) — **100% 오렌지 금지**
  - 뱃지: CANCELLED → "완료 · 잔여 취소" / CONVERTED → "완료 · USDT 전환" / FORCE_SETTLED → "완료 · 강제 정산"
  - **잔여 처리 카드** 추가 (전환 요청 카드 자리): CANCELLED → "잔여 {remainderKrw}원은 취소되어 사이트로 반환되었어요" / CONVERTED → "잔여 {remainderKrw}원이 {remainderUsdt(4자리)} USDT로 전환되었어요" / FORCE_SETTLED → "잔여 {remainderKrw}원이 정산 처리되었어요"
- 잔여 0원(전액 매칭 완료) 종결: 기존 표기 유지 (100% 오렌지 허용)
- 구데이터(resolution NULL, 잔여>0): 진행바·헤드라인은 동일 개편 적용, 카드 문구는 "잔여 {krw−confirmed}원은 미매칭 종결되었어요" (일반 문구)

### 2.2 OrdersView 끝난 거래 카드
- 종결 카드 서브텍스트: "받음 {confirmed} · 총 {krwAmount}" + resolution 있으면 "· 잔여 {remainderKrw}원 취소/전환/정산"

### 2.3 types.ts / fixtures.ts
- P2pOrder에 3필드 추가, fixtures에 종결-잔여취소 케이스 추가 (id37 시나리오: 총 29,520/받음 20,000/잔여 9,520 CANCELLED)

## 3. 표기 규칙
- USDT 4자리 절사 표기는 기존 usdt4 헬퍼 재사용 (중복 정의 금지 — 이번 기회에 `utils/format.ts`로 승격하여 3파일 중복 해소 권장)

## 4. 완료 기준
1. `:common:compileJava` `:core:compileJava` `:open-api:compileJava` 통과
2. p2p-ui `npm run build` 통과
3. 검증 사례 id 37: 헤드라인 "받음 20,000원", 뱃지 "완료 · 잔여 취소", 진행바 68% 오렌지+32% 회색, 잔여 카드 "9,520원 취소되어 사이트로 반환"
4. DDL↔엔티티 양방향 정합

## 5. 배포
open-api(spring:deploy-production ▶) + p2p-ui 배포 ▶. DDL은 이미 적용됨.
