# API 호환성 및 논리적 오류 검증 보고서

> 작성일: 2025년 8월 26일
> 분석 범위: Frontend-Backend API 호환성 및 비즈니스 로직 검증

## 1. Critical 호환성 문제

### 🔴 1.1 Equipment 데이터 구조 불일치

#### 문제점
프론트엔드가 두 가지 상충되는 데이터 모델을 동시에 사용:
```dart
// equipment_in_form.dart
// 1. Legacy 카테고리 시스템
CategoryCascadeFormField(
  category1: _controller.category1,
  category2: _controller.category2,
  category3: _controller.category3,
)

// 2. 새로운 Vendor-Model 시스템 
EquipmentVendorModelSelector(
  initialVendorId: _controller.vendorId,
  initialModelId: _controller.modelsId,
)
```

#### 백엔드 기대값
```rust
// 백엔드는 models_id FK만 사용
pub struct Equipment {
    pub models_id: i32,  // Foreign Key to models table
    // category1, category2, category3 필드 없음
}
```

#### 영향도
- **데이터 무결성 파괴**: 같은 화면에서 두 가지 다른 분류 체계 사용
- **API 호출 실패 위험**: 백엔드가 기대하지 않는 필드 전송
- **사용자 혼란**: 어떤 입력이 실제로 저장되는지 불명확

### 🔴 1.2 API 경로 불일치

| 기능 | 프론트엔드 경로 | 백엔드 경로 | 상태 |
|-----|---------------|------------|------|
| 장비 | `/equipment` | `/equipments` | ❌ 불일치 |
| 창고 | `/warehouse-locations` | `/warehouses` | ❌ 불일치 |
| 라이선스 | `/licenses` | 존재하지 않음 | ❌ 404 에러 |
| 유지보수 | 구현 안됨 | `/maintenances` | ❌ 미사용 |

### 🔴 1.3 필드명 케이스 불일치

```dart
// 프론트엔드 (camelCase)
{
  "equipmentNumber": "EQ-001",
  "serialNumber": "SN12345",
  "purchaseDate": "2025-08-26"
}

// 백엔드 기대값 (snake_case)
{
  "equipment_number": "EQ-001",
  "serial_number": "SN12345",
  "purchase_date": "2025-08-26"
}
```

## 2. 논리적 오류 및 알고리즘 문제

### 🔴 2.1 재고 관리 논리 부재

#### 현재 상태
- Equipment History API 완전 미구현
- 입고/출고 추적 불가능
- 재고 수량 관리 로직 없음

#### 예상 문제
```dart
// equipment_remote_datasource.dart
Future<EquipmentIoResponse> equipmentOut(EquipmentOutRequest request) {
  // 재고 확인 로직 없음
  // 출고 가능 수량 검증 없음
  // 동시 출고 방지 로직 없음
  return _apiClient.post('/equipment/out', data: request);
}
```

### 🔴 2.2 중복 데이터 검증 미흡

#### 시리얼 번호 중복 검사
```dart
// 프론트엔드에만 존재, 백엔드 검증 없음
validator: (value) {
  if (value.trim().isEmpty) {
    return '장비 번호는 필수입니다';
  }
  // 중복 검사 로직 없음
  return null;
}
```

### 🔴 2.3 트랜잭션 처리 부재

#### 문제 시나리오
```dart
// 장비 생성 + 초기 재고 입고를 별도 API로 호출
await createEquipment(request);  // 성공
await createEquipmentHistory(historyRequest);  // 실패시?
// 롤백 로직 없음 → 데이터 불일치 발생
```

## 3. 페이지네이션 로직 불일치

### 프론트엔드 기대값
```dart
{
  'page': 1,
  'per_page': 20,
  'total': 100,
  'total_pages': 5
}
```

### 백엔드 실제 응답
```json
{
  "pagination": {
    "page": 1,
    "per_page": 20,
    "total": 100,
    "total_pages": 5
  }
}
```

