# DDL 정리 v1.6 지침서

**대상**: DDL + Spring Boot (common Entity) + Node.js (types, repos)
**날짜**: 2026-03-19

---

## 변경 요약

| # | 대상 | 변경 | 이유 |
|---|------|------|------|
| 1 | `blockchain_networks` | 가스 관련 4개 컬럼 제거 | 미사용, 런타임 계산으로 대체 |
| 2 | `relayer_wallets` | **테이블 제거** | 복잡도 감소, wallet_addresses로 흡수 |
| 3 | `wallet_addresses` | wallet_type `SYSTEM` → `RELAYER` | 명확한 명칭 |
| 4 | `nonce_tracker` | COMMENT 수정 | SYSTEM → RELAYER 반영 |
| 5 | `collection_queue` | `relayer_wallet_id` → `relayer_address_id` | relayer_wallets 제거에 따른 FK 참조 변경 |
| 6 | `withdrawals` | `relayer_wallet_id` → `relayer_address_id` | relayer_wallets 제거에 따른 FK 참조 변경 |

---

## 1. `blockchain_networks` — 가스 관련 4개 컬럼 제거

### DDL 변경

제거 대상:

```sql
-- 제거할 컬럼
avg_gas_price_gwei DECIMAL(20,4)
last_gas_updated_at DATETIME(6)
gas_min_balance DECIMAL(36,18)
approve_gas_amount DECIMAL(36,18)
```

**이유**: 어디서도 사용하지 않음. 가스비는 런타임 동적 계산:
- BSC/Polygon: `currentGasPrice × gasLimit(~80,000)`
- TRON: TronZap API (0.1 TRX + 에너지 100,000 렌탈)

### ALTER SQL

```sql
ALTER TABLE blockchain_networks
  DROP COLUMN avg_gas_price_gwei,
  DROP COLUMN last_gas_updated_at,
  DROP COLUMN gas_min_balance,
  DROP COLUMN approve_gas_amount;
```

### Spring Boot Entity

**파일**: `common/src/main/java/com/cryptoments/common/entity/BlockchainNetwork.java`

제거:
```java
// 삭제
private BigDecimal avgGasPriceGwei;
private LocalDateTime lastGasUpdatedAt;
private BigDecimal gasMinBalance;
private BigDecimal approveGasAmount;
```

---

## 2. `relayer_wallets` — 테이블 제거

### DDL 변경

```sql
DROP TABLE IF EXISTS relayer_wallets;
```

DDL 파일에서 `CREATE TABLE relayer_wallets` 블록 전체 삭제.

### 기존 필드 처리

| 기존 필드 | 처리 |
|----------|------|
| `relayer_role` | 제거 — 통합 Relayer, 역할 구분 없음 |
| `priority` | 제거 — 라운드로빈 |
| `contract_address` | 제거 — `relayer_contracts` 테이블에서 조회 |
| `registration_tx_hash` | audit_log에 기록 |
| `registration_status` | 제거 — addRelayer 성공 시 ACTIVE, 실패 시 삭제 |
| `status` | `wallet_addresses.status` 사용 |
| `current_pending_tx_count` | `nonce_tracker.status` (AVAILABLE/LOCKED)로 관리 |
| `max_pending_tx_count` | 제거 — 시스템 설정 또는 config |

### Relayer 선택 로직 (변경 후)

```
1. wallet_addresses WHERE wallet_type='RELAYER' AND network_id=? AND status='ACTIVE' 조회
2. 각 RELAYER의 nonce_tracker.status 확인
3. status='AVAILABLE' (사용 중이지 않은) Relayer 선택
4. 없으면 대기 후 재시도
5. 네트워크당 최소 5개 Relayer, 성능에 따라 증설
```

### Spring Boot 변경

**삭제 대상**:
- `common/.../entity/RelayerWallet.java` — Entity 삭제
- `common/.../repository/RelayerWalletRepository.java` — Repository 삭제
- `common/.../enums/RelayerRole.java` — Enum 삭제 (있다면)
- `common/.../enums/RegistrationStatus.java` — Enum 삭제 (있다면)

**수정 대상**:
- `admin-api/.../service/RelayerManagementService.java` — `relayerWalletRepository` 참조 제거, 간소화
- `admin-api/.../controller/RelayerManagementController.java` — 엔드포인트 간소화
- `admin-api/.../mapper/RelayerSearchMapper.java` — relayer_wallets JOIN 제거
- `admin-api/.../dto/response/RelayerDetailResponse.java` — relayer_wallets 필드 제거
- `admin-api/.../dto/request/RelayerCreateRequest.java` — `relayerRole` 필드 제거

**RelayerCreateRequest 변경 후**:
```java
public class RelayerCreateRequest {
    @NotNull
    private Long networkId;
    @NotNull
    private Long hdWalletId;
    // relayerRole 제거
}
```

### Node.js 변경

**삭제 대상**:
- `common/src/db/repositories/RelayerWalletRepo.ts` — 전체 삭제
- `common/src/types/wallet.ts` — `RelayerWallet`, `RelayerRole`, `RegistrationStatus` 타입 삭제

**수정 대상**:
- `common/src/index.ts` — `relayerWalletRepo` export 제거
- `relayer-api/src/routes/relayer.ts` — `relayerWalletRepo` 사용 제거, Relayer 등록 로직 간소화
- `blockchain-api/src/services/ContractManagementService.ts` — `relayerWalletRepo` 참조 제거

**relayer.ts register 핸들러 간소화**:

```typescript
// 변경 후: relayer_wallets INSERT 제거, wallet_addresses(RELAYER)만 생성
router.post('/register', async (req, res) => {
  const { networkId, hdWalletId } = req.body;
  // relayerRole 파라미터 제거

  // 1. 컨트랙트 확인
  // 2. HD 파생 → wallet_addresses(RELAYER) INSERT + wallet_keys INSERT
  // 3. 온체인 addRelayer() TX
  // 4. 실패 시 wallet_addresses 삭제 (또는 INACTIVE)
  // ※ relayer_wallets INSERT 단계 완전 제거
});
```

---

## 3. `wallet_addresses` — wallet_type SYSTEM → RELAYER

### DDL 변경

COMMENT만 수정:
```sql
wallet_type VARCHAR(20) NOT NULL
    COMMENT 'HOT — 사용자 입금 지갑
             MASTER — 파트너 마스터 (출금 원천)
             GAS — 가스비 관리 지갑 (Admin 생성)
             ADMIN — 컨트랙트 Owner 지갑 (네트워크당 1개)
             SETTLEMENT — 정산 수익 보관
             POOL — 소수점 매칭 풀 주소
             RELAYER — Relayer EOA (집금/출금 TX 실행)',
```

### Spring Boot Enum 변경

**파일**: `common/.../enums/WalletType.java`

```java
// 변경 전
SYSTEM

// 변경 후
RELAYER
```

### Node.js 타입 변경

**파일**: `common/src/types/wallet.ts`

```typescript
// 변경 전
export type WalletType = 'HOT' | 'POOL' | 'MASTER' | 'GAS' | 'ADMIN' | 'SETTLEMENT' | 'SYSTEM';

// 변경 후 (SYSTEM 제거, RELAYER 추가)
export type WalletType = 'HOT' | 'POOL' | 'MASTER' | 'GAS' | 'ADMIN' | 'SETTLEMENT' | 'RELAYER';
```

### 코드 전체 검색 후 치환

```bash
# Spring Boot
grep -rn "SYSTEM" --include="*.java" common/ admin-api/ open-api/ partner-api/ core/
# → WalletType.SYSTEM → WalletType.RELAYER

# Node.js
grep -rn "'SYSTEM'" --include="*.ts" node-service/packages/
# → 'SYSTEM' → 'RELAYER'
```

---

## 4. `nonce_tracker` — COMMENT만 수정

```sql
-- 변경 전
) COMMENT '논스 관리 (MASTER/SYSTEM/Relayer 지갑)';

-- 변경 후
) COMMENT '논스 관리 (RELAYER 지갑)';
```

---

## 5. `collection_queue` / `withdrawals` — relayer_wallet_id → relayer_address_id

relayer_wallets 테이블 제거에 따라, 기존 `relayer_wallet_id` (relayer_wallets.id 참조)를
`relayer_address_id` (wallet_addresses.id 참조)로 변경.

### ALTER SQL

```sql
-- collection_queue
ALTER TABLE collection_queue CHANGE COLUMN relayer_wallet_id relayer_address_id BIGINT COMMENT 'wallet_addresses.id — 집금 실행 Relayer';

-- withdrawals
ALTER TABLE withdrawals CHANGE COLUMN relayer_wallet_id relayer_address_id BIGINT COMMENT 'wallet_addresses.id — 출금 실행 Relayer';
```

### Spring Boot Entity 변경

**CollectionQueue.java**: `relayerWalletId` → `relayerAddressId`
**Withdrawal.java**: `relayerWalletId` → `relayerAddressId`

### Node.js 타입 변경

해당 타입에서 `relayer_wallet_id` → `relayer_address_id`

---

## DDL 적용 SQL (실행 순서)

```sql
-- 1. blockchain_networks 가스 컬럼 제거
ALTER TABLE blockchain_networks
  DROP COLUMN avg_gas_price_gwei,
  DROP COLUMN last_gas_updated_at,
  DROP COLUMN gas_min_balance,
  DROP COLUMN approve_gas_amount;

-- 2. 기존 SYSTEM 타입을 RELAYER로 변경 (데이터 마이그레이션)
UPDATE wallet_addresses SET wallet_type = 'RELAYER' WHERE wallet_type = 'SYSTEM';

-- 3. relayer_wallets 테이블 제거
DROP TABLE IF EXISTS relayer_wallets;

-- 4. collection_queue / withdrawals 컬럼명 변경
ALTER TABLE collection_queue CHANGE COLUMN relayer_wallet_id relayer_address_id BIGINT COMMENT 'wallet_addresses.id — 집금 실행 Relayer';
ALTER TABLE withdrawals CHANGE COLUMN relayer_wallet_id relayer_address_id BIGINT COMMENT 'wallet_addresses.id — 출금 실행 Relayer';

-- 5. 확인
SELECT wallet_type, COUNT(*) FROM wallet_addresses GROUP BY wallet_type;
DESCRIBE blockchain_networks;
DESCRIBE collection_queue;
DESCRIBE withdrawals;
SHOW TABLES LIKE 'relayer%';
```

---

## 전체 리셋 후 재시작 순서

DDL 구조 변경이므로 Phase 0 데이터를 리셋하고 다시 시작:

```bash
# 1. DDL 적용 (위 SQL 실행)
# 2. Spring Boot Entity/Enum/Service 수정 → 빌드
# 3. Node.js 타입/Repo/Route 수정 → pnpm build
# 4. 트랜잭션 데이터 리셋 (hd_wallets 이하)
# 5. seed-hd-wallet.ts 실행
# 6. ADMIN 지갑 생성 (3 networks)
# 7. 컨트랙트 등록 (3 networks)
# 8. GAS 지갑 생성 (3 networks)
# 9. Relayer 생성 (네트워크당 5개, 3 networks = 15개)
# 10. GAS/Relayer native coin 충전 (수동)
```
