Files
sam-docs/dev/dev_plans/react-api-integration-plan.md
권혁성 db63fcff85 refactor: [docs] 팀별 폴더 구조 재편 (공유/개발/프론트/기획)
- 개발팀 전용 폴더 dev/ 생성 (standards, guides, quickstart, changes, deploys, data, history, dev_plans 이동)
- 프론트엔드 전용 폴더 frontend/ 생성 (api/ → frontend/api-specs/)
- 기획팀 폴더 requests/ 생성
- plans/ → dev/dev_plans/ 이름 변경
- README.md 신규 (사람용 안내), INDEX.md 재작성 (Claude Code용)
- resources.md 신규 (노션 링크용, assets/brochure 이관 예정)
- CURRENT_WORKS.md 삭제, TODO.md → dev/ 이동
- 전체 참조 경로 업데이트

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 16:46:03 +09:00

813 lines
39 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# React-API 연동 테스트 계획
> **작성일**: 2025-12-22
> **목적**: React(dev.sam.kr) 프론트엔드와 API 연동 테스트 및 스펙 동기화
> **기준 문서**: `erp-api-development-plan-d1.0-changes.md`
> **상태**: 🔄 진행중
---
## 1. 개요
### 1.1 배경
- React와 API가 동일한 기획서(SAM_ERP_Storyboard_D1.0)로 각각 개발됨
- 기획서에 API 명세가 없어 React는 목업 데이터로, API는 자체 설계로 구현
- 두 시스템 간 request/response 스펙 동기화 필요
### 1.2 기준 원칙
```
┌─────────────────────────────────────────────────────────────────┐
│ 🎯 React를 기준으로 API를 맞춤 │
├─────────────────────────────────────────────────────────────────┤
│ - React에서 호출하는 API 경로/파라미터 분석 │
│ - API의 request/response를 React 요구사항에 맞게 수정 │
│ - API 내부 로직 변경이 필요한 경우 → 사용자 컨펌 필수 │
└─────────────────────────────────────────────────────────────────┘
```
### 1.3 변경 승인 정책
| 변경 유형 | 예시 | 승인 |
|----------|------|------|
| ✅ **즉시 가능** | Response 필드 추가, Query 파라미터 추가, 필드명 변경 | 불필요 |
| ⚠️ **컨펌 필요** | Service 로직 변경, DB 쿼리 변경, 새 엔드포인트 추가 | **필수** |
| 🔴 **금지** | 테이블 구조 변경, 기존 API 삭제 | 별도 협의 |
### 1.4 준수 규칙
- `docs/guides/PROJECT_DEVELOPMENT_POLICY.md` - 개발 공통 정책
- `docs/guides/common-workflow-framework.md` - 작업 프레임워크
### 1.5 Flow Test 병행
연동 테스트와 함께 **API Flow Test**를 병행합니다.
```
┌─────────────────────────────────────────────────────────────────┐
│ 🧪 Flow Tester 병행 테스트 │
├─────────────────────────────────────────────────────────────────┤
│ - 도구: https://mng.sam.kr/dev-tools/flow-tester │
│ - 목적: 각 기능의 모든 경우의 수(TC)를 자동화 테스트 │
│ - 저장: docs/dev_plans/flow-tests/{feature}-flow.json │
└─────────────────────────────────────────────────────────────────┘
```
**Flow Test JSON 형식:**
```json
{
"name": "플로우 이름 (50자 이내)",
"description": "플로우 상세 설명",
"version": "1.0",
"config": {
"baseUrl": "",
"timeout": 30000,
"stopOnFailure": true
},
"variables": {
"user_id": "{{$env.FLOW_TESTER_USER_ID}}",
"user_pwd": "{{$env.FLOW_TESTER_USER_PWD}}"
},
"steps": [
{
"id": "login",
"name": "로그인",
"method": "POST",
"endpoint": "/api/v1/login",
"body": {
"user_id": "{{user_id}}",
"user_pwd": "{{user_pwd}}"
},
"expect": {
"status": [200],
"jsonPath": { "$.access_token": "@isString" }
},
"extract": { "token": "$.access_token" }
},
{
"id": "step2",
"name": "다음 단계",
"method": "GET",
"endpoint": "/api/v1/path",
"headers": {
"Authorization": "Bearer {{login.token}}"
},
"expect": {
"status": [200],
"jsonPath": { "$.success": true }
}
}
]
}
```
#### 🔴 Flow Test JSON 작성 규칙 (필수 준수)
| # | 규칙 | 설명 |
|---|------|------|
| 1 | **config.baseUrl** | 빈 문자열 `""` 로 설정 (서버에서 .env 기본값 사용) |
| 2 | **config.apiKey** | ❌ JSON에 포함하지 않음 (서버에서 자동 주입) |
| 3 | **variables** | `{{$env.XXX}}` 형식으로 환경변수 참조 |
| 4 | **steps[].body** | `{{변수명}}` 형식으로 variables 값 참조 |
| 5 | **headers.Authorization** | `Bearer {{login.token}}` 형식으로 추출한 토큰 사용 |
| 6 | **extract** | 다음 스텝에서 `{{stepId.변수명}}`으로 참조됨 |
| 7 | **endpoint** | `/api/v1`을 포함한 전체 경로 필수 |
| 8 | **flows 배열** | ❌ 사용 금지 - 최상위에 바로 `steps` 배열 사용 |
| 9 | **dependsOn** | ❌ 사용 금지 - steps 순서대로 실행됨 |
#### 변수 참조 규칙
```
┌─────────────────────────────────────────────────────────────────────────┐
│ ✅ 올바른 참조 │
├─────────────────────────────────────────────────────────────────────────┤
│ variables 참조: "user_id": "{{user_id}}" │
│ 환경변수 참조: "user_id": "{{$env.FLOW_TESTER_USER_ID}}" │
│ 추출값 참조: "Authorization": "Bearer {{login.token}}" │
│ 동적 값: "email": "test_{{$timestamp}}@example.com" │
├─────────────────────────────────────────────────────────────────────────┤
│ ❌ 잘못된 참조 │
├─────────────────────────────────────────────────────────────────────────┤
│ ❌ "user_id": "{{variables.user_id}}" (variables. 접두사 사용 금지) │
│ ❌ "Authorization": "Bearer {{login.accessToken}}" (추출 키 불일치) │
└─────────────────────────────────────────────────────────────────────────┘
```
---
## 2. 대상 페이지 목록
### 2.1 Phase 5: 기본 확장
| # | React URL (예상) | 기능 | 관련 API | 연동 | Flow Test |
|---|-----------------|------|----------|:----:|:---------:|
| 5.1-1 | `/hr/employees/invite` | 사용자 초대 | `POST /v1/users/invite` | ✅ | ✅ |
| 5.1-2 | `/hr/employees/invitations` | 초대 목록 | `GET /v1/users/invitations` | ⏭️ | ⏭️ |
| 5.2-1 | `/settings/notifications` | 알림 설정 | `GET /v1/settings/notifications` | ✅ | ✅ |
| 5.2-2 | `/settings/notifications` | 알림 설정 수정 | `PUT /v1/settings/notifications` | ✅ | ✅ |
| 5.3-1 | `/account` | 회원 탈퇴 | `POST /v1/account/withdraw` | ✅ | ✅ |
| 5.3-2 | `/account` | 사용 중지 | `POST /v1/account/suspend` | ✅ | ✅ |
| 5.4-1 | `/accounting/sales/{id}` | 거래명세서 | `GET /v1/sales/{id}/statement` | ✅ | ✅ |
**Phase 5 Flow Test 파일:**
- `user-invitation-flow.json` - 사용자 초대 전체 플로우
- `notification-settings-flow.json` - 알림 설정 플로우
- `account-management-flow.json` - 계정관리 (탈퇴/중지) 플로우
- `sales-statement-flow.json` - 거래명세서 플로우
### 2.2 Phase 6: 핵심 신규 ✅
| # | React URL (예상) | 기능 | 관련 API | 연동 | Flow Test |
|---|-----------------|------|----------|:----:|:---------:|
| 6.1-1 | `/accounting/bad-debts` | 악성채권 목록 | `GET /v1/bad-debts` | ✅ | ✅ |
| 6.1-2 | `/accounting/bad-debts` | 악성채권 요약 | `GET /v1/bad-debts/summary` | ✅ | ✅ |
| 6.1-3 | `/accounting/bad-debts/{id}` | 악성채권 상세 | `GET /v1/bad-debts/{id}` | ✅ | ✅ |
| 6.1-4 | `/accounting/bad-debts/new` | 악성채권 등록 | `POST /v1/bad-debts` | ✅ | ✅ |
| 6.2-1 | `/settings/popups` | 팝업 목록 | `GET /v1/popups` | ✅ | ✅ |
| 6.2-2 | `/settings/popups` | 활성 팝업 | `GET /v1/popups/active` | ✅ | ✅ |
| 6.2-3 | `/settings/popups/{id}` | 팝업 상세 | `GET /v1/popups/{id}` | ✅ | ✅ |
**Phase 6 Flow Test 파일:**
- `bad-debt-flow.json` - 악성채권 추심관리 CRUD 플로우
- `popup-flow.json` - 팝업관리 CRUD 플로우
### 2.3 Phase 7: 게시판 연동 (⏭️ 후순위)
| # | React URL (예상) | 기능 | 관련 API | 연동 | Flow Test |
|---|-----------------|------|----------|:----:|:---------:|
| 7.1-1 | `/settings/boards` | 게시판 관리 목록 | `GET /v1/boards` | ⏭️ | ⏭️ |
| 7.1-2 | `/settings/boards/{id}` | 게시판 상세 | `GET /v1/boards/{id}` | ⏭️ | ⏭️ |
| 7.2-1 | `/boards` | 게시판 목록 (탭) | `GET /v1/boards` | ⏭️ | ⏭️ |
| 7.2-2 | `/boards/{code}` | 게시글 목록 | `GET /v1/boards/{code}/posts` | ⏭️ | ⏭️ |
| 7.2-3 | `/boards/{code}/{id}` | 게시글 상세 | `GET /v1/boards/{code}/posts/{id}` | ⏭️ | ⏭️ |
| 7.2-4 | `/boards/my` | 나의 게시글 | `GET /v1/posts/my` | ⏭️ | ⏭️ |
| 7.2-5 | `/boards/{code}/{id}` | 댓글 목록 | `GET /v1/boards/{code}/posts/{id}/comments` | ⏭️ | ⏭️ |
**Phase 7 Flow Test 파일:**
- `board-management-flow.json` - 게시판 관리 CRUD 플로우
- `post-crud-flow.json` - 게시글 CRUD + 댓글 플로우
### 2.4 Phase 8: SaaS 확장 ✅
| # | React URL (예상) | 기능 | 관련 API | 연동 | Flow Test |
|---|-----------------|------|----------|:----:|:---------:|
| 8.1-1 | `/subscription` | 현재 구독 정보 | `GET /v1/subscriptions/current` | ✅ | ✅ |
| 8.1-2 | `/subscription` | 사용량 조회 | `GET /v1/subscriptions/usage` | ✅ | ✅ |
| 8.1-3 | `/subscription/export` | 자료 내보내기 | `POST /v1/subscriptions/export` | ✅ | ✅ |
| 8.1-4 | `/subscription` | 서비스 해지 | `POST /v1/subscriptions/{id}/cancel` | ✅ | ✅ |
| 8.2-1 | `/payments` | 결제 내역 | `GET /v1/payments` | ✅ | ✅ |
| 8.2-2 | `/payments/{id}` | 결제 상세 | `GET /v1/payments/{id}` | ✅ | ✅ |
| 8.2-3 | `/payments/{id}/statement` | 거래명세서 | `GET /v1/payments/{id}/statement` | ✅ | ✅ |
| 8.3-1 | `/companies/add` | 회사 추가 | `POST /v1/companies/request` | ✅ | ✅ |
**Phase 8 Flow Test 파일:**
- `subscription-flow.json` - 구독관리 플로우
- `payment-flow.json` - 결제내역 플로우
- `company-request-flow.json` - 회사 추가 신청 플로우
---
## 3. 연동 테스트 절차
### 3.1 단일 페이지 테스트 절차
```
Step 1: React 페이지 분석
├── dev.sam.kr에서 해당 페이지 접속
├── 개발자 도구 > Network 탭 열기
├── 페이지 동작 수행 (조회, 등록, 수정 등)
└── API 호출 패턴 기록
├── URL 경로
├── HTTP Method
├── Request Headers
├── Request Body/Query
└── Expected Response
Step 2: API 현재 상태 확인
├── Swagger UI 접속 (sam.kr/api-docs)
├── 해당 엔드포인트 확인
└── 현재 request/response 스펙 확인
Step 3: 차이점 분석
├── URL 경로 차이
├── Request 파라미터 차이
├── Response 필드 차이
└── 인증 방식 차이
Step 4: 수정 사항 정리
├── ✅ 즉시 가능 → 바로 수정
└── ⚠️ 컨펌 필요 → 문서에 기록 후 승인 요청
Step 5: Flow Test 작성
├── 해당 기능의 모든 TC(Test Case) 도출
├── Flow Test JSON 작성
├── docs/dev_plans/flow-tests/{feature}-flow.json 저장
└── https://mng.sam.kr/dev-tools/flow-tester 에서 실행
```
### 3.2 Flow Test 작성 가이드
#### 🔴 핵심 원칙: 화면의 모든 분기 상황을 Flow로 작성
```
┌─────────────────────────────────────────────────────────────────────────┐
│ ❌ 간소화된 단일 플로우 금지 (대표 케이스 1개만 테스트하면 안됨) │
│ ✅ 화면에서 발생 가능한 모든 상황/분기를 개별 플로우로 작성 │
└─────────────────────────────────────────────────────────────────────────┘
```
#### Flow로 잡아야 하는 모든 분기 상황
| 분류 | 분기 유형 | 예시 |
|------|----------|------|
| **입력 분기** | Select Box | 카테고리, 상태, 유형 선택 |
| | Radio Button | 결제방식(카드/계좌/현금), 성별 |
| | Checkbox | 약관동의, 옵션 선택, 다중 선택 |
| | Toggle/Switch | 활성화/비활성화, 공개/비공개 |
| **조건부 UI** | 조건부 필드 표시 | 유형 A 선택 시 추가 필드 노출 |
| | 조건부 버튼 활성화 | 필수값 입력 시 버튼 활성화 |
| | 조건부 섹션 표시 | 특정 조건에서만 탭/섹션 노출 |
| **데이터 상태** | 데이터 유무 | 빈 목록 vs 데이터 있음 |
| | 데이터 상태값 | 대기/승인/반려/완료 각각 |
| | 페이징 상태 | 첫 페이지/중간/마지막 |
| **사용자 상태** | 권한별 | 관리자/일반사용자/게스트 |
| | 로그인 상태 | 로그인/비로그인 |
| | 역할별 | 작성자/승인자/조회자 |
| **액션 분기** | 버튼별 액션 | 저장/임시저장/취소/삭제 |
| | 모달/다이얼로그 | 확인/취소 선택 |
| | 네비게이션 | 이전/다음/목록으로 |
#### 조합 계산 공식
```
총 Flow 수 = (분기1 옵션수) × (분기2 옵션수) × ... × (분기N 옵션수)
```
**예시 - 등록 화면 분석:**
```
┌─────────────────────────────────────────────────────────────────────────┐
│ 화면: 악성채권 등록 │
├─────────────────────────────────────────────────────────────────────────┤
│ [입력 분기] │
│ - 채권유형 Select: 매출채권, 대여금, 선급금 → 3개 │
│ - 추심상태 Select: 추심중, 법적대응, 포기 → 3개 │
│ - 담당자지정 Radio: 자동배정, 직접지정 → 2개 │
│ - 알림설정 Checkbox: 이메일, SMS, 푸시 → 2³ = 8개 조합 │
│ │
│ [조건부 UI] │
│ - 담당자지정=직접지정 시: 담당자 Select 노출 (5명) → 5개 추가 │
│ │
│ [액션 분기] │
│ - 저장 버튼: 정상저장 │
│ - 임시저장 버튼: 임시저장 │
├─────────────────────────────────────────────────────────────────────────┤
│ 기본 Flow: 3 × 3 × 8 = 72개 │
│ 조건부 Flow: 직접지정 시 × 5 = 36개 추가 │
│ 액션별: × 2 (저장/임시저장) │
│ │
│ ⚠️ 전체 Flow 수 = (72 + 36) × 2 = 216개 │
└─────────────────────────────────────────────────────────────────────────┘
```
**예시 - 목록 화면 분석:**
```
┌─────────────────────────────────────────────────────────────────────────┐
│ 화면: 게시글 목록 │
├─────────────────────────────────────────────────────────────────────────┤
│ [필터 분기] │
│ - 게시판 탭: 공지, 자유, 질문 → 3개 │
│ - 정렬 Select: 최신순, 조회순, 댓글순 → 3개 │
│ - 기간 필터: 전체, 1주, 1개월, 3개월 → 4개 │
│ │
│ [데이터 상태] │
│ - 검색결과: 있음, 없음 → 2개 │
│ - 페이징: 첫페이지, 중간, 마지막 → 3개 │
│ │
│ [사용자 상태] │
│ - 권한: 관리자(수정/삭제 가능), 일반(조회만) → 2개 │
├─────────────────────────────────────────────────────────────────────────┤
│ 필터 조합: 3 × 3 × 4 = 36개 │
│ 데이터 상태: × 2 × 3 = × 6 │
│ 권한별: × 2 │
│ │
│ ⚠️ 전체 Flow 수 = 36 × 6 × 2 = 432개 │
│ (실제로는 의미있는 조합만 선별하여 테스트) │
└─────────────────────────────────────────────────────────────────────────┘
```
#### 실용적 접근: 분기 우선순위
모든 조합이 수백 개가 되면, 우선순위를 정해 단계적으로 테스트:
```
┌─────────────────────────────────────────────────────────────────────────┐
│ 🔴 P1 (필수): 비즈니스 핵심 분기 │
│ - 주요 유형/상태 조합 │
│ - 결제/금액 관련 분기 │
│ - 권한별 접근 차이 │
├─────────────────────────────────────────────────────────────────────────┤
│ 🟡 P2 (중요): UI 조건부 분기 │
│ - 조건부 필드 표시/숨김 │
│ - 버튼 활성화/비활성화 │
│ - 데이터 상태별 표시 │
├─────────────────────────────────────────────────────────────────────────┤
│ 🟢 P3 (권장): 부가 분기 │
│ - 정렬/필터 조합 │
│ - 페이징 상태 │
│ - 알림 설정 조합 │
└─────────────────────────────────────────────────────────────────────────┘
```
#### Flow 작성 체크리스트
화면 분석 시 반드시 확인:
```
□ 입력 분기: Select, Radio, Checkbox, Toggle 개수와 옵션
□ 조건부 UI: 특정 선택 시 나타나는/사라지는 필드
□ 데이터 상태: 빈 상태, 로딩, 에러, 정상 데이터
□ 사용자 상태: 권한별, 역할별 차이
□ 액션 분기: 각 버튼별 동작
□ 총 분기 조합 수 계산
□ 우선순위 분류 (P1/P2/P3)
□ P1 분기 전체 Flow 작성
```
**Flow Test 저장 위치:**
```
docs/dev_plans/flow-tests/
├── user-invitation-flow.json ✅ 완료 (6 steps)
├── notification-settings-flow.json ✅ 완료 (10 steps)
├── account-management-flow.json ✅ 완료 (6 steps)
├── sales-statement-flow.json ✅ 완료 (9 steps)
├── bad-debt-flow.json ✅ 완료 (11 steps)
├── popup-flow.json ✅ 완료 (9 steps)
├── subscription-flow.json ✅ 완료 (13 steps)
├── payment-flow.json ✅ 완료 (12 steps)
└── company-request-flow.json ✅ 완료 (9 steps)
```
### 3.3 분석 템플릿
```markdown
### [페이지 ID] 페이지명
**React 분석 결과:**
- URL: `GET /api/xxx`
- Request: `{ param1, param2 }`
- Response: `{ field1, field2 }`
**API 현재 상태:**
- URL: `GET /v1/xxx`
- Request: `{ paramA, paramB }`
- Response: `{ fieldA, fieldB }`
**차이점:**
| 항목 | React | API | 조치 |
|------|-------|-----|------|
| URL | /api/xxx | /v1/xxx | 수정 필요 |
| Response.field1 | 있음 | 없음 | 추가 필요 |
**수정 사항:**
- [ ] ✅ Response에 field1 추가
- [ ] ⚠️ Service 로직 변경 필요 (컨펌 요청)
```
---
## 4. 페이지별 연동 상세
> 각 페이지 테스트 후 이 섹션에 상세 내용 추가
### 4.1 Phase 5: 기본 확장
#### 5.1-1 사용자 초대
- **상태**: ✅ 완료
- **분석 결과**:
**React 분석 (UserInviteDialog.tsx):**
- Request: `{ email, role, message }` (role: 'admin' | 'manager' | 'user' 문자열)
**API 분석 (POST /v1/users/invite):**
- 기존: `{ email, role_id, message, expires_days }` (role_id: integer FK)
**차이점 및 조치:**
| 항목 | React | API | 조치 |
|------|-------|-----|------|
| role | `role` (문자열) | `role_id` (integer) | ✅ API에서 role 문자열도 지원하도록 수정 |
**수정된 파일:**
- `app/Http/Requests/UserInvitation/InviteUserRequest.php` - role 필드 추가
- `app/Services/UserInvitationService.php` - role → role_id 변환 로직 추가
- `app/Swagger/v1/UserInvitationApi.php` - Swagger 문서 업데이트
#### 5.1-2 초대 목록
- **상태**: ⏭️ 스킵
- **분석 결과**: React에 초대 목록 페이지 미구현 (API는 준비됨: `GET /v1/users/invitations`)
#### 5.2 알림 설정
- **상태**: ✅ 완료
- **분석 결과**:
**React 분석 (SettingsNotificationsPage.tsx):**
- 그룹 기반 계층 구조 사용
- Request/Response 구조:
```typescript
{
notice: { enabled: boolean, notice: { enabled, email }, event: { enabled, email } },
schedule: { enabled: boolean, vatReport: { enabled, email }, ... },
vendor: { enabled: boolean, newVendor: { enabled, email }, ... },
attendance: { enabled: boolean, annualLeave: { enabled, email }, ... },
order: { enabled: boolean, salesOrder: { enabled, email }, ... },
approval: { enabled: boolean, approvalRequest: { enabled, email }, ... },
production: { enabled: boolean, safetyStock: { enabled, email }, ... }
}
```
**API 분석 (기존):**
- 플랫 구조: 각 알림 타입별 개별 설정 (push_enabled, email_enabled, sms_enabled 등)
**차이점 및 조치:**
| 항목 | React | API | 조치 |
|------|-------|-----|------|
| 구조 | 그룹 기반 계층 | 플랫 | ✅ API에서 React 구조 직접 지원 |
| 엔드포인트 | `/settings/notifications` | `/users/me/notification-settings` | ✅ 새 엔드포인트 추가 |
**구현 방식:**
- API가 React 구조를 직접 반환 (변환 로직 불필요)
- 그룹 정의를 DB로 관리 (테넌트별 커스터마이징 가능)
**신규 생성 파일:**
- `database/migrations/2025_12_22_171959_create_notification_setting_groups_tables.php`
- `app/Models/NotificationSettingGroup.php`
- `app/Models/NotificationSettingGroupItem.php`
- `app/Models/NotificationSettingGroupState.php`
- `app/Http/Requests/NotificationSetting/UpdateGroupedSettingRequest.php`
**수정된 파일:**
- `app/Services/NotificationSettingService.php` - getGroupedSettings(), updateGroupedSettings() 추가
- `app/Http/Controllers/Api/V1/NotificationSettingController.php` - indexGrouped(), updateGrouped() 추가
- `routes/api.php` - 새 라우트 추가
- `app/Swagger/v1/NotificationSettingApi.php` - 스키마 및 엔드포인트 문서 추가
**새 API 엔드포인트:**
- `GET /api/v1/settings/notifications` - 그룹 기반 알림 설정 조회
- `PUT /api/v1/settings/notifications` - 그룹 기반 알림 설정 수정
#### 5.3-1 회원 탈퇴
- **상태**: ✅ 완료 (API 수정 불필요)
- **분석 결과**:
**React 분석 (AccountInfoManagement/index.tsx):**
- `handleConfirmWithdraw()`: 확인 다이얼로그 후 로그아웃 처리
- 조건: `canWithdraw = !accountInfo.isTenantMaster` (테넌트 마스터가 아닌 경우만)
- 현재 API 연동: `// TODO: 탈퇴 API 연동`
**API 분석 (POST /v1/account/withdraw):**
- Request: `{ password(필수), reason?, detail? }`
- Response: `{ withdrawn_at }`
- 로직: 비밀번호 확인 → 모든 테넌트 연결 해제 → 탈퇴 사유 저장 → 사용자 soft delete → 토큰 삭제
**차이점 및 조치:**
| 항목 | React | API | 조치 |
|------|-------|-----|------|
| 비밀번호 확인 | UI 없음 | `password` 필수 | ⚠️ React에서 비밀번호 입력 UI 추가 필요 |
| 탈퇴 사유 | UI 없음 | `reason`, `detail` 옵션 | React에서 선택적 추가 가능 |
**결정**: API 유지 (보안상 권장) - React 담당자에게 비밀번호 입력 UI 추가 요청
#### 5.3-2 사용 중지
- **상태**: ✅ 완료 (호환됨)
- **분석 결과**:
**React 분석:**
- `handleConfirmSuspend()`: 확인 다이얼로그 후 처리
- 조건: `canSuspend = accountInfo.isTenantMaster` (테넌트 마스터인 경우만)
- 현재 API 연동: `// TODO: 사용중지 API 연동`
**API 분석 (POST /v1/account/suspend):**
- Request: 없음 (현재 로그인된 사용자/테넌트 기준)
- Response: `{ suspended, new_default_tenant_id }`
- 로직: 현재 테넌트에서 비활성화 → 다른 활성 테넌트가 있으면 기본 테넌트 변경
**차이점 및 조치:** 없음 - API 호환됨 ✅
#### 5.4-1 거래명세서
- **상태**: ✅ 완료 (API 이미 구현됨)
- **분석 결과**:
**React 분석 (SalesManagement/SalesDetail.tsx):**
- `거래명세서 조회` 버튼: `// TODO: 거래명세서 조회 기능 연결` (line 527)
- `거래명세서 발행하기` 버튼: Mock 이메일 발송 (`handleSendTransactionStatement`)
**API 분석 (이미 완전히 구현됨):**
| 엔드포인트 | 설명 | Response |
|-----------|------|----------|
| `GET /v1/sales/{id}/statement` | 조회 | `{ statement_number, issued_at, sale, seller, buyer, items, summary }` |
| `POST /v1/sales/{id}/statement/issue` | 발행 | `{ statement_number, issued_at }` |
| `POST /v1/sales/{id}/statement/send` | 발송 | `{ sent_to, sent_at, statement_number }` |
**차이점 및 조치:** API 수정 불필요 - React에서 API 연동만 하면 됨 ✅
<!-- 이하 페이지별 상세 추가 -->
### 4.2 Phase 6: 핵심 신규
#### 6.1 악성채권 추심관리
- **상태**: ✅ 완료 (API 이미 완전 구현됨)
- **분석 결과**:
**React 분석 (BadDebtCollection/types.ts):**
```typescript
interface BadDebtRecord {
vendorId, vendorName, businessNumber, // 거래처 정보
debtAmount, status, overdueDays, // 악성채권 정보
files: AttachedFile[], // 첨부 파일
memos: BadDebtMemo[] // 메모
}
```
**API 분석 (완전 구현됨):**
| 엔드포인트 | 설명 | Response |
|-----------|------|----------|
| `GET /v1/bad-debts` | 목록 | 페이지네이션 + client 관계 |
| `GET /v1/bad-debts/summary` | 요약 | 상태별 금액 합계 |
| `GET /v1/bad-debts/{id}` | 상세 | client, documents, memos 관계 포함 |
| `POST /v1/bad-debts` | 등록 | `{ client_id, debt_amount, status, ... }` |
| `PUT /v1/bad-debts/{id}` | 수정 | 부분 업데이트 지원 |
| `DELETE /v1/bad-debts/{id}` | 삭제 | Soft Delete |
| `PATCH /v1/bad-debts/{id}/toggle` | 토글 | is_active 토글 |
| `POST /v1/bad-debts/{id}/documents` | 서류 첨부 | document_type, file_id |
| `POST /v1/bad-debts/{id}/memos` | 메모 추가 | content |
**차이점 및 조치:** API 수정 불필요 - React에서 연동만 필요 ✅
#### 6.2 팝업관리
- **상태**: ✅ 완료 (API 이미 완전 구현됨)
- **분석 결과**:
**React 분석 (PopupManagement/types.ts):**
```typescript
interface Popup {
target: 'all' | 'department',
targetName, title, content, status,
startDate, endDate, author
}
```
**API 분석 (완전 구현됨):**
| 엔드포인트 | 설명 | Response |
|-----------|------|----------|
| `GET /v1/popups` | 목록 (관리자용) | 페이지네이션 + creator, department 관계 |
| `GET /v1/popups/active` | 활성 팝업 (사용자용) | 현재 활성화된 팝업만 |
| `GET /v1/popups/{id}` | 상세 | creator, department 관계 포함 |
| `POST /v1/popups` | 등록 | `{ target_type, target_id, title, content, status, started_at, ended_at }` |
| `PUT /v1/popups/{id}` | 수정 | 부분 업데이트 지원 |
| `DELETE /v1/popups/{id}` | 삭제 | Soft Delete |
**필드 매핑:**
| React | API |
|-------|-----|
| `target` | `target_type` |
| `targetDepartmentId` | `target_id` |
| `startDate` | `started_at` |
| `endDate` | `ended_at` |
**차이점 및 조치:** API 수정 불필요 - React에서 필드명 매핑하여 연동 ✅
### 4.3 Phase 7: 게시판 연동
⏭️ **후순위로 연기** - 마지막에 진행 예정
### 4.4 Phase 8: SaaS 확장
#### 8.1 구독관리
- **상태**: ✅ 완료 (API 이미 완전 구현됨)
- **분석 결과**:
**React 분석 (SubscriptionManagement):**
```typescript
// types.ts
interface SubscriptionInfo {
lastPaymentDate: string;
nextPaymentDate: string;
subscriptionAmount: number;
plan: 'free' | 'basic' | 'premium' | 'enterprise';
userCount: number;
userLimit: number | null; // null = 무제한
storageUsed: number; // TB 단위
storageLimit: number;
apiCallsUsed: number;
apiCallsLimit: number;
}
```
- `handleExportData()`: 자료 내보내기 - TODO
- `handleCancelService()`: 서비스 해지 - TODO
**API 분석 (완전 구현됨):**
| 엔드포인트 | 설명 | 기능 |
|-----------|------|------|
| `GET /v1/subscriptions/current` | 현재 활성 구독 | 구독 정보 조회 |
| `GET /v1/subscriptions/usage` | 사용량 조회 | 사용자/저장공간/API 호출 통계 |
| `POST /v1/subscriptions/export` | 내보내기 요청 | 자료 내보내기 생성 |
| `GET /v1/subscriptions/export/{id}` | 내보내기 상태 | 진행 상태 확인 |
| `POST /v1/subscriptions/{id}/cancel` | 구독 취소 | 해지 처리 (reason 옵션) |
| `POST /v1/subscriptions/{id}/suspend` | 일시정지 | 구독 일시정지 |
| `POST /v1/subscriptions/{id}/resume` | 재개 | 구독 재개 |
**필드 매핑:**
| React | API |
|-------|-----|
| `lastPaymentDate` | `last_payment_at` |
| `nextPaymentDate` | `next_payment_at` |
| `subscriptionAmount` | `amount` |
| `userCount` | `user_count` |
| `userLimit` | `user_limit` |
| `storageUsed` | `storage_used` |
| `storageLimit` | `storage_limit` |
| `apiCallsUsed` | `api_calls_used` |
| `apiCallsLimit` | `api_calls_limit` |
**차이점 및 조치:** API 수정 불필요 - React에서 필드명 매핑하여 연동 ✅
#### 8.2 결제내역
- **상태**: ✅ 완료 (API 이미 완전 구현됨)
- **분석 결과**:
**React 분석 (PaymentHistoryManagement):**
```typescript
// types.ts
interface PaymentHistory {
id: string;
paymentDate: string;
subscriptionName: string;
paymentMethod: string;
subscriptionPeriod: { start: string; end: string; };
amount: number;
canViewInvoice: boolean;
createdAt: string;
updatedAt: string;
}
```
- Mock 데이터 사용 (`generateMockData()`)
- `handleViewInvoice()`: 거래명세서 조회 - MES 연동 예정
**API 분석 (완전 구현됨):**
| 엔드포인트 | 설명 | 기능 |
|-----------|------|------|
| `GET /v1/payments` | 결제 목록 | 페이지네이션 지원 |
| `GET /v1/payments/summary` | 요약 통계 | 결제 금액 합계 등 |
| `GET /v1/payments/{id}` | 결제 상세 | 상세 정보 조회 |
| `GET /v1/payments/{id}/statement` | 명세서 | 거래명세서 조회 |
| `POST /v1/payments/{id}/complete` | 완료 처리 | 결제 완료 처리 |
| `POST /v1/payments/{id}/cancel` | 취소 | 결제 취소 |
| `POST /v1/payments/{id}/refund` | 환불 | 환불 처리 |
**필드 매핑:**
| React | API |
|-------|-----|
| `id` | `id` |
| `paymentDate` | `paid_at` |
| `subscriptionName` | `subscription_name` |
| `paymentMethod` | `payment_method` |
| `subscriptionPeriod.start` | `period_start` |
| `subscriptionPeriod.end` | `period_end` |
| `canViewInvoice` | `can_view_statement` |
**차이점 및 조치:** API 수정 불필요 - React에서 필드명 매핑하여 연동 ✅
#### 8.3 회사 추가
- **상태**: ✅ 완료 (API 이미 완전 구현됨)
- **분석 결과**:
**React 분석 (CompanyInfoManagement/AddCompanyDialog.tsx):**
```typescript
// 입력: 사업자등록번호 10자리
// 처리 프로세스:
// 1. 사업자등록번호 조회 (바로빌 API 연동 TODO)
// 2. 휴폐업 상태 확인
// 3. 기존 등록 여부 확인
// 4. 신청 알림 발송
```
**API 분석 (완전 구현됨):**
| 엔드포인트 | 설명 | 기능 |
|-----------|------|------|
| `POST /v1/companies/check` | 사업자번호 검증 | 유효성/중복 검사 |
| `POST /v1/companies/request` | 회사 추가 신청 | 신청 등록 |
| `GET /v1/companies/my-requests` | 내 신청 목록 | 사용자 신청 이력 |
| `GET /v1/companies/requests` | 신청 목록 (관리자) | 관리자용 전체 목록 |
| `GET /v1/companies/requests/{id}` | 신청 상세 | 상세 정보 |
| `POST /v1/companies/requests/{id}/approve` | 승인 | 관리자 승인 |
| `POST /v1/companies/requests/{id}/reject` | 반려 | 관리자 반려 (reason 옵션) |
**React 연동 방식:**
```typescript
// 1단계: 사업자등록번호 검증
const checkResult = await api.post('/v1/companies/check', {
business_number: '1234567890'
});
// 2단계: 회사 추가 신청
if (checkResult.valid) {
await api.post('/v1/companies/request', {
business_number: '1234567890',
// 추가 정보...
});
}
```
**차이점 및 조치:** API 수정 불필요 - React에서 연동만 필요 ✅
---
## 5. 컨펌 대기 목록
> API 내부 로직 변경이 필요한 항목 (승인 필요)
| # | 페이지 | 변경 내용 | 영향 범위 | 상태 |
|---|--------|----------|----------|------|
| - | - | - | - | - |
---
## 6. 변경 이력
| 날짜 | 페이지 | 변경 내용 | 파일 | 승인 |
|------|--------|----------|------|------|
| 2025-12-22 | 8.3 | 회사 가입 신청 Flow Test 작성 (9 steps) | `company-request-flow.json` | ✅ |
| 2025-12-22 | 8.2 | 결제 관리 Flow Test 작성 (12 steps) | `payment-flow.json` | ✅ |
| 2025-12-22 | 8.1 | 구독 관리 Flow Test 작성 (13 steps) | `subscription-flow.json` | ✅ |
| 2025-12-22 | 6.2 | 팝업 관리 Flow Test 작성 (9 steps) | `popup-flow.json` | ✅ |
| 2025-12-22 | 6.1 | 부실채권 관리 Flow Test 작성 (11 steps) | `bad-debt-flow.json` | ✅ |
| 2025-12-22 | 5.4 | 매출 명세서 Flow Test 작성 (9 steps) | `sales-statement-flow.json` | ✅ |
| 2025-12-22 | 5.3 | 계정 관리 Flow Test 작성 (6 steps) | `account-management-flow.json` | ✅ |
| 2025-12-22 | 5.2 | 알림 설정 Flow Test 작성 (10 steps) | `notification-settings-flow.json` | ✅ |
| 2025-12-22 | - | Flow Test JSON 작성 규칙 정리 (9개 필수 규칙 + 변수 참조 규칙) | 문서 | ✅ |
| 2025-12-22 | - | endpoint 정책 추가 (/api/v1 전체 경로 필수) | 문서 + user-invitation-flow.json | ✅ |
| 2025-12-22 | - | Flow Test 파일 통합 (docs/dev_plans/flow-tests/로 이동) | 9개 파일 이동 | ✅ |
| 2025-12-22 | 5.1-1 | 사용자 초대 Flow Test 작성 (14 flows, P1~P3) | `user-invitation-flow.json` | ✅ |
| 2025-12-22 | 8.1 | 구독관리 API 분석 - 완전 구현됨, 필드명 매핑 필요 | - | ✅ |
| 2025-12-22 | 8.2 | 결제내역 API 분석 - 완전 구현됨, 필드명 매핑 필요 | - | ✅ |
| 2025-12-22 | 8.3 | 회사 추가 API 분석 - 완전 구현됨, React 연동만 필요 | - | ✅ |
| 2025-12-22 | 6.1 | 악성채권 API 분석 - 완전 구현됨, React 연동만 필요 | - | ✅ |
| 2025-12-22 | 6.2 | 팝업관리 API 분석 - 완전 구현됨, 필드명 매핑 필요 | - | ✅ |
| 2025-12-22 | 5.3-1 | 회원 탈퇴 API 분석 - API 유지, React에서 비밀번호 UI 추가 필요 | - | ✅ |
| 2025-12-22 | 5.3-2 | 사용 중지 API 분석 - 호환됨, 수정 불필요 | - | ✅ |
| 2025-12-22 | 5.4-1 | 거래명세서 API 분석 - 이미 완전 구현됨, React 연동만 필요 | - | ✅ |
| 2025-12-22 | 5.2 | 알림 설정 API - React 호환 그룹 구조 구현 | 마이그레이션, 모델, 서비스, 컨트롤러, Swagger | ✅ |
| 2025-12-22 | 5.1-1 | 사용자 초대 API - role 문자열 지원 추가 | Request, Service, Swagger | ✅ |
| 2025-12-22 | 3.2 | 화면 전체 분기 상황 Flow 작성 규칙으로 확장 | - | - |
| 2025-12-22 | - | Flow Test 병행 절차 추가 | - | - |
| 2025-12-22 | - | 문서 초안 작성 | - | - |
---
## 7. 참고 문서
- **기준 개발 계획**: [`erp-api-development-plan-d1.0-changes.md`](./erp-api-development-plan-d1.0-changes.md)
- **개발 공통 정책**: [`../guides/PROJECT_DEVELOPMENT_POLICY.md`](../guides/PROJECT_DEVELOPMENT_POLICY.md)
- **작업 프레임워크**: [`../guides/common-workflow-framework.md`](../guides/common-workflow-framework.md)
- **API Swagger UI**: http://sam.kr/api-docs/index.html
- **React 개발 서버**: http://dev.sam.kr
- **Flow Tester**: https://mng.sam.kr/dev-tools/flow-tester
- **Flow Test 파일**: `docs/dev_plans/flow-tests/*.json`