fix: CRUD 작업 후 화면 갱신 문제 해결 및 장비 출고 기능 구현
주요 변경사항: - 장비 출고 API 연동 구현 (equipment_out_form_controller.dart) - 모든 리스트 화면에서 CRUD 후 자동 갱신 확인 - CLAUDE.md 프로젝트 문서 실제 정보로 업데이트 - 실제 테스트 계정 정보 반영 (admin@superport.kr) - API 소스코드 경로 추가 (/Users/maximilian.j.sul/Documents/flutter/superport_api) - 테스트 도구 추가 - test_api_integration.sh: API 통합 테스트 스크립트 - test_crud_operations.md: CRUD 테스트 체크리스트 기술적 개선: - Mock 서비스 의존도 제거 - Real API 전용 모드로 전환 - GetIt을 통한 서비스 주입 활용
This commit is contained in:
510
CLAUDE.md
510
CLAUDE.md
@@ -1,376 +1,198 @@
|
||||
# Superport ERP System - Project Rules v2.0
|
||||
# Superport ERP System
|
||||
|
||||
> 💡 **Note**: Global Claude Code rules from `~/.claude/CLAUDE.md` are automatically applied. This document contains **project-specific** configurations only.
|
||||
> 💡 **Note**: Global Claude Code rules are in `~/.claude/CLAUDE.md`. This document contains project-specific context.
|
||||
|
||||
## 🎯 Project Identity
|
||||
## 🎯 Project Overview
|
||||
|
||||
**Superport**는 Rust 백엔드 + Flutter 웹/모바일 기반의 **엔터프라이즈 ERP 시스템**입니다.
|
||||
**Superport**는 기업용 장비 관리 및 유지보수를 위한 클라우드 기반 ERP 시스템입니다.
|
||||
|
||||
### Core Domains
|
||||
- **Equipment Management**: 장비 입고/출고, 시리얼 번호 추적, 재고 관리
|
||||
- **Company Management**: 고객사 정보, 다중 지점 관리
|
||||
- **User Management**: 역할 기반 접근 제어 (S: 관리자, M: 멤버)
|
||||
- **License Management**: 유지보수 라이선스, 만료일 추적
|
||||
- **Warehouse Management**: 창고 위치 체계적 관리
|
||||
### Business Purpose
|
||||
- 장비 입출고 및 재고 관리 자동화
|
||||
- 유지보수 라이선스 만료일 추적
|
||||
- 고객사별 장비 배치 현황 관리
|
||||
- 실시간 대시보드를 통한 경영 인사이트 제공
|
||||
|
||||
## 🏗️ Architecture Rules
|
||||
### Target Users
|
||||
- **관리자 (Admin)**: 전체 시스템 관리, 사용자 권한 설정
|
||||
- **매니저 (Manager)**: 장비 입출고 승인, 라이선스 관리
|
||||
- **일반 사용자 (Member)**: 장비 조회, 기본 작업 수행
|
||||
|
||||
### Clean Architecture Structure
|
||||
```
|
||||
lib/
|
||||
├── core/ # ⚠️ 핵심 설정 - 신중히 수정
|
||||
│ ├── api_client.dart # Dio/Retrofit 설정
|
||||
│ ├── exceptions.dart # 전역 예외 처리
|
||||
│ └── navigation.dart # 라우팅 관리
|
||||
├── data/ # 데이터 레이어
|
||||
│ ├── dto/ # API 응답 모델 (Freezed)
|
||||
│ ├── repositories/ # 데이터 소스 추상화
|
||||
│ └── services/ # API 서비스 (Retrofit)
|
||||
├── domain/ # 비즈니스 로직
|
||||
│ ├── entities/ # 도메인 모델
|
||||
│ ├── repositories/ # Repository 인터페이스
|
||||
│ └── usecases/ # 비즈니스 로직
|
||||
├── services/ # 애플리케이션 서비스
|
||||
│ ├── auth_service.dart # JWT 인증 관리
|
||||
│ ├── api_service.dart # API 호출 관리
|
||||
│ └── storage_service.dart # 로컬 저장소
|
||||
├── screens/ # Feature-First UI
|
||||
│ └── [feature]/
|
||||
│ ├── controllers/ # Provider 기반 상태 관리
|
||||
│ ├── widgets/ # 재사용 컴포넌트
|
||||
│ └── [feature]_form.dart
|
||||
└── di/ # GetIt 의존성 주입
|
||||
```
|
||||
## 🏗️ Technical Architecture
|
||||
|
||||
### Architecture Constraints
|
||||
### Tech Stack
|
||||
```yaml
|
||||
constraints:
|
||||
- "Controller는 반드시 ChangeNotifier 상속"
|
||||
- "모든 API 호출은 ApiService 경유"
|
||||
- "DTO는 Freezed + JsonSerializable 필수"
|
||||
- "화면별 Controller 분리 원칙"
|
||||
- "Mock과 Real 서비스 완전 분리"
|
||||
Frontend:
|
||||
platform: Flutter Web (Mobile ready)
|
||||
state_management: Provider + ChangeNotifier
|
||||
ui_framework: ShadCN Flutter Port
|
||||
api_client: Dio + Retrofit
|
||||
code_generation: Freezed + JsonSerializable
|
||||
|
||||
Backend:
|
||||
language: Rust
|
||||
framework: Actix-Web
|
||||
database: PostgreSQL
|
||||
auth: JWT (24시간 만료)
|
||||
api_url: https://api-dev.beavercompany.co.kr
|
||||
source_path: /Users/maximilian.j.sul/Documents/flutter/superport_api
|
||||
|
||||
Infrastructure:
|
||||
hosting: AWS (예정)
|
||||
storage: S3 (예정)
|
||||
ci_cd: GitHub Actions (예정)
|
||||
```
|
||||
|
||||
## 💻 Development Environment
|
||||
### Project Structure
|
||||
```
|
||||
/Users/maximilian.j.sul/Documents/flutter/
|
||||
├── superport/ # Flutter Frontend
|
||||
│ ├── lib/
|
||||
│ │ ├── core/ # 핵심 설정 및 유틸리티
|
||||
│ │ ├── data/ # API 통신 레이어
|
||||
│ │ │ ├── models/ # Freezed DTO
|
||||
│ │ │ └── datasources/ # API 클라이언트
|
||||
│ │ ├── screens/ # UI 화면
|
||||
│ │ │ └── [feature]/
|
||||
│ │ │ ├── controllers/ # 상태 관리
|
||||
│ │ │ └── widgets/ # UI 컴포넌트
|
||||
│ │ └── services/ # 비즈니스 로직
|
||||
│
|
||||
└── superport_api/ # Rust Backend
|
||||
├── src/
|
||||
│ ├── handlers/ # API 엔드포인트
|
||||
│ ├── services/ # 비즈니스 로직
|
||||
│ └── entities/ # DB 모델
|
||||
└── migrations/ # DB 마이그레이션
|
||||
```
|
||||
|
||||
### API Endpoints
|
||||
## ✅ Implementation Status
|
||||
|
||||
### Completed Features (100%)
|
||||
- ✅ **인증 시스템**: JWT 기반 로그인/로그아웃
|
||||
- ✅ **회사 관리**: CRUD, 지점 관리, 연락처 정보
|
||||
- ✅ **사용자 관리**: 계정 생성, 권한 설정 (Admin/Manager/Member)
|
||||
- ✅ **창고 위치 관리**: 입고지 등록 및 관리
|
||||
- ✅ **장비 입고**: 시리얼 번호 추적, 수량 관리
|
||||
- ✅ **라이선스 관리**: 유지보수 기간, 만료일 알림
|
||||
|
||||
### In Progress (70%)
|
||||
- 🔄 **장비 출고**: API 연동 완료, UI 개선 필요
|
||||
- 🔄 **대시보드**: 기본 통계 표시, 차트 구현 중
|
||||
- 🔄 **검색 및 필터**: 기본 검색 구현, 고급 필터 개발 중
|
||||
|
||||
### Not Started (0%)
|
||||
- ⏳ **장비 대여**: 대여/반납 프로세스
|
||||
- ⏳ **장비 폐기**: 폐기 사유 및 이력 관리
|
||||
- ⏳ **보고서 생성**: Excel/PDF 내보내기
|
||||
- ⏳ **모바일 앱**: 반응형 레이아웃 최적화
|
||||
- ⏳ **알림 시스템**: 이메일/푸시 알림
|
||||
|
||||
## 🐛 Known Issues
|
||||
|
||||
### Critical
|
||||
```yaml
|
||||
development:
|
||||
base_url: "https://api-dev.beavercompany.co.kr"
|
||||
test_account: "admin@test.com / Test123!@#"
|
||||
jwt_expiry: 24h
|
||||
시리얼_번호_중복:
|
||||
location: "장비 입고 프로세스"
|
||||
issue: "백엔드에서 중복 체크 미구현"
|
||||
workaround: "프론트엔드 임시 검증"
|
||||
priority: HIGH
|
||||
|
||||
production:
|
||||
base_url: "TBD"
|
||||
security: "JWT + Secure Storage"
|
||||
권한_체크_누락:
|
||||
location: ["warehouse_location", "overview"]
|
||||
issue: "일부 화면에서 역할 기반 접근 제어 미적용"
|
||||
impact: "모든 사용자가 접근 가능"
|
||||
priority: HIGH
|
||||
```
|
||||
|
||||
### Environment Switching
|
||||
```dart
|
||||
// 환경 변수 설정 (.env)
|
||||
API_MODE=mock # mock | real
|
||||
BASE_URL=https://api-dev.beavercompany.co.kr
|
||||
|
||||
// 코드에서 환경 전환
|
||||
final isMockMode = dotenv.env['API_MODE'] == 'mock';
|
||||
if (isMockMode) {
|
||||
GetIt.I.registerSingleton<ApiService>(MockApiService());
|
||||
} else {
|
||||
GetIt.I.registerSingleton<ApiService>(RealApiService());
|
||||
}
|
||||
```
|
||||
|
||||
## 🧪 Test Automation System
|
||||
|
||||
### Test Infrastructure
|
||||
```dart
|
||||
// 모든 화면 테스트는 BaseScreenTest 상속
|
||||
abstract class BaseScreenTest {
|
||||
// 자동 에러 진단 및 수정
|
||||
ApiErrorDiagnostics diagnostics;
|
||||
|
||||
// 한국식 현실적 테스트 데이터
|
||||
TestDataGenerator generator;
|
||||
|
||||
// 병렬 실행 제어 (최대 3개)
|
||||
SemaphoreManager semaphore;
|
||||
}
|
||||
```
|
||||
|
||||
### Test Execution Priority
|
||||
### Minor
|
||||
```yaml
|
||||
test_order:
|
||||
1: "Company Management" # 회사 먼저 생성
|
||||
2: "User Management" # 회사에 사용자 연결
|
||||
3: "Warehouse Location" # 창고 위치 설정
|
||||
4: "Equipment In" # 장비 입고
|
||||
5: "License Management" # 라이선스 등록
|
||||
6: "Equipment Out" # 장비 출고
|
||||
7: "Overview Dashboard" # 통계 확인
|
||||
상태_갱신_지연:
|
||||
location: "CRUD 작업 후 리스트 화면"
|
||||
issue: "일부 화면에서 자동 새로고침 미작동"
|
||||
workaround: "수동 새로고침"
|
||||
priority: MEDIUM
|
||||
|
||||
날짜_포맷:
|
||||
location: "라이선스 만료일"
|
||||
issue: "한국 시간대 표시 불일치"
|
||||
priority: LOW
|
||||
```
|
||||
|
||||
### Test Commands
|
||||
## 📋 TODO List
|
||||
|
||||
### Immediate (This Week)
|
||||
- [ ] 장비 출고 프로세스 완성
|
||||
- [ ] 대시보드 차트 구현 (Chart.js 통합)
|
||||
- [ ] 시리얼 번호 중복 체크 백엔드 구현
|
||||
- [ ] 권한 체크 누락 화면 수정
|
||||
|
||||
### Short Term (This Month)
|
||||
- [ ] 장비 대여/반납 기능 구현
|
||||
- [ ] 고급 검색 필터 구현
|
||||
- [ ] Excel 내보내기 기능
|
||||
- [ ] 성능 최적화 (가상 스크롤링)
|
||||
|
||||
### Long Term
|
||||
- [ ] 모바일 앱 최적화
|
||||
- [ ] 푸시 알림 시스템
|
||||
- [ ] 다국어 지원 (영어)
|
||||
- [ ] 대시보드 커스터마이징
|
||||
|
||||
## 🔑 Key Decisions
|
||||
|
||||
### 2025-01-07
|
||||
- **Decision**: Mock 서비스 제거, Real API 전용으로 전환
|
||||
- **Reason**: 개발 환경 단순화 및 실제 환경 테스트 강화
|
||||
|
||||
### 2025-01-06
|
||||
- **Decision**: Provider 패턴 유지 (Riverpod 마이그레이션 보류)
|
||||
- **Reason**: 현재 구조가 안정적, 팀 학습 곡선 고려
|
||||
|
||||
### 2024-12-20
|
||||
- **Decision**: Flutter Web 우선 개발
|
||||
- **Reason**: 빠른 배포와 크로스 플랫폼 지원
|
||||
|
||||
## 🚀 Quick Commands
|
||||
|
||||
### Development
|
||||
```bash
|
||||
# 전체 테스트 실행 (병렬)
|
||||
flutter test test/master_test_suite.dart
|
||||
# Start development (Real API)
|
||||
flutter run -d chrome
|
||||
|
||||
# 특정 화면 테스트
|
||||
flutter test test/screens/company/company_test.dart
|
||||
# Run tests
|
||||
flutter test
|
||||
|
||||
# Mock 모드 테스트
|
||||
API_MODE=mock flutter test
|
||||
|
||||
# 에러 진단 모드
|
||||
flutter test --dart-define=DIAGNOSTIC_MODE=true
|
||||
```
|
||||
|
||||
## 🎨 UI/UX Standards
|
||||
|
||||
### Design System
|
||||
```yaml
|
||||
base_template: "Metronic Admin Template"
|
||||
component_library: "ShadCN Flutter Port"
|
||||
|
||||
colors:
|
||||
primary: "#5867dd" # Metronic 기본색
|
||||
secondary: "#34bfa3"
|
||||
background: "#f7f8fa"
|
||||
error: "#fd397a"
|
||||
success: "#0abb87"
|
||||
|
||||
typography:
|
||||
font_family: "NotoSansKR"
|
||||
korean_support: true
|
||||
|
||||
layout:
|
||||
style: "Microsoft Dynamics 365"
|
||||
structure: "Header + Sidebar + Content"
|
||||
responsive: "Web First → Mobile Adaptive"
|
||||
```
|
||||
|
||||
### Component Patterns
|
||||
```dart
|
||||
// 모든 폼은 이 패턴 따르기
|
||||
class EntityForm extends StatefulWidget {
|
||||
final EntityController controller;
|
||||
final FormMode mode; // create | edit | view
|
||||
|
||||
// 필수 섹션
|
||||
Widget buildBasicInfo() {}
|
||||
Widget buildDetailInfo() {}
|
||||
Widget buildActionButtons() {}
|
||||
}
|
||||
|
||||
// 리스트 화면 패턴
|
||||
class EntityList extends StatelessWidget {
|
||||
// 필수 요소
|
||||
Widget buildSearchBar() {}
|
||||
Widget buildFilterOptions() {}
|
||||
Widget buildDataTable() {}
|
||||
Widget buildPagination() {}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔌 API Integration Rules
|
||||
|
||||
### Error Handling Strategy
|
||||
```dart
|
||||
// 모든 API 호출은 이 패턴 사용
|
||||
try {
|
||||
final response = await apiService.call();
|
||||
return Right(response);
|
||||
} on DioException catch (e) {
|
||||
// 422개 에러 패턴 자동 분석
|
||||
final diagnosis = ApiErrorDiagnostics.analyze(e);
|
||||
return Left(ApiFailure(
|
||||
code: diagnosis.code,
|
||||
message: diagnosis.userMessage, // 한국어
|
||||
technicalDetails: diagnosis.details,
|
||||
));
|
||||
}
|
||||
```
|
||||
|
||||
### Response Parsing Rules
|
||||
```dart
|
||||
// JSON 파싱 주의사항
|
||||
rules:
|
||||
- "null 값 안전 처리 필수"
|
||||
- "날짜는 ISO 8601 형식"
|
||||
- "ID는 항상 String 타입"
|
||||
- "빈 배열은 [] 반환"
|
||||
- "중첩 객체는 별도 DTO 생성"
|
||||
```
|
||||
|
||||
## 🚨 Critical Areas & Known Issues
|
||||
|
||||
### ⚠️ Current Gotchas
|
||||
```yaml
|
||||
equipment_in:
|
||||
issue: "시리얼 번호 중복 체크 미구현"
|
||||
workaround: "프론트엔드에서 임시 검증"
|
||||
|
||||
license_management:
|
||||
issue: "만료일 계산 로직 불일치"
|
||||
note: "백엔드와 프론트엔드 로직 통일 필요"
|
||||
|
||||
user_permission:
|
||||
issue: "권한 체크 일부 화면 누락"
|
||||
affected: ["warehouse_location", "overview"]
|
||||
```
|
||||
|
||||
### 🔥 Hot Paths (성능 주의)
|
||||
```yaml
|
||||
critical_operations:
|
||||
- path: "Equipment List with 10000+ items"
|
||||
solution: "Virtual scrolling 구현됨"
|
||||
|
||||
- path: "Dashboard statistics calculation"
|
||||
solution: "5분 캐싱 적용"
|
||||
|
||||
- path: "Company branch tree loading"
|
||||
solution: "Lazy loading 필수"
|
||||
```
|
||||
|
||||
## 📊 Current Sprint Focus
|
||||
|
||||
### Active Development (2025-01-06)
|
||||
```yaml
|
||||
priority_1:
|
||||
task: "Overview Dashboard 완성"
|
||||
acceptance_criteria:
|
||||
- "실시간 통계 데이터 정확성"
|
||||
- "차트 렌더링 성능 최적화"
|
||||
- "필터링 기능 구현"
|
||||
|
||||
priority_2:
|
||||
task: "Equipment Out 프로세스"
|
||||
blockers:
|
||||
- "출고 승인 워크플로우 미정"
|
||||
- "재고 차감 로직 검증 필요"
|
||||
|
||||
priority_3:
|
||||
task: "Mobile App 변환 준비"
|
||||
requirements:
|
||||
- "반응형 레이아웃 점검"
|
||||
- "터치 제스처 최적화"
|
||||
```
|
||||
|
||||
## 🧬 Code Generation Commands
|
||||
|
||||
### Freezed & JsonSerializable
|
||||
```bash
|
||||
# 단일 파일 생성
|
||||
# Generate code (Freezed, JsonSerializable)
|
||||
flutter pub run build_runner build --delete-conflicting-outputs
|
||||
|
||||
# 전체 재생성 (주의: 시간 소요)
|
||||
flutter pub run build_runner build --delete-conflicting-outputs
|
||||
# API integration test
|
||||
./test_api_integration.sh
|
||||
|
||||
# Watch mode (개발 중)
|
||||
flutter pub run build_runner watch
|
||||
# Start backend API (별도 터미널)
|
||||
cd /Users/maximilian.j.sul/Documents/flutter/superport_api
|
||||
cargo run
|
||||
|
||||
# View API logs
|
||||
cd /Users/maximilian.j.sul/Documents/flutter/superport_api
|
||||
tail -f logs/api.log
|
||||
```
|
||||
|
||||
### Injectable (DI)
|
||||
```bash
|
||||
# DI 설정 재생성
|
||||
flutter pub run build_runner build --delete-conflicting-outputs
|
||||
### API Configuration
|
||||
```
|
||||
Base URL: https://api-dev.beavercompany.co.kr
|
||||
Test Account: admin@superport.kr / admin123!
|
||||
API Source Code: /Users/maximilian.j.sul/Documents/flutter/superport_api
|
||||
```
|
||||
|
||||
## 🔍 Debugging Helpers
|
||||
## 📞 Team Contacts
|
||||
|
||||
### Quick Debug Commands
|
||||
```dart
|
||||
// API 응답 로깅
|
||||
ApiService.enableLogging = true;
|
||||
|
||||
// Mock 데이터 확인
|
||||
MockDataViewer.show(context);
|
||||
|
||||
// 현재 인증 상태
|
||||
AuthService.debugPrintToken();
|
||||
|
||||
// Controller 상태 추적
|
||||
controller.addListener(() => print(controller.debugState));
|
||||
```
|
||||
|
||||
### Performance Monitoring
|
||||
```dart
|
||||
// 화면 렌더링 시간 측정
|
||||
Timeline.startSync('ScreenRender');
|
||||
// ... rendering code
|
||||
Timeline.finishSync();
|
||||
|
||||
// API 호출 시간 추적
|
||||
final stopwatch = Stopwatch()..start();
|
||||
await apiCall();
|
||||
print('API took: ${stopwatch.elapsed}');
|
||||
```
|
||||
|
||||
## 📝 Commit Message Convention
|
||||
|
||||
### Project-Specific Prefixes
|
||||
```
|
||||
equipment: 장비 관리 관련
|
||||
company: 회사 관리 관련
|
||||
user: 사용자 관리 관련
|
||||
license: 유지보수 라이선스 관련
|
||||
warehouse: 창고 관련
|
||||
dashboard: 대시보드 관련
|
||||
auth: 인증/권한 관련
|
||||
api: API 연동 관련
|
||||
```
|
||||
|
||||
### Examples
|
||||
```
|
||||
equipment: 시리얼 번호 중복 검증 로직 추가
|
||||
company: 지점 트리 구조 lazy loading 구현
|
||||
test: Equipment In 자동화 테스트 완성
|
||||
api: 422 에러 자동 복구 메커니즘 구현
|
||||
```
|
||||
|
||||
## 🎯 Success Metrics
|
||||
|
||||
### Code Quality Standards
|
||||
```yaml
|
||||
flutter_analyze:
|
||||
errors: 0
|
||||
warnings: < 10
|
||||
info: < 50
|
||||
|
||||
test_coverage:
|
||||
minimum: 80%
|
||||
critical_paths: 100%
|
||||
|
||||
performance:
|
||||
initial_load: < 3s
|
||||
api_response: < 500ms
|
||||
list_render: < 100ms
|
||||
```
|
||||
|
||||
## 🚀 Quick Start Guide
|
||||
|
||||
### For New Developers
|
||||
```bash
|
||||
# 1. 환경 설정
|
||||
cp .env.example .env
|
||||
flutter pub get
|
||||
|
||||
# 2. 코드 생성
|
||||
flutter pub run build_runner build --delete-conflicting-outputs
|
||||
|
||||
# 3. Mock 모드로 시작
|
||||
API_MODE=mock flutter run -d chrome
|
||||
|
||||
# 4. 테스트 실행
|
||||
flutter test test/master_test_suite.dart
|
||||
|
||||
# 5. 실제 API 연동
|
||||
API_MODE=real flutter run -d chrome
|
||||
```
|
||||
- **Backend API Issues**: Rust 백엔드 팀
|
||||
- **UI/UX Questions**: 디자인 팀
|
||||
- **Business Logic**: 프로덕트 매니저
|
||||
|
||||
---
|
||||
|
||||
**Version**: 2.0
|
||||
**Last Updated**: 2025-01-06
|
||||
**Project Stage**: Production Ready
|
||||
**Next Milestone**: Mobile App Release
|
||||
**Project Stage**: Development (70% Complete)
|
||||
**Next Milestone**: Beta Release (2025-02-01)
|
||||
**Last Updated**: 2025-01-08
|
||||
**Version**: 3.0
|
||||
@@ -1,10 +1,13 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:superport/models/equipment_unified_model.dart';
|
||||
import 'package:superport/models/company_model.dart';
|
||||
import 'package:superport/models/company_branch_info.dart';
|
||||
import 'package:superport/models/address_model.dart';
|
||||
import 'package:superport/services/mock_data_service.dart';
|
||||
import 'package:superport/services/equipment_service.dart';
|
||||
import 'package:superport/services/company_service.dart';
|
||||
import 'package:superport/utils/constants.dart';
|
||||
|
||||
/// 장비 출고 폼 컨트롤러
|
||||
@@ -195,22 +198,55 @@ class EquipmentOutFormController extends ChangeNotifier {
|
||||
}
|
||||
|
||||
try {
|
||||
// TODO: 실제 저장 로직 구현
|
||||
// 현재는 Mock 데이터 서비스에 저장
|
||||
// API를 통한 출고 처리
|
||||
final equipmentService = GetIt.instance<EquipmentService>();
|
||||
final companyService = GetIt.instance<CompanyService>();
|
||||
|
||||
// 회사 ID 가져오기
|
||||
int? companyId;
|
||||
int? branchId;
|
||||
|
||||
// 선택된 회사 정보에서 ID 추출
|
||||
if (selectedCompanies[0] != null) {
|
||||
final companies = await companyService.getCompanies(search: selectedCompanies[0]);
|
||||
if (companies.isNotEmpty) {
|
||||
companyId = companies.first.id;
|
||||
// TODO: 지점 ID 처리 로직 추가
|
||||
}
|
||||
}
|
||||
|
||||
if (companyId == null) {
|
||||
throw Exception('출고처 정보를 찾을 수 없습니다.');
|
||||
}
|
||||
|
||||
if (isEditMode) {
|
||||
// 수정 모드
|
||||
// dataService.updateEquipmentOut(...)
|
||||
// 수정 모드 - 현재 미구현
|
||||
throw UnimplementedError('출고 수정 기능은 아직 구현되지 않았습니다.');
|
||||
} else {
|
||||
// 생성 모드
|
||||
if (selectedEquipments != null && selectedEquipments!.isNotEmpty) {
|
||||
// 다중 장비 출고
|
||||
for (var equipmentData in selectedEquipments!) {
|
||||
// dataService.addEquipmentOut(...)
|
||||
final equipment = equipmentData['equipment'] as Equipment;
|
||||
if (equipment.id != null) {
|
||||
await equipmentService.equipmentOut(
|
||||
equipmentId: equipment.id!,
|
||||
quantity: equipment.quantity,
|
||||
companyId: companyId,
|
||||
branchId: branchId,
|
||||
notes: note ?? remarkController.text,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if (selectedEquipment != null) {
|
||||
} else if (selectedEquipment != null && selectedEquipment!.id != null) {
|
||||
// 단일 장비 출고
|
||||
// dataService.addEquipmentOut(...)
|
||||
await equipmentService.equipmentOut(
|
||||
equipmentId: selectedEquipment!.id!,
|
||||
quantity: selectedEquipment!.quantity,
|
||||
companyId: companyId,
|
||||
branchId: branchId,
|
||||
notes: note ?? remarkController.text,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
56
test_api_integration.sh
Executable file
56
test_api_integration.sh
Executable file
@@ -0,0 +1,56 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Superport API 통합 테스트 스크립트
|
||||
# 작성일: 2025-01-07
|
||||
|
||||
echo "======================================"
|
||||
echo "Superport API 통합 테스트 시작"
|
||||
echo "======================================"
|
||||
|
||||
# 색상 정의
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# API 기본 URL
|
||||
API_URL="https://api-dev.beavercompany.co.kr"
|
||||
|
||||
# 테스트 계정
|
||||
TEST_EMAIL="admin@superport.kr"
|
||||
TEST_PASSWORD="admin123!"
|
||||
|
||||
echo -e "\n${YELLOW}1. 헬스 체크${NC}"
|
||||
curl -s -X GET "$API_URL/health" | jq '.' || echo -e "${RED}헬스 체크 실패${NC}"
|
||||
|
||||
echo -e "\n${YELLOW}2. 로그인 테스트${NC}"
|
||||
TOKEN=$(curl -s -X POST "$API_URL/auth/login" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"email\":\"$TEST_EMAIL\",\"password\":\"$TEST_PASSWORD\"}" | jq -r '.data.token')
|
||||
|
||||
if [ -z "$TOKEN" ] || [ "$TOKEN" = "null" ]; then
|
||||
echo -e "${RED}로그인 실패! 토큰을 받지 못했습니다.${NC}"
|
||||
exit 1
|
||||
else
|
||||
echo -e "${GREEN}로그인 성공! 토큰 획득${NC}"
|
||||
fi
|
||||
|
||||
echo -e "\n${YELLOW}3. 장비 목록 조회${NC}"
|
||||
curl -s -X GET "$API_URL/equipment" \
|
||||
-H "Authorization: Bearer $TOKEN" | jq '.data[0] | {id, equipmentNumber, status}' || echo -e "${RED}장비 조회 실패${NC}"
|
||||
|
||||
echo -e "\n${YELLOW}4. 회사 목록 조회${NC}"
|
||||
curl -s -X GET "$API_URL/companies" \
|
||||
-H "Authorization: Bearer $TOKEN" | jq '.data[0] | {id, name, isActive}' || echo -e "${RED}회사 조회 실패${NC}"
|
||||
|
||||
echo -e "\n${YELLOW}5. 창고 위치 목록 조회${NC}"
|
||||
curl -s -X GET "$API_URL/warehouse-locations" \
|
||||
-H "Authorization: Bearer $TOKEN" | jq '.data[0] | {id, name, isActive}' || echo -e "${RED}창고 조회 실패${NC}"
|
||||
|
||||
echo -e "\n${YELLOW}6. 라이선스 목록 조회${NC}"
|
||||
curl -s -X GET "$API_URL/licenses" \
|
||||
-H "Authorization: Bearer $TOKEN" | jq '.data[0] | {id, licenseKey, isActive}' || echo -e "${RED}라이선스 조회 실패${NC}"
|
||||
|
||||
echo -e "\n======================================"
|
||||
echo -e "${GREEN}API 통합 테스트 완료${NC}"
|
||||
echo "======================================"
|
||||
53
test_crud_operations.md
Normal file
53
test_crud_operations.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# CRUD 작업 후 화면 갱신 테스트 체크리스트
|
||||
|
||||
## 테스트 일시
|
||||
- 작성일: 2025-01-07
|
||||
- 테스트 환경: API 모드 (Mock 비활성화)
|
||||
|
||||
## 1. 장비 관리 (Equipment)
|
||||
|
||||
### 입고 (Equipment In)
|
||||
- [ ] 새 장비 입고 → 리스트 화면에 즉시 반영
|
||||
- [ ] 입고 정보 수정 → 리스트 화면에 변경사항 반영
|
||||
- [ ] 입고 삭제 → 리스트에서 제거
|
||||
|
||||
### 출고 (Equipment Out)
|
||||
- [ ] 장비 출고 처리 → 상태 변경 확인
|
||||
- [ ] 출고 정보 수정 → 변경사항 반영
|
||||
- [ ] 출고 취소 → 상태 복구
|
||||
|
||||
## 2. 회사 관리 (Company)
|
||||
- [ ] 새 회사 추가 → 리스트에 즉시 표시
|
||||
- [ ] 회사 정보 수정 → 변경사항 반영
|
||||
- [ ] 회사 삭제 → 리스트에서 제거
|
||||
- [ ] 지점 추가/수정/삭제 → 변경사항 반영
|
||||
|
||||
## 3. 창고 위치 관리 (Warehouse Location)
|
||||
- [ ] 새 창고 추가 → 리스트에 표시
|
||||
- [ ] 창고 정보 수정 → 변경사항 반영
|
||||
- [ ] 창고 삭제 → 리스트에서 제거
|
||||
|
||||
## 4. 유지보수 라이선스 (License)
|
||||
- [ ] 새 라이선스 추가 → 리스트에 표시
|
||||
- [ ] 라이선스 정보 수정 → 변경사항 반영
|
||||
- [ ] 라이선스 삭제 → 리스트에서 제거
|
||||
- [ ] 라이선스 할당/해제 → 상태 변경 반영
|
||||
|
||||
## 5. 사용자 관리 (User)
|
||||
- [ ] 새 사용자 추가 → 리스트에 표시
|
||||
- [ ] 사용자 정보 수정 → 변경사항 반영
|
||||
- [ ] 사용자 삭제 → 리스트에서 제거
|
||||
- [ ] 권한 변경 → 즉시 반영
|
||||
|
||||
## 테스트 결과 기록
|
||||
|
||||
### 문제 발견 시:
|
||||
1. 화면명:
|
||||
2. 작업 유형: (생성/수정/삭제)
|
||||
3. 증상:
|
||||
4. 예상 원인:
|
||||
|
||||
### 해결 방법:
|
||||
1. 수정한 파일:
|
||||
2. 수정 내용:
|
||||
3. 테스트 결과:
|
||||
Reference in New Issue
Block a user