fix: API 응답 파싱 오류 수정 및 에러 처리 개선
주요 변경사항: - 창고 관리 API 응답 구조와 DTO 불일치 수정 - WarehouseLocationDto에 code, manager_phone 필드 추가 - RemoteDataSource에서 API 응답을 DTO 구조에 맞게 변환 - 회사 관리 API 응답 파싱 오류 수정 - CompanyResponse의 필수 필드를 nullable로 변경 - PaginatedResponse 구조 매핑 로직 개선 - 에러 처리 및 로깅 개선 - Service Layer에 상세 에러 로깅 추가 - Controller에서 에러 타입별 처리 - 새로운 유틸리티 추가 - ResponseInterceptor: API 응답 정규화 - DebugLogger: 디버깅 도구 - HealthCheckService: 서버 상태 확인 - 문서화 - API 통합 테스트 가이드 - 에러 분석 보고서 - 리팩토링 계획서
This commit is contained in:
@@ -12,6 +12,8 @@ import 'package:superport/data/models/auth/login_response.dart';
|
||||
import 'package:superport/data/models/auth/logout_request.dart';
|
||||
import 'package:superport/data/models/auth/refresh_token_request.dart';
|
||||
import 'package:superport/data/models/auth/token_response.dart';
|
||||
import 'package:superport/core/config/environment.dart' as env;
|
||||
import 'package:superport/services/mock_data_service.dart';
|
||||
|
||||
abstract class AuthService {
|
||||
Future<Either<Failure, LoginResponse>> login(LoginRequest request);
|
||||
@@ -45,6 +47,16 @@ class AuthServiceImpl implements AuthService {
|
||||
@override
|
||||
Future<Either<Failure, LoginResponse>> login(LoginRequest request) async {
|
||||
try {
|
||||
print('[AuthService] login 시작 - useApi: ${env.Environment.useApi}');
|
||||
|
||||
// Mock 모드일 때
|
||||
if (!env.Environment.useApi) {
|
||||
print('[AuthService] Mock 모드로 로그인 처리');
|
||||
return _mockLogin(request);
|
||||
}
|
||||
|
||||
// API 모드일 때
|
||||
print('[AuthService] API 모드로 로그인 처리');
|
||||
final result = await _authRemoteDataSource.login(request);
|
||||
|
||||
return await result.fold(
|
||||
@@ -68,6 +80,61 @@ class AuthServiceImpl implements AuthService {
|
||||
return Left(ServerFailure(message: '로그인 처리 중 오류가 발생했습니다.'));
|
||||
}
|
||||
}
|
||||
|
||||
Future<Either<Failure, LoginResponse>> _mockLogin(LoginRequest request) async {
|
||||
try {
|
||||
// Mock 데이터 서비스의 사용자 확인
|
||||
final mockService = MockDataService();
|
||||
final users = mockService.getAllUsers();
|
||||
|
||||
// 사용자 찾기
|
||||
final user = users.firstWhere(
|
||||
(u) => u.email == request.email,
|
||||
orElse: () => throw Exception('사용자를 찾을 수 없습니다.'),
|
||||
);
|
||||
|
||||
// 비밀번호 확인 (Mock에서는 간단하게 처리)
|
||||
if (request.password != 'admin123' && request.password != 'password123') {
|
||||
return Left(AuthenticationFailure(message: '잘못된 비밀번호입니다.'));
|
||||
}
|
||||
|
||||
// Mock 토큰 생성
|
||||
final mockAccessToken = 'mock_access_token_${DateTime.now().millisecondsSinceEpoch}';
|
||||
final mockRefreshToken = 'mock_refresh_token_${DateTime.now().millisecondsSinceEpoch}';
|
||||
|
||||
// Mock 로그인 응답 생성
|
||||
final loginResponse = LoginResponse(
|
||||
accessToken: mockAccessToken,
|
||||
refreshToken: mockRefreshToken,
|
||||
tokenType: 'Bearer',
|
||||
expiresIn: 3600,
|
||||
user: AuthUser(
|
||||
id: user.id ?? 0,
|
||||
username: user.username ?? '',
|
||||
email: user.email ?? request.email ?? '',
|
||||
name: user.name,
|
||||
role: user.role,
|
||||
),
|
||||
);
|
||||
|
||||
// 토큰 및 사용자 정보 저장
|
||||
await _saveTokens(
|
||||
loginResponse.accessToken,
|
||||
loginResponse.refreshToken,
|
||||
loginResponse.expiresIn,
|
||||
);
|
||||
await _saveUser(loginResponse.user);
|
||||
|
||||
// 인증 상태 변경 알림
|
||||
_authStateController.add(true);
|
||||
|
||||
print('[AuthService] Mock 로그인 성공');
|
||||
return Right(loginResponse);
|
||||
} catch (e) {
|
||||
print('[AuthService] Mock 로그인 실패: $e');
|
||||
return Left(ServerFailure(message: '로그인 처리 중 오류가 발생했습니다.'));
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Either<Failure, void>> logout() async {
|
||||
@@ -164,8 +231,17 @@ class AuthServiceImpl implements AuthService {
|
||||
@override
|
||||
Future<String?> getAccessToken() async {
|
||||
try {
|
||||
return await _secureStorage.read(key: _accessTokenKey);
|
||||
final token = await _secureStorage.read(key: _accessTokenKey);
|
||||
if (token != null && token.length > 20) {
|
||||
print('[AuthService] getAccessToken: Found (${token.substring(0, 20)}...)');
|
||||
} else if (token != null) {
|
||||
print('[AuthService] getAccessToken: Found (${token})');
|
||||
} else {
|
||||
print('[AuthService] getAccessToken: Not found');
|
||||
}
|
||||
return token;
|
||||
} catch (e) {
|
||||
print('[AuthService] getAccessToken error: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -199,6 +275,13 @@ class AuthServiceImpl implements AuthService {
|
||||
String refreshToken,
|
||||
int expiresIn,
|
||||
) async {
|
||||
print('[AuthService] Saving tokens...');
|
||||
final accessTokenPreview = accessToken.length > 20 ? '${accessToken.substring(0, 20)}...' : accessToken;
|
||||
final refreshTokenPreview = refreshToken.length > 20 ? '${refreshToken.substring(0, 20)}...' : refreshToken;
|
||||
print('[AuthService] Access token: $accessTokenPreview');
|
||||
print('[AuthService] Refresh token: $refreshTokenPreview');
|
||||
print('[AuthService] Expires in: $expiresIn seconds');
|
||||
|
||||
await _secureStorage.write(key: _accessTokenKey, value: accessToken);
|
||||
await _secureStorage.write(key: _refreshTokenKey, value: refreshToken);
|
||||
|
||||
@@ -208,6 +291,8 @@ class AuthServiceImpl implements AuthService {
|
||||
key: _tokenExpiryKey,
|
||||
value: expiry.toIso8601String(),
|
||||
);
|
||||
|
||||
print('[AuthService] Tokens saved successfully');
|
||||
}
|
||||
|
||||
Future<void> _saveUser(AuthUser user) async {
|
||||
|
||||
Reference in New Issue
Block a user