feat(app): finalize ad gated flows and weather

- add AppLogger and replace scattered print logging\n- implement ad-gated recommendation flow with reminder handling and calendar link\n- complete Bluetooth share pipeline with ad gate and merge\n- integrate KMA weather API with caching and dart-define decoding\n- add NaverUrlProcessor refactor and restore restaurant repository tests
This commit is contained in:
JiWoong Sul
2025-11-22 00:10:51 +09:00
parent 947fe59486
commit 2a01fa50c6
43 changed files with 1777 additions and 571 deletions

View File

@@ -1,5 +1,6 @@
import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import '../../utils/app_logger.dart';
/// 로깅 인터셉터
///
@@ -13,16 +14,18 @@ class LoggingInterceptor extends Interceptor {
final method = options.method;
final headers = options.headers;
print('═══════════════════════════════════════════════════════════════');
print('>>> REQUEST [$method] $uri');
print('>>> Headers: $headers');
AppLogger.debug(
'═══════════════════════════════════════════════════════════════',
);
AppLogger.debug('>>> REQUEST [$method] $uri');
AppLogger.debug('>>> Headers: $headers');
if (options.data != null) {
print('>>> Body: ${options.data}');
AppLogger.debug('>>> Body: ${options.data}');
}
if (options.queryParameters.isNotEmpty) {
print('>>> Query Parameters: ${options.queryParameters}');
AppLogger.debug('>>> Query Parameters: ${options.queryParameters}');
}
}
@@ -35,21 +38,25 @@ class LoggingInterceptor extends Interceptor {
final statusCode = response.statusCode;
final uri = response.requestOptions.uri;
print('<<< RESPONSE [$statusCode] $uri');
AppLogger.debug('<<< RESPONSE [$statusCode] $uri');
if (response.headers.map.isNotEmpty) {
print('<<< Headers: ${response.headers.map}');
AppLogger.debug('<<< Headers: ${response.headers.map}');
}
// 응답 본문은 너무 길 수 있으므로 처음 500자만 출력
final responseData = response.data.toString();
if (responseData.length > 500) {
print('<<< Body: ${responseData.substring(0, 500)}...(truncated)');
AppLogger.debug(
'<<< Body: ${responseData.substring(0, 500)}...(truncated)',
);
} else {
print('<<< Body: $responseData');
AppLogger.debug('<<< Body: $responseData');
}
print('═══════════════════════════════════════════════════════════════');
AppLogger.debug(
'═══════════════════════════════════════════════════════════════',
);
}
return handler.next(response);
@@ -61,17 +68,21 @@ class LoggingInterceptor extends Interceptor {
final uri = err.requestOptions.uri;
final message = err.message;
print('═══════════════════════════════════════════════════════════════');
print('!!! ERROR $uri');
print('!!! Message: $message');
AppLogger.debug(
'═══════════════════════════════════════════════════════════════',
);
AppLogger.debug('!!! ERROR $uri');
AppLogger.debug('!!! Message: $message');
if (err.response != null) {
print('!!! Status Code: ${err.response!.statusCode}');
print('!!! Response: ${err.response!.data}');
AppLogger.debug('!!! Status Code: ${err.response!.statusCode}');
AppLogger.debug('!!! Response: ${err.response!.data}');
}
print('!!! Error Type: ${err.type}');
print('═══════════════════════════════════════════════════════════════');
AppLogger.debug('!!! Error Type: ${err.type}');
AppLogger.debug(
'═══════════════════════════════════════════════════════════════',
);
}
return handler.next(err);

View File

@@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:math';
import 'package:dio/dio.dart';
import '../network_config.dart';
import '../../utils/app_logger.dart';
import '../../errors/network_exceptions.dart';
/// 재시도 인터셉터
@@ -24,7 +25,7 @@ class RetryInterceptor extends Interceptor {
// 지수 백오프 계산
final delay = _calculateBackoffDelay(retryCount);
print(
AppLogger.debug(
'RetryInterceptor: 재시도 ${retryCount + 1}/${NetworkConfig.maxRetries} - ${delay}ms 대기',
);
@@ -59,7 +60,7 @@ class RetryInterceptor extends Interceptor {
// 네이버 관련 요청은 재시도하지 않음
final url = err.requestOptions.uri.toString();
if (url.contains('naver.com') || url.contains('naver.me')) {
print('RetryInterceptor: 네이버 API 요청은 재시도하지 않음 - $url');
AppLogger.debug('RetryInterceptor: 네이버 API 요청은 재시도하지 않음 - $url');
return false;
}

View File

@@ -1,9 +1,11 @@
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:dio_cache_interceptor/dio_cache_interceptor.dart';
import 'package:dio_cache_interceptor_hive_store/dio_cache_interceptor_hive_store.dart';
import 'package:flutter/foundation.dart';
import 'package:lunchpick/core/utils/app_logger.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:io';
import 'network_config.dart';
import '../errors/network_exceptions.dart';
@@ -88,8 +90,12 @@ class NetworkClient {
);
_dio.interceptors.add(DioCacheInterceptor(options: cacheOptions));
} catch (e) {
debugPrint('NetworkClient: 캐시 설정 실패 - $e');
} catch (e, stackTrace) {
AppLogger.error(
'NetworkClient: 캐시 설정 실패 - $e',
error: e,
stackTrace: stackTrace,
);
// 캐시 실패해도 계속 진행
}
}