### 변환 로직 오류
```dart
// equipment_remote_datasource.dart
final pagination = response.data['pagination'] ?? {};
final listData = {
  'items': dataList,
  'total': pagination['total'] ?? 0,
  'page': pagination['page'] ?? 1,  // 'current_page' 아님
  // 하지만 다른 곳에서는 'current_page' 사용
};
```

## 4. 한국어 검색 로직 문제

### 현재 구현
```dart
// 단순 문자열 포함 검색만 지원
if (search != null && search.isNotEmpty) 'search': search,
```

### 누락된 기능
- 초성 검색 지원 안됨 (ㅅㅁㅅ → 삼성)
- 공백 무시 검색 안됨 (삼 성 → 삼성)
- 영한 혼용 검색 안됨 (samsung 갤럭시)

## 5. 날짜/시간 처리 불일치

### 프론트엔드
```dart
DateTime.now().toIso8601String()  // "2025-08-26T15:30:45.123Z"
```

### 백엔드 기대값
```rust
// NaiveDate expects "2025-08-26"
// NaiveDateTime expects "2025-08-26 15:30:45"
```

## 6. 권한 체크 로직 누락

### 현재 상태
```dart
// 모든 API 호출시 권한 체크 없음
Future<void> deleteEquipment(int id) async {
  // 삭제 권한 확인 없이 직접 호출
  await _apiClient.delete('/equipment/$id');
}
```

### 필요한 구현
```dart
// 권한 체크 후 호출
if (currentUser.hasPermission('equipment.delete')) {
  await _apiClient.delete('/equipment/$id');
} else {
  throw UnauthorizedException();
}
```

## 7. 에러 처리 불일치

### 백엔드 에러 형식
```json
{
  "success": false,
  "message": "Equipment not found",
  "error_code": "EQUIPMENT_NOT_FOUND"
}
```

### 프론트엔드 에러 처리
```dart
// error_code 무시, message만 사용
throw ServerException(
  message: e.response?.data['message'] ?? 'Network error occurred',
  // error_code 처리 없음
);
```

## 8. 비즈니스 로직 검증 오류

### 8.1 회사 계층 구조
- 백엔드: parent_company_id 지원
- 프론트엔드: 플랫 구조만 지원

### 8.2 유지보수 vs 라이선스
- 백엔드: maintenances (equipment_history 기반)
- 프론트엔드: licenses (독립 엔티티)

### 8.3 장비 상태 관리
```dart
// 상태 전환 규칙 미구현
changeEquipmentStatus(id, 'DISPOSED', reason) {
  // ACTIVE → DISPOSED 직접 전환 허용
  // 중간 상태 검증 없음
}
```

## 9. 성능 문제

### 9.1 N+1 쿼리 문제
```dart
// 장비 목록 조회 후 각 장비마다 추가 API 호출
for (var equipment in equipments) {
  final vendor = await getVendor(equipment.vendorId);  // N번 호출
  final model = await getModel(equipment.modelId);     // N번 호출
}
```

### 9.2 캐싱 전략 부재
```dart
// 매번 새로운 API 호출
Future<List<LookupDto>> getLookups() async {
  // 캐시 체크 없음
  return await _apiClient.get('/lookups');
}
```

## 10. 권장 수정 사항

### Priority 1 (즉시)
1. API 경로 통일 (equipment → equipments)
2. 필드명 케이스 변환기 구현
3. Equipment category 시스템 제거, models_id만 사용

### Priority 2 (단기)
1. Equipment History API 구현
2. 트랜잭션 처리 로직 추가
3. 중복 검증 로직 구현

### Priority 3 (중기)
1. 한국어 검색 개선
2. 캐싱 전략 구현
3. 권한 체크 시스템 구현

## 결론

현재 프론트엔드와 백엔드 간의 API 호환성은 **심각한 수준**입니다. 특히 Equipment 관련 데이터 구조 불일치와 재고 관리 로직 부재는 비즈니스 운영에 직접적인 영향을 미칠 수 있습니다.

즉시 수정이 필요한 항목들을 우선적으로 처리하고, 체계적인 API 통합 테스트를 구축하는 것이 필요합니다.