From 4a49083ef354dc5525980b23174adcf67bc1a14f Mon Sep 17 00:00:00 2001 From: Yuri Petrov <48598325+petrovyuri@users.noreply.github.com> Date: Thu, 11 Dec 2025 10:27:19 +0300 Subject: [PATCH] =?UTF-8?q?refactor(http):=20=D1=83=D0=B4=D0=B0=D0=BB?= =?UTF-8?q?=D0=B8=D1=82=D1=8C=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5?= =?UTF-8?q?=D0=B9=D1=81=20IHttpClient=20=D0=B8=20=D1=83=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D1=81=D1=82=D0=B8=D1=82=D1=8C=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D1=8E=20AppHttpClient=20=20=20(#42)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor(http): удалить интерфейс IHttpClient и упростить реализацию AppHttpClient - Удален интерфейс IHttpClient, что упростило структуру кода. - AppHttpClient теперь напрямую использует Dio без промежуточного интерфейса. - Обновлены зависимости в репозиториях для использования нового HTTP клиента. * refactor(code): dart format * chore(pr-template): удалить отключения markdownlint из шаблона PR * docs(copilot-instructions): добавить правила проведения Code Review --------- Co-authored-by: petrovyuri --- .github/copilot-instructions.md | 5 + .github/pull_request_template.md | 2 - lib/app/http/app_http_client.dart | 109 +----------------- lib/app/http/i_http_client.dart | 94 --------------- lib/app/theme/app_colors_scheme.dart | 2 +- lib/app/ui_kit/app_snackbar.dart | 18 +-- lib/di/di_container.dart | 9 +- lib/di/di_repositories.dart | 31 ++--- .../data/repository/auth_mock_repository.dart | 3 + .../auth/data/repository/auth_repository.dart | 6 +- .../data/repository/main_mock_repository.dart | 5 +- .../main/data/repository/main_repository.dart | 9 +- .../repository/profile_mock_repository.dart | 5 +- .../data/repository/profile_repository.dart | 8 +- .../data/repository/update_repository.dart | 6 +- 15 files changed, 54 insertions(+), 258 deletions(-) delete mode 100644 lib/app/http/i_http_client.dart diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 5583e1d..fee43c8 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -6,6 +6,11 @@ --- +# Правила проведения Code Review + +## Основные правила проведения Code Review +- Комментарии и описание Pull Request должны быть на русском языке. + # Стиль кода ## Именование diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index ed98222..8764cbf 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,5 +1,3 @@ - - ## Ссылка на задачу или issue (обязательно) diff --git a/lib/app/http/app_http_client.dart b/lib/app/http/app_http_client.dart index 253a3eb..2bef6ac 100644 --- a/lib/app/http/app_http_client.dart +++ b/lib/app/http/app_http_client.dart @@ -1,13 +1,12 @@ import 'package:dio/dio.dart'; import 'package:friflex_starter/app/app_config/app_config.dart'; -import 'package:friflex_starter/app/http/i_http_client.dart'; import 'package:friflex_starter/features/debug/i_debug_service.dart'; /// {@template app_http_client} /// Класс для реализации HTTP-клиента для управления запросами /// {@endtemplate} -final class AppHttpClient implements IHttpClient { +final class AppHttpClient { /// Создает HTTP клиент /// /// Принимает: @@ -18,7 +17,6 @@ final class AppHttpClient implements IHttpClient { required IAppConfig appConfig, }) { _httpClient = Dio(); - _appConfig = appConfig; _httpClient.options ..baseUrl = appConfig.baseUrl @@ -30,111 +28,8 @@ final class AppHttpClient implements IHttpClient { _httpClient.interceptors.add(debugService.dioLogger); } - /// Конфигурация приложения - late final IAppConfig _appConfig; - /// Экземпляр HTTP клиента late final Dio _httpClient; - @override - Future get( - String path, { - Object? data, - Map? queryParameters, - Options? options, - }) async { - _httpClient.options.baseUrl = _appConfig.baseUrl; - - return _httpClient.get( - path, - data: data, - queryParameters: queryParameters, - options: options, - ); - } - - @override - Future post( - String path, { - Object? data, - Map? queryParameters, - Options? options, - }) async { - _httpClient.options.baseUrl = _appConfig.baseUrl; - - return _httpClient.post( - path, - data: data, - queryParameters: queryParameters, - options: options, - ); - } - - @override - Future patch( - String path, { - Object? data, - Map? queryParameters, - Options? options, - }) async { - _httpClient.options.baseUrl = _appConfig.baseUrl; - - return _httpClient.patch( - path, - data: data, - queryParameters: queryParameters, - options: options, - ); - } - - @override - Future put( - String path, { - Object? data, - Map? queryParameters, - Options? options, - }) async { - _httpClient.options.baseUrl = _appConfig.baseUrl; - - return _httpClient.put( - path, - data: data, - queryParameters: queryParameters, - options: options, - ); - } - - @override - Future delete( - String path, { - Object? data, - Map? queryParameters, - Options? options, - }) async { - _httpClient.options.baseUrl = _appConfig.baseUrl; - - return _httpClient.delete( - path, - data: data, - queryParameters: queryParameters, - options: options, - ); - } - - @override - Future head( - String path, { - Object? data, - Map? queryParameters, - Options? options, - }) async { - _httpClient.options.baseUrl = _appConfig.baseUrl; - - return _httpClient.head( - path, - data: data, - queryParameters: queryParameters, - options: options, - ); - } + Dio get client => _httpClient; } diff --git a/lib/app/http/i_http_client.dart b/lib/app/http/i_http_client.dart deleted file mode 100644 index 34d8315..0000000 --- a/lib/app/http/i_http_client.dart +++ /dev/null @@ -1,94 +0,0 @@ -import 'package:dio/dio.dart'; - -/// Класс для описания интерфейса сервиса по управлению HTTP запросами -abstract interface class IHttpClient { - /// Описывает поля HTTP клиента - const IHttpClient(); - - /// Наименование сервиса - static const name = 'IHttpClient'; - - /// Метод для реализации запроса GET - /// - /// Принимает: - /// - [path] - путь к ресурсу - /// - [data] - тело запроса - /// - [queryParameters] - параметры запроса - /// - [options] - конфигурация запроса - Future get( - String path, { - Object? data, - Map? queryParameters, - Options? options, - }); - - /// Метод для реализации запроса POST - /// - /// Принимает: - /// - [path] - путь к ресурсу - /// - [data] - тело запроса - /// - [queryParameters] - параметры запроса - /// - [options] - конфигурация запроса - Future post( - String path, { - Object? data, - Map? queryParameters, - Options? options, - }); - - /// Метод для реализации запроса PATCH - /// - /// Принимает: - /// - [path] - путь к ресурсу - /// - [data] - тело запроса - /// - [queryParameters] - параметры запроса - /// - [options] - конфигурация запроса - Future patch( - String path, { - Object? data, - Map? queryParameters, - Options? options, - }); - - /// Метод для реализации запроса PUT - /// - /// Принимает: - /// - [path] - путь к ресурсу - /// - [data] - тело запроса - /// - [queryParameters] - параметры запроса - /// - [options] - конфигурация запроса - Future put( - String path, { - Object? data, - Map? queryParameters, - Options? options, - }); - - /// Метод для реализации запроса DELETE - /// - /// Принимает: - /// - [path] - путь к ресурсу - /// - [data] - тело запроса - /// - [queryParameters] - параметры запроса - /// - [options] - конфигурация запроса - Future delete( - String path, { - Object? data, - Map? queryParameters, - Options? options, - }); - - /// Метод для реализации запроса POST - /// - /// Принимает: - /// - [path] - путь к ресурсу - /// - [data] - тело запроса - /// - [queryParameters] - параметры запроса - /// - [options] - конфигурация запроса - Future head( - String path, { - Object? data, - Map? queryParameters, - Options? options, - }); -} diff --git a/lib/app/theme/app_colors_scheme.dart b/lib/app/theme/app_colors_scheme.dart index 4b3c653..5cf254f 100644 --- a/lib/app/theme/app_colors_scheme.dart +++ b/lib/app/theme/app_colors_scheme.dart @@ -55,7 +55,7 @@ class AppColors extends ThemeExtension with _$AppColorsTailorMixin { ); /// Цвета тёмной темы - static const AppColors dark = AppColors( + static const AppColors dark = AppColors( testColor: Colors.green, errorSnackbarBackground: Color(0xFF638B8B), successSnackbarBackground: Color(0xFF93C499), diff --git a/lib/app/ui_kit/app_snackbar.dart b/lib/app/ui_kit/app_snackbar.dart index adfa2f7..85f5aee 100644 --- a/lib/app/ui_kit/app_snackbar.dart +++ b/lib/app/ui_kit/app_snackbar.dart @@ -290,21 +290,9 @@ class _Icon extends StatelessWidget { @override Widget build(BuildContext context) { return switch (type) { - .success => const Icon( - Icons.check_circle, - color: Colors.white, - size: 32, - ), - .error => const Icon( - Icons.error, - color: Colors.white, - size: 32, - ), - .info => const Icon( - Icons.info, - color: Colors.white, - size: 32, - ), + .success => const Icon(Icons.check_circle, color: Colors.white, size: 32), + .error => const Icon(Icons.error, color: Colors.white, size: 32), + .info => const Icon(Icons.info, color: Colors.white, size: 32), }; } } diff --git a/lib/di/di_container.dart b/lib/di/di_container.dart index f4fcdb0..5197471 100644 --- a/lib/di/di_container.dart +++ b/lib/di/di_container.dart @@ -1,7 +1,6 @@ import 'package:friflex_starter/app/app_config/app_config.dart'; import 'package:friflex_starter/app/app_env.dart'; import 'package:friflex_starter/app/http/app_http_client.dart'; -import 'package:friflex_starter/app/http/i_http_client.dart'; import 'package:friflex_starter/di/di_repositories.dart'; import 'package:friflex_starter/di/di_services.dart'; import 'package:friflex_starter/di/di_typedefs.dart'; @@ -25,7 +24,7 @@ final class DiContainer { late final IAppConfig appConfig; /// Сервис для работы с HTTP запросами - late final IHttpClient Function(IDebugService, IAppConfig) httpClientFactory; + late final AppHttpClient httpClient; /// Репозитории приложения late final DiRepositories repositories; @@ -47,8 +46,10 @@ final class DiContainer { }; // Инициализация HTTP клиента - httpClientFactory = (debugService, appConfig) => - AppHttpClient(debugService: debugService, appConfig: appConfig); + httpClient = AppHttpClient( + debugService: debugService, + appConfig: appConfig, + ); // Инициализация сервисов services = DiServices() diff --git a/lib/di/di_repositories.dart b/lib/di/di_repositories.dart index dcbc2b9..9493589 100644 --- a/lib/di/di_repositories.dart +++ b/lib/di/di_repositories.dart @@ -77,8 +77,8 @@ final class DiRepositories { // Инициализация репозитория обновлений updatesRepository = _lazyInitRepo( - mockFactory: UpdateMockRepository.new, - mainFactory: UpdateRepository.new, + mockFactory: () => const UpdateMockRepository(), + mainFactory: () => UpdateRepository(httpClient: diContainer.httpClient), onProgress: onProgress, onError: onError, environment: diContainer.env, @@ -86,13 +86,8 @@ final class DiRepositories { // Инициализация репозитория авторизации authRepository = _lazyInitRepo( - mockFactory: AuthMockRepository.new, - mainFactory: () => AuthRepository( - httpClient: diContainer.httpClientFactory( - diContainer.debugService, - diContainer.appConfig, - ), - ), + mockFactory: () => const AuthMockRepository(), + mainFactory: () => AuthRepository(httpClient: diContainer.httpClient), onProgress: onProgress, onError: onError, environment: diContainer.env, @@ -100,13 +95,8 @@ final class DiRepositories { // Инициализация репозитория сервиса управления токеном доступа mainRepository = _lazyInitRepo( - mockFactory: MainMockRepository.new, - mainFactory: () => MainRepository( - httpClient: diContainer.httpClientFactory( - diContainer.debugService, - diContainer.appConfig, - ), - ), + mockFactory: () => const MainMockRepository(), + mainFactory: () => MainRepository(httpClient: diContainer.httpClient), onProgress: onProgress, onError: onError, environment: diContainer.env, @@ -114,13 +104,8 @@ final class DiRepositories { // Инициализация репозитория профиля profileRepository = _lazyInitRepo( - mockFactory: ProfileMockRepository.new, - mainFactory: () => ProfileRepository( - httpClient: diContainer.httpClientFactory( - diContainer.debugService, - diContainer.appConfig, - ), - ), + mockFactory: () => const ProfileMockRepository(), + mainFactory: () => ProfileRepository(httpClient: diContainer.httpClient), onProgress: onProgress, onError: onError, environment: diContainer.env, diff --git a/lib/features/auth/data/repository/auth_mock_repository.dart b/lib/features/auth/data/repository/auth_mock_repository.dart index df2cd5f..531289b 100644 --- a/lib/features/auth/data/repository/auth_mock_repository.dart +++ b/lib/features/auth/data/repository/auth_mock_repository.dart @@ -4,6 +4,9 @@ import 'package:friflex_starter/features/auth/domain/repository/i_auth_repositor /// Mock реализация репозитория авторизации /// {@endtemplate} final class AuthMockRepository implements IAuthRepository { + /// {@macro AuthMockRepository} + const AuthMockRepository(); + @override String get name => 'AuthMockRepository'; } diff --git a/lib/features/auth/data/repository/auth_repository.dart b/lib/features/auth/data/repository/auth_repository.dart index 5ee45ef..799648d 100644 --- a/lib/features/auth/data/repository/auth_repository.dart +++ b/lib/features/auth/data/repository/auth_repository.dart @@ -1,4 +1,4 @@ -import 'package:friflex_starter/app/http/i_http_client.dart'; +import 'package:friflex_starter/app/http/app_http_client.dart'; import 'package:friflex_starter/features/auth/domain/repository/i_auth_repository.dart'; @@ -7,7 +7,9 @@ import 'package:friflex_starter/features/auth/domain/repository/i_auth_repositor /// {@endtemplate} final class AuthRepository implements IAuthRepository { AuthRepository({required this.httpClient}); - final IHttpClient httpClient; + + /// Экземпляр HTTP клиента для взаимодействия с сервером + final AppHttpClient httpClient; @override String get name => 'AuthRepository'; diff --git a/lib/features/main/data/repository/main_mock_repository.dart b/lib/features/main/data/repository/main_mock_repository.dart index 839a6fe..995dfdc 100644 --- a/lib/features/main/data/repository/main_mock_repository.dart +++ b/lib/features/main/data/repository/main_mock_repository.dart @@ -1,9 +1,12 @@ import 'package:friflex_starter/features/main/domain/repository/i_main_repository.dart'; /// {@template MainMockRepository} -/// +/// Мок реализация репозитория главного сервиса /// {@endtemplate} final class MainMockRepository implements IMainRepository { + /// {@macro MainMockRepository} + const MainMockRepository(); + @override String get name => 'MainMockRepository'; } diff --git a/lib/features/main/data/repository/main_repository.dart b/lib/features/main/data/repository/main_repository.dart index 5be3b6c..336db50 100644 --- a/lib/features/main/data/repository/main_repository.dart +++ b/lib/features/main/data/repository/main_repository.dart @@ -1,13 +1,14 @@ -import 'package:friflex_starter/app/http/i_http_client.dart'; - +import 'package:friflex_starter/app/http/app_http_client.dart'; import 'package:friflex_starter/features/main/domain/repository/i_main_repository.dart'; /// {@template MainRepository} -/// +/// Реализация репозитория главного сервиса /// {@endtemplate} final class MainRepository implements IMainRepository { MainRepository({required this.httpClient}); - final IHttpClient httpClient; + + /// Экземпляр HTTP клиента для взаимодействия с сервером + final AppHttpClient httpClient; @override String get name => 'MainRepository'; diff --git a/lib/features/profile/data/repository/profile_mock_repository.dart b/lib/features/profile/data/repository/profile_mock_repository.dart index 7406455..4c22342 100644 --- a/lib/features/profile/data/repository/profile_mock_repository.dart +++ b/lib/features/profile/data/repository/profile_mock_repository.dart @@ -1,9 +1,12 @@ import 'package:friflex_starter/features/profile/domain/repository/i_profile_repository.dart'; /// {@template ProfileMockRepository} -/// +/// Мок реализация репозитория профиля пользователя /// {@endtemplate} final class ProfileMockRepository implements IProfileRepository { + /// {@macro ProfileMockRepository} + const ProfileMockRepository(); + @override String get name => 'ProfileMockRepository'; diff --git a/lib/features/profile/data/repository/profile_repository.dart b/lib/features/profile/data/repository/profile_repository.dart index a3700af..2fb675c 100644 --- a/lib/features/profile/data/repository/profile_repository.dart +++ b/lib/features/profile/data/repository/profile_repository.dart @@ -1,13 +1,15 @@ -import 'package:friflex_starter/app/http/i_http_client.dart'; +import 'package:friflex_starter/app/http/app_http_client.dart'; import 'package:friflex_starter/features/profile/domain/repository/i_profile_repository.dart'; /// {@template ProfileRepository} -/// +/// Реализация репозитория профиля пользователя /// {@endtemplate} final class ProfileRepository implements IProfileRepository { ProfileRepository({required this.httpClient}); - final IHttpClient httpClient; + + /// Экземпляр HTTP клиента для взаимодействия с сервером + final AppHttpClient httpClient; @override String get name => 'ProfileRepository'; diff --git a/lib/features/update/data/repository/update_repository.dart b/lib/features/update/data/repository/update_repository.dart index f20812a..a44ad11 100644 --- a/lib/features/update/data/repository/update_repository.dart +++ b/lib/features/update/data/repository/update_repository.dart @@ -1,3 +1,4 @@ +import 'package:friflex_starter/app/http/app_http_client.dart'; import 'package:friflex_starter/features/update/domain/entity/update_entity.dart'; import 'package:friflex_starter/features/update/domain/repository/i_update_repository.dart'; @@ -6,7 +7,10 @@ import 'package:friflex_starter/features/update/domain/repository/i_update_repos /// {@endtemplate} final class UpdateRepository implements IUpdateRepository { /// {@macro UpdateRepository} - const UpdateRepository(); + UpdateRepository({required this.httpClient}); + + /// Экземпляр HTTP клиента для взаимодействия с сервером + final AppHttpClient httpClient; @override Future checkForUpdates({