# Fetch Wrapper Migration Checklist

**생성일**: 2025-12-30
**목적**: 모든 Server Actions의 API 통신을 `serverFetch`로 중앙화

## 목적 및 배경

### 왜 fetch-wrapper를 도입했는가?

1. **중앙화된 인증 처리**
   - 401 에러(세션 만료) 발생 시 → 로그인 페이지 리다이렉트
   - 모든 API 호출에서 **일관된 인증 검증**

2. **개발 규칙 표준화**
   - 새 작업자도 `serverFetch` 사용하면 자동으로 인증 검증 적용
   - 개별 파일마다 인증 로직 구현 불필요

3. **유지보수성 향상**
   - 인증 로직 변경 시 **`fetch-wrapper.ts` 한 파일만** 수정
   - 403, 네트워크 에러 등 공통 에러 처리도 중앙화

---

## 마이그레이션 패턴

### Before (기존 패턴)
```typescript
import { cookies } from 'next/headers';

async function getApiHeaders(): Promise<HeadersInit> {
  const cookieStore = await cookies();
  const token = cookieStore.get('access_token')?.value;
  return {
    'Authorization': token ? `Bearer ${token}` : '',
    // ...
  };
}

export async function getSomething() {
  const headers = await getApiHeaders();
  const response = await fetch(url, { headers });
  // 401 처리 없음!
}
```

### After (새 패턴)
```typescript
import { serverFetch } from '@/lib/api/fetch-wrapper';

export async function getSomething() {
  const { response, error } = await serverFetch(url, { method: 'GET' });

  if (error) {
    // 401/403/네트워크 에러 자동 처리됨
    return { success: false, error: error.message };
  }

  const data = await response.json();
  // ...
}
```

---

## 마이그레이션 체크리스트

### Accounting 도메인 (12 files) ✅ 완료
- [x] `SalesManagement/actions.ts`
- [x] `VendorManagement/actions.ts`
- [x] `PurchaseManagement/actions.ts`
- [x] `DepositManagement/actions.ts`
- [x] `WithdrawalManagement/actions.ts`
- [x] `VendorLedger/actions.ts`
- [x] `ReceivablesStatus/actions.ts`
- [x] `ExpectedExpenseManagement/actions.ts`
- [x] `CardTransactionInquiry/actions.ts`
- [x] `DailyReport/actions.ts`
- [x] `BadDebtCollection/actions.ts`
- [x] `BankTransactionInquiry/actions.ts`

### HR 도메인 (6 files) ✅ 완료
- [x] `EmployeeManagement/actions.ts` ✅ (이미 마이그레이션됨)
- [x] `VacationManagement/actions.ts` ✅
- [x] `SalaryManagement/actions.ts` ✅
- [x] `CardManagement/actions.ts` ✅
- [x] `DepartmentManagement/actions.ts` ✅
- [x] `AttendanceManagement/actions.ts` ✅

### Approval 도메인 (4 files) ✅ 완료
- [x] `ApprovalBox/actions.ts`
- [x] `DraftBox/actions.ts`
- [x] `ReferenceBox/actions.ts`
- [x] `DocumentCreate/actions.ts` (파일 업로드는 직접 fetch 유지)

### Production 도메인 (4 files) ✅ 완료
- [x] `WorkerScreen/actions.ts`
- [x] `WorkOrders/actions.ts`
- [x] `WorkResults/actions.ts`
- [x] `ProductionDashboard/actions.ts`

### Settings 도메인 (10 files) ✅ 완료
- [x] `WorkScheduleManagement/actions.ts`
- [x] `SubscriptionManagement/actions.ts`
- [x] `PopupManagement/actions.ts`
- [x] `PaymentHistoryManagement/actions.ts`
- [x] `LeavePolicyManagement/actions.ts`
- [x] `NotificationSettings/actions.ts`
- [x] `AttendanceSettingsManagement/actions.ts`
- [x] `CompanyInfoManagement/actions.ts`
- [x] `AccountInfoManagement/actions.ts`
- [x] `AccountManagement/actions.ts`

### 기타 도메인 (12 files) ✅ 완료
- [x] `process-management/actions.ts`
- [x] `outbound/ShipmentManagement/actions.ts`
- [x] `material/StockStatus/actions.ts`
- [x] `material/ReceivingManagement/actions.ts`
- [x] `customer-center/shared/actions.ts`
- [x] `board/actions.ts`
- [x] `reports/actions.ts`
- [x] `quotes/actions.ts`
- [x] `board/BoardManagement/actions.ts`
- [x] `attendance/actions.ts`
- [x] `pricing/actions.ts`
- [x] `quality/InspectionManagement/actions.ts`

---

## 진행 상황

| 도메인 | 파일 수 | 완료 | 상태 |
|--------|---------|------|------|
| Accounting | 12 | 12 | ✅ 완료 |
| HR | 6 | 6 | ✅ 완료 |
| Approval | 4 | 4 | ✅ 완료 |
| Production | 4 | 4 | ✅ 완료 |
| Settings | 10 | 10 | ✅ 완료 |
| 기타 | 12 | 12 | ✅ 완료 |
| **총계** | **48** | **48** | **100%** ✅ |

### 완료된 파일 (완전 마이그레이션)

**Accounting 도메인 (12/12)**
- [x] `SalesManagement/actions.ts`
- [x] `VendorManagement/actions.ts`
- [x] `PurchaseManagement/actions.ts`
- [x] `DepositManagement/actions.ts`
- [x] `WithdrawalManagement/actions.ts`
- [x] `VendorLedger/actions.ts`
- [x] `ReceivablesStatus/actions.ts`
- [x] `ExpectedExpenseManagement/actions.ts`
- [x] `CardTransactionInquiry/actions.ts`
- [x] `DailyReport/actions.ts`
- [x] `BadDebtCollection/actions.ts`
- [x] `BankTransactionInquiry/actions.ts`

**HR 도메인 (6/6)**
- [x] `EmployeeManagement/actions.ts` (이미 마이그레이션됨)
- [x] `VacationManagement/actions.ts`
- [x] `SalaryManagement/actions.ts`
- [x] `CardManagement/actions.ts`
- [x] `DepartmentManagement/actions.ts`
- [x] `AttendanceManagement/actions.ts`

**Approval 도메인 (4/4)**
- [x] `ApprovalBox/actions.ts`
- [x] `DraftBox/actions.ts`
- [x] `ReferenceBox/actions.ts`
- [x] `DocumentCreate/actions.ts` (파일 업로드는 직접 fetch 유지)

**Production 도메인 (4/4)**
- [x] `WorkerScreen/actions.ts`
- [x] `WorkOrders/actions.ts`
- [x] `WorkResults/actions.ts`
- [x] `ProductionDashboard/actions.ts`

**Settings 도메인 (10/10)**
- [x] `WorkScheduleManagement/actions.ts`
- [x] `SubscriptionManagement/actions.ts`
- [x] `PopupManagement/actions.ts`
- [x] `PaymentHistoryManagement/actions.ts`
- [x] `LeavePolicyManagement/actions.ts`
- [x] `NotificationSettings/actions.ts`
- [x] `AttendanceSettingsManagement/actions.ts`
- [x] `CompanyInfoManagement/actions.ts`
- [x] `AccountInfoManagement/actions.ts`
- [x] `AccountManagement/actions.ts`

**기타 도메인 (12/12)** ✅ 완료
- [x] `process-management/actions.ts`
- [x] `outbound/ShipmentManagement/actions.ts`
- [x] `material/StockStatus/actions.ts`
- [x] `material/ReceivingManagement/actions.ts`
- [x] `customer-center/shared/actions.ts`
- [x] `board/actions.ts`
- [x] `reports/actions.ts`
- [x] `quotes/actions.ts`
- [x] `board/BoardManagement/actions.ts`
- [x] `attendance/actions.ts`
- [x] `pricing/actions.ts`
- [x] `quality/InspectionManagement/actions.ts`

---

## 참조 파일

- **fetch-wrapper**: `src/lib/api/fetch-wrapper.ts`
- **errors**: `src/lib/api/errors.ts`
- **완료된 예시**: `src/components/accounting/BillManagement/actions.ts` (참고용)

---

## 주의사항

1. **기존 `getApiHeaders()` 함수 제거** - `serverFetch`가 헤더 자동 생성
2. **`import { cookies } from 'next/headers'` 제거** - wrapper에서 처리
3. **에러 응답 구조 맞추기** - `{ success: false, error: string }` 형태 유지
4. **빌드 테스트 필수** - 마이그레이션 후 `npm run build` 확인

---

## 🔜 추가 작업 (마이그레이션 완료 후)

### Phase 2: 리프레시 토큰 자동 갱신 적용

**현재 문제:**
- access_token 만료 시 (약 2시간) 바로 로그인 리다이렉트됨
- refresh_token (7일)을 사용한 자동 갱신 로직이 호출되지 않음
- 결과: 40분~2시간 후 세션 만료 → 재로그인 필요

**목표:**
- 401 발생 시 → 리프레시 토큰으로 갱신 시도 → 성공 시 재시도
- 7일간 세션 유지 (refresh_token 만료 시에만 재로그인)

**적용 범위:**

| 영역 | 적용 위치 | 작업 |
|------|----------|------|
| Server Actions | `fetch-wrapper.ts` | 401 시 리프레시 후 재시도 로직 추가 |
| 품목관리 | `ItemListClient.tsx` 등 | 클라이언트 fetch에 리프레시 로직 추가 |
| 품목기준관리 | 관련 컴포넌트들 | 클라이언트 fetch에 리프레시 로직 추가 |

**관련 파일:**
- `src/lib/auth/token-refresh.ts` - 리프레시 함수 (이미 존재)
- `src/app/api/auth/refresh/route.ts` - 리프레시 API (이미 존재)

**예상 구현:**
```typescript
// fetch-wrapper.ts 401 처리 부분
if (response.status === 401 && !options?.skipAuthCheck) {
  // 1. 리프레시 토큰으로 갱신 시도
  const refreshResult = await refreshTokenServer(refreshToken);

  if (refreshResult.success) {
    // 2. 새 토큰으로 원래 요청 재시도
    return serverFetch(url, { ...options, skipAuthCheck: true });
  }

  // 3. 리프레시도 실패하면 로그인 리다이렉트
  redirect('/login');
}
```
