From a1f4903bb1adb6ec29879cc4fa5364ccdc21e00d Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:15:38 +0100 Subject: [PATCH 01/19] chore: update MongoDB database name example - Change the example database name in the .env.example file - Update from 'ht_api_db' to 'flutter_news_app_api_server_full_source_code_db' - Ensure users have a clear example of the expected database name --- .env.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.example b/.env.example index a5d3178..fb6d661 100644 --- a/.env.example +++ b/.env.example @@ -4,7 +4,7 @@ # REQUIRED: The full connection string for your MongoDB instance. # The application cannot start without a database connection. -# DATABASE_URL="mongodb://user:password@localhost:27017/ht_api_db" +# DATABASE_URL="mongodb://user:password@localhost:27017/flutter_news_app_api_server_full_source_code_db" # REQUIRED: A secure, randomly generated secret for signing JWTs. # The application cannot start without this. From cb2bd23140be763be0c2779f8a608758026b1f14 Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:16:26 +0100 Subject: [PATCH 02/19] build(deps): update dependency repository locations and names - Update project name and repository URL - Update all dependency package names and repository URLs to reflect new locations - Replace "ht_" prefix with more generic names across all dependencies --- pubspec.yaml | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/pubspec.yaml b/pubspec.yaml index 4d78953..456e53a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ -name: ht_api -description: ht_api is the backend API component of the Headlines Toolkit (HT) project. -repository: https://github.com/headlines-toolkit/ht-api +name: flutter_news_app_api_server_full_source_code +description: ... +repository: https://github.com/flutter-news-app-full-source-code/flutter-news-app-api-server-full-source-code publish_to: none environment: @@ -10,30 +10,30 @@ dependencies: dart_frog: ^1.1.0 dart_jsonwebtoken: ^3.2.0 dotenv: ^4.2.0 - ht_data_client: + data_client: git: - url: https://github.com/headlines-toolkit/ht-data-client.git - ht_data_mongodb: + url: https://github.com/flutter-news-app-full-source-code/data-client.git + data_mongodb: git: - url: https://github.com/headlines-toolkit/ht-data-mongodb.git - ht_data_repository: + url: https://github.com/flutter-news-app-full-source-code/data-mongodb.git + data_repository: git: - url: https://github.com/headlines-toolkit/ht-data-repository.git - ht_email_client: + url: https://github.com/flutter-news-app-full-source-code/data-repository.git + email_client: git: - url: https://github.com/headlines-toolkit/ht-email-client.git - ht_email_repository: + url: https://github.com/flutter-news-app-full-source-code/email-client.git + email_repository: git: - url: https://github.com/headlines-toolkit/ht-email-repository.git - ht_email_sendgrid: + url: https://github.com/flutter-news-app-full-source-code/email-repository.git + email_sendgrid: git: - url: https://github.com/headlines-toolkit/ht-email-sendgrid.git - ht_http_client: + url: https://github.com/flutter-news-app-full-source-code/email-sendgrid.git + http_client: git: - url: https://github.com/headlines-toolkit/ht-http-client.git - ht_shared: + url: https://github.com/flutter-news-app-full-source-code/http-client.git + core: git: - url: https://github.com/headlines-toolkit/ht-shared.git + url: https://github.com/flutter-news-app-full-source-code/core.git json_annotation: ^4.9.0 logging: ^1.3.0 meta: ^1.16.0 @@ -43,4 +43,4 @@ dependencies: dev_dependencies: mocktail: ^1.0.3 test: ^1.25.5 - very_good_analysis: ^7.0.0 + very_good_analysis: ^9.0.0 From 90b7c45a5f25492f97eed61005e2307052aa4f49 Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:16:33 +0100 Subject: [PATCH 03/19] chore: update repository links and rename project - Change repository name to flutter_news_app_api_server_full_source_code - Update GitHub links to point to new repository location - Reflect new project name in README content --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index e4d405f..6957c52 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,18 @@ -# ht_api +# flutter_news_app_api_server_full_source_code ![coverage: percentage](https://img.shields.io/badge/coverage-xx-green) [![style: very good analysis](https://img.shields.io/badge/style-very_good_analysis-B22C89.svg)](https://pub.dev/packages/very_good_analysis) [![License: PolyForm Free Trial](https://img.shields.io/badge/License-PolyForm%20Free%20Trial-blue)](https://polyformproject.org/licenses/free-trial/1.0.0) -πŸš€ Accelerate the development of your news application backend with **ht_api**, the +πŸš€ Accelerate the development of your news application backend with **flutter_news_app_api_server_full_source_code**, the dedicated API service for the Headlines Toolkit. Built on the high-performance -Dart Frog framework, `ht_api` provides the essential server-side infrastructure +Dart Frog framework, `flutter_news_app_api_server_full_source_code` provides the essential server-side infrastructure specifically designed to power robust and feature-rich news applications. -`ht_api` is a core component of the **Headlines Toolkit**, a comprehensive, +`flutter_news_app_api_server_full_source_code` is a core component of the **Headlines Toolkit**, a comprehensive, source-available ecosystem designed for building feature-rich news -applications, which also includes a Flutter [mobile app](https://github.com/headlines-toolkit/ht-main) and a web-based [content -management dashboard](https://github.com/headlines-toolkit/ht-dashboard). +applications, which also includes a Flutter [mobile app](https://github.com/flutter-news-app-full-source-code/ht-main) and a web-based [content +management dashboard](https://github.com/flutter-news-app-full-source-code/ht-dashboard). ## ✨ Key Capabilities @@ -53,7 +53,7 @@ management dashboard](https://github.com/headlines-toolkit/ht-dashboard). ## πŸ”Œ API Endpoints -`ht_api` provides a clear and organized API surface under the `/api/v1/` path. +`flutter_news_app_api_server_full_source_code` provides a clear and organized API surface under the `/api/v1/` path. Key endpoint groups cover authentication, data access, and user settings. For complete API specifications, detailed endpoint documentation, @@ -62,10 +62,10 @@ documentation website [todo:Link to the docs website]. ## πŸ”‘ Access and Licensing -`ht_api` is source-available as part of the Headlines Toolkit ecosystem. +`flutter_news_app_api_server_full_source_code` is source-available as part of the Headlines Toolkit ecosystem. To acquire a commercial license for building unlimited news applications, please visit -the [Headlines Toolkit GitHub organization page](https://github.com/headlines-toolkit) +the [Headlines Toolkit GitHub organization page](https://github.com/flutter-news-app-full-source-code) for more details. ## πŸ’» Setup & Running @@ -88,8 +88,8 @@ for more details. 3. **Clone the repository:** ```bash - git clone https://github.com/headlines-toolkit/ht-api.git - cd ht-api + git clone https://github.com/flutter-news-app-full-source-code/flutter-news-app-api-server-full-source-code.git + cd flutter-news-app-api-server-full-source-code ``` 4. **Get dependencies:** ```bash From 75ab1807cd9462744aec3168814e9acc5988b17c Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:17:28 +0100 Subject: [PATCH 04/19] chore(dependabot): add specific package ignores in dependabot config - Remove wildcard ignore for 'ht_*' - Add individual ignores for core packages - Add ignores for email and data related packages - Add ignore for http_client package --- .github/dependabot.yaml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 4b6cb76..57711c7 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -10,4 +10,11 @@ updates: schedule: interval: "daily" ignore: - - dependency-name: 'ht_*' \ No newline at end of file + - dependency-name: 'core' + - dependency-name: 'data_client' + - dependency-name: 'data_mongodb' + - dependency-name: 'data_repository' + - dependency-name: 'email_client' + - dependency-name: 'email_repository' + - dependency-name: 'email_sendgrid' + - dependency-name: 'http_client' \ No newline at end of file From 45c8ae4385327609407574f65c1e15b07c6c07be Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:17:49 +0100 Subject: [PATCH 05/19] refactor(api): update dependencies and imports - Update package imports to use core package - Rename repository packages to remove 'ht_' prefix - Rename http_client package to remove 'ht_' prefix - Update class imports to use new package structure - Rename logger instances to use new class names --- lib/src/config/app_dependencies.dart | 131 ++++++++++++++------------- 1 file changed, 66 insertions(+), 65 deletions(-) diff --git a/lib/src/config/app_dependencies.dart b/lib/src/config/app_dependencies.dart index baec24c..e14d15f 100644 --- a/lib/src/config/app_dependencies.dart +++ b/lib/src/config/app_dependencies.dart @@ -1,22 +1,24 @@ -import 'package:ht_api/src/config/environment_config.dart'; -import 'package:ht_api/src/rbac/permission_service.dart'; -import 'package:ht_api/src/services/auth_service.dart'; -import 'package:ht_api/src/services/auth_token_service.dart'; -import 'package:ht_api/src/services/dashboard_summary_service.dart'; -import 'package:ht_api/src/services/database_seeding_service.dart'; -import 'package:ht_api/src/services/default_user_preference_limit_service.dart'; -import 'package:ht_api/src/services/jwt_auth_token_service.dart'; -import 'package:ht_api/src/services/mongodb_token_blacklist_service.dart'; -import 'package:ht_api/src/services/mongodb_verification_code_storage_service.dart'; -import 'package:ht_api/src/services/token_blacklist_service.dart'; -import 'package:ht_api/src/services/user_preference_limit_service.dart'; -import 'package:ht_api/src/services/verification_code_storage_service.dart'; -import 'package:ht_data_mongodb/ht_data_mongodb.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_email_repository/ht_email_repository.dart'; -import 'package:ht_email_sendgrid/ht_email_sendgrid.dart'; -import 'package:ht_http_client/ht_http_client.dart'; -import 'package:ht_shared/ht_shared.dart'; +// ignore_for_file: public_member_api_docs + +import 'package:core/core.dart'; +import 'package:data_mongodb/data_mongodb.dart'; +import 'package:data_repository/data_repository.dart'; +import 'package:email_repository/email_repository.dart'; +import 'package:email_sendgrid/email_sendgrid.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/config/environment_config.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/rbac/permission_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/auth_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/auth_token_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/dashboard_summary_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/database_seeding_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/default_user_preference_limit_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/jwt_auth_token_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/mongodb_token_blacklist_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/mongodb_verification_code_storage_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/token_blacklist_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/user_preference_limit_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/verification_code_storage_service.dart'; +import 'package:http_client/http_client.dart'; import 'package:logging/logging.dart'; /// {@template app_dependencies} @@ -44,16 +46,16 @@ class AppDependencies { late final MongoDbConnectionManager _mongoDbConnectionManager; // Repositories - late final HtDataRepository headlineRepository; - late final HtDataRepository topicRepository; - late final HtDataRepository sourceRepository; - late final HtDataRepository countryRepository; - late final HtDataRepository userRepository; - late final HtDataRepository userAppSettingsRepository; - late final HtDataRepository + late final DataRepository headlineRepository; + late final DataRepository topicRepository; + late final DataRepository sourceRepository; + late final DataRepository countryRepository; + late final DataRepository userRepository; + late final DataRepository userAppSettingsRepository; + late final DataRepository userContentPreferencesRepository; - late final HtDataRepository remoteConfigRepository; - late final HtEmailRepository emailRepository; + late final DataRepository remoteConfigRepository; + late final EmailRepository emailRepository; // Services late final TokenBlacklistService tokenBlacklistService; @@ -92,99 +94,98 @@ class AppDependencies { _log.info('Database seeding complete.'); // 3. Initialize Data Clients (MongoDB implementation) - final headlineClient = HtDataMongodb( + final headlineClient = DataMongodb( connectionManager: _mongoDbConnectionManager, modelName: 'headlines', fromJson: Headline.fromJson, toJson: (item) => item.toJson(), searchableFields: ['title'], - logger: Logger('HtDataMongodb'), + logger: Logger('DataMongodb'), ); - final topicClient = HtDataMongodb( + final topicClient = DataMongodb( connectionManager: _mongoDbConnectionManager, modelName: 'topics', fromJson: Topic.fromJson, toJson: (item) => item.toJson(), searchableFields: ['name'], - logger: Logger('HtDataMongodb'), + logger: Logger('DataMongodb'), ); - final sourceClient = HtDataMongodb( + final sourceClient = DataMongodb( connectionManager: _mongoDbConnectionManager, modelName: 'sources', fromJson: Source.fromJson, toJson: (item) => item.toJson(), searchableFields: ['name'], - logger: Logger('HtDataMongodb'), + logger: Logger('DataMongodb'), ); - final countryClient = HtDataMongodb( + final countryClient = DataMongodb( connectionManager: _mongoDbConnectionManager, modelName: 'countries', fromJson: Country.fromJson, toJson: (item) => item.toJson(), - logger: Logger('HtDataMongodb'), + logger: Logger('DataMongodb'), ); - final userClient = HtDataMongodb( + final userClient = DataMongodb( connectionManager: _mongoDbConnectionManager, modelName: 'users', fromJson: User.fromJson, toJson: (item) => item.toJson(), - logger: Logger('HtDataMongodb'), + logger: Logger('DataMongodb'), ); - final userAppSettingsClient = HtDataMongodb( + final userAppSettingsClient = DataMongodb( connectionManager: _mongoDbConnectionManager, modelName: 'user_app_settings', fromJson: UserAppSettings.fromJson, toJson: (item) => item.toJson(), - logger: Logger('HtDataMongodb'), - ); - final userContentPreferencesClient = - HtDataMongodb( - connectionManager: _mongoDbConnectionManager, - modelName: 'user_content_preferences', - fromJson: UserContentPreferences.fromJson, - toJson: (item) => item.toJson(), - logger: Logger('HtDataMongodb'), - ); - final remoteConfigClient = HtDataMongodb( + logger: Logger('DataMongodb'), + ); + final userContentPreferencesClient = DataMongodb( + connectionManager: _mongoDbConnectionManager, + modelName: 'user_content_preferences', + fromJson: UserContentPreferences.fromJson, + toJson: (item) => item.toJson(), + logger: Logger('DataMongodb'), + ); + final remoteConfigClient = DataMongodb( connectionManager: _mongoDbConnectionManager, modelName: 'remote_configs', fromJson: RemoteConfig.fromJson, toJson: (item) => item.toJson(), - logger: Logger('HtDataMongodb'), + logger: Logger('DataMongodb'), ); // 4. Initialize Repositories - headlineRepository = HtDataRepository(dataClient: headlineClient); - topicRepository = HtDataRepository(dataClient: topicClient); - sourceRepository = HtDataRepository(dataClient: sourceClient); - countryRepository = HtDataRepository(dataClient: countryClient); - userRepository = HtDataRepository(dataClient: userClient); - userAppSettingsRepository = HtDataRepository( + headlineRepository = DataRepository(dataClient: headlineClient); + topicRepository = DataRepository(dataClient: topicClient); + sourceRepository = DataRepository(dataClient: sourceClient); + countryRepository = DataRepository(dataClient: countryClient); + userRepository = DataRepository(dataClient: userClient); + userAppSettingsRepository = DataRepository( dataClient: userAppSettingsClient, ); - userContentPreferencesRepository = HtDataRepository( + userContentPreferencesRepository = DataRepository( dataClient: userContentPreferencesClient, ); - remoteConfigRepository = HtDataRepository(dataClient: remoteConfigClient); + remoteConfigRepository = DataRepository(dataClient: remoteConfigClient); // Configure the HTTP client for SendGrid. - // The HtHttpClient's AuthInterceptor will use the tokenProvider to add + // The HttpClient's AuthInterceptor will use the tokenProvider to add // the 'Authorization: Bearer ' header. final sendGridApiBase = EnvironmentConfig.sendGridApiUrl ?? 'https://api.sendgrid.com'; - final sendGridHttpClient = HtHttpClient( + final sendGridHttpClient = HttpClient( baseUrl: '$sendGridApiBase/v3', tokenProvider: () async => EnvironmentConfig.sendGridApiKey, - logger: Logger('HtEmailSendgridClient'), + logger: Logger('EmailSendgridClient'), ); // Initialize the SendGrid email client with the dedicated HTTP client. - final emailClient = HtEmailSendGrid( + final emailClient = EmailSendGrid( httpClient: sendGridHttpClient, - log: Logger('HtEmailSendgrid'), + log: Logger('EmailSendgrid'), ); - emailRepository = HtEmailRepository(emailClient: emailClient); + emailRepository = EmailRepository(emailClient: emailClient); // 5. Initialize Services tokenBlacklistService = MongoDbTokenBlacklistService( From 993b2630ca1676a0238412b5de5c8c6c0e5ce8a8 Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:17:56 +0100 Subject: [PATCH 06/19] refactor:flutter_news_app_api_server_full_source_code: update imports in response helper - Replace `ht_api` and `ht_shared` imports with `core` package - Update `request_id` import path --- lib/src/helpers/response_helper.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/helpers/response_helper.dart b/lib/src/helpers/response_helper.dart index 83a8e51..bc2673b 100644 --- a/lib/src/helpers/response_helper.dart +++ b/lib/src/helpers/response_helper.dart @@ -1,8 +1,8 @@ import 'dart:io'; +import 'package:core/core.dart'; import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/models/request_id.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/models/request_id.dart'; /// A utility class to simplify the creation of standardized API responses. abstract final class ResponseHelper { From 33fc1212ccac83c2e9dd97ea4cd338a4a89a13fc Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:18:51 +0100 Subject: [PATCH 07/19] refactor(api): update imports and exceptions handling - Update import paths to use core package and local paths - Replace HtHttpException with HttpException for broader error handling - Update error mapping and logging to use new exception types - Remove unused imports and adjust package references --- .../authentication_middleware.dart | 8 ++++---- .../middlewares/authorization_middleware.dart | 6 +++--- lib/src/middlewares/error_handler.dart | 20 +++++++++---------- .../ownership_check_middleware.dart | 14 ++++++------- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/src/middlewares/authentication_middleware.dart b/lib/src/middlewares/authentication_middleware.dart index 6656b81..50fd434 100644 --- a/lib/src/middlewares/authentication_middleware.dart +++ b/lib/src/middlewares/authentication_middleware.dart @@ -1,6 +1,6 @@ +import 'package:core/core.dart'; import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/services/auth_token_service.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/auth_token_service.dart'; import 'package:logging/logging.dart'; final _log = Logger('AuthMiddleware'); @@ -58,12 +58,12 @@ Middleware authenticationProvider() { // using this middleware strictly require a valid token. // However, providing null allows routes to handle optional auth. } - } on HtHttpException catch (e) { + } on HttpException catch (e) { // Log token validation errors from the service _log.warning('Token validation failed.', e); // Let the error propagate if needed, or handle specific cases. // For now, we treat validation errors as resulting in no user. - user = null; // Keep user null if HtHttpException occurred + user = null; // Keep user null if HttpException occurred } catch (e, s) { // Catch unexpected errors during validation _log.severe('Unexpected error during token validation.', e, s); diff --git a/lib/src/middlewares/authorization_middleware.dart b/lib/src/middlewares/authorization_middleware.dart index 7681e8b..c89fb24 100644 --- a/lib/src/middlewares/authorization_middleware.dart +++ b/lib/src/middlewares/authorization_middleware.dart @@ -1,7 +1,7 @@ +import 'package:core/core.dart'; import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/rbac/permission_service.dart'; -import 'package:ht_api/src/registry/model_registry.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/rbac/permission_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/registry/model_registry.dart'; import 'package:logging/logging.dart'; final _log = Logger('AuthorizationMiddleware'); diff --git a/lib/src/middlewares/error_handler.dart b/lib/src/middlewares/error_handler.dart index 6e5cae1..6cc5ed7 100644 --- a/lib/src/middlewares/error_handler.dart +++ b/lib/src/middlewares/error_handler.dart @@ -3,9 +3,9 @@ import 'dart:io'; +import 'package:core/core.dart'; import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/config/environment_config.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/config/environment_config.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:logging/logging.dart'; @@ -20,10 +20,10 @@ Middleware errorHandler() { // Attempt to execute the request handler final response = await handler(context); return response; - } on HtHttpException catch (e, stackTrace) { - // Handle specific HtHttpExceptions from the client/repository layers + } on HttpException catch (e, stackTrace) { + // Handle specific HttpExceptions from the client/repository layers final statusCode = _mapExceptionToStatusCode(e); - _log.warning('HtHttpException Caught', e, stackTrace); + _log.warning('HttpException Caught', e, stackTrace); return _jsonErrorResponse( statusCode: statusCode, exception: e, @@ -64,8 +64,8 @@ Middleware errorHandler() { }; } -/// Maps HtHttpException subtypes to appropriate HTTP status codes. -int _mapExceptionToStatusCode(HtHttpException exception) { +/// Maps HttpException subtypes to appropriate HTTP status codes. +int _mapExceptionToStatusCode(HttpException exception) { return switch (exception) { InvalidInputException() => HttpStatus.badRequest, // 400 AuthenticationException() => HttpStatus.unauthorized, // 401 @@ -82,8 +82,8 @@ int _mapExceptionToStatusCode(HtHttpException exception) { }; } -/// Maps HtHttpException subtypes to consistent error code strings. -String _mapExceptionToCodeString(HtHttpException exception) { +/// Maps HttpException subtypes to consistent error code strings. +String _mapExceptionToCodeString(HttpException exception) { return switch (exception) { InvalidInputException() => 'invalidInput', AuthenticationException() => 'authenticationFailed', @@ -107,7 +107,7 @@ String _mapExceptionToCodeString(HtHttpException exception) { /// application to read the error message body. Response _jsonErrorResponse({ required int statusCode, - required HtHttpException exception, + required HttpException exception, required RequestContext context, }) { final errorCode = _mapExceptionToCodeString(exception); diff --git a/lib/src/middlewares/ownership_check_middleware.dart b/lib/src/middlewares/ownership_check_middleware.dart index 58410a4..5e0cfda 100644 --- a/lib/src/middlewares/ownership_check_middleware.dart +++ b/lib/src/middlewares/ownership_check_middleware.dart @@ -1,8 +1,8 @@ +import 'package:core/core.dart'; import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/rbac/permission_service.dart'; -import 'package:ht_api/src/registry/model_registry.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:data_repository/data_repository.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/rbac/permission_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/registry/model_registry.dart'; /// A wrapper class to provide a fetched item into the request context. /// @@ -72,13 +72,13 @@ Middleware ownershipCheckMiddleware() { switch (modelName) { case 'user': - final repo = context.read>(); + final repo = context.read>(); item = await repo.read(id: id, userId: userIdForRepoCall); case 'user_app_settings': - final repo = context.read>(); + final repo = context.read>(); item = await repo.read(id: id, userId: userIdForRepoCall); case 'user_content_preferences': - final repo = context.read>(); + final repo = context.read>(); item = await repo.read(id: id, userId: userIdForRepoCall); default: throw OperationFailedException( From ff00dd9b74145d990eba0b8e9f698b340007f716 Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:19:03 +0100 Subject: [PATCH 08/19] docs(countries_client_provider): update outdated commentary - Replace references to `HtDataRepository` with `DataRepository` - Clarify the role of `modelRegistry` in data endpoint support --- lib/src/providers/countries_client_provider.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/providers/countries_client_provider.dart b/lib/src/providers/countries_client_provider.dart index 2d59911..36747ed 100644 --- a/lib/src/providers/countries_client_provider.dart +++ b/lib/src/providers/countries_client_provider.dart @@ -20,8 +20,8 @@ // to support the generic `/api/v1/data` endpoint. // // Instead of individual provider middleware files here: -// 1. Instances of the core data repositories (`HtDataRepository`, -// `HtDataRepository`, etc.) are created and provided directly +// 1. Instances of the core data repositories (`DataRepository`, +// `DataRepository`, etc.) are created and provided directly // within the top-level `routes/_middleware.dart` file. // 2. A `modelRegistry` (`lib/src/registry/model_registry.dart`) is used in // conjunction with middleware at `routes/api/v1/data/_middleware.dart` to From fef92b982908ab2315506c640aeb491d02af8b0f Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:19:51 +0100 Subject: [PATCH 09/19] refactor(rbac): update imports in permission_service and role_permissions - Replace 'package:ht_api/src/rbac/...' with 'package:flutter_news_app_api_server_full_source_code/src/rbac/...' - Replace 'package:ht_shared/ht_shared.dart' with 'package:core/core.dart' - Update relative imports to use full package name - Standardize on 'core' package for shared dependencies --- lib/src/rbac/permission_service.dart | 4 ++-- lib/src/rbac/role_permissions.dart | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/rbac/permission_service.dart b/lib/src/rbac/permission_service.dart index 4411631..c75ba07 100644 --- a/lib/src/rbac/permission_service.dart +++ b/lib/src/rbac/permission_service.dart @@ -1,5 +1,5 @@ -import 'package:ht_api/src/rbac/role_permissions.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:core/core.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/rbac/role_permissions.dart'; /// {@template permission_service} /// Service responsible for checking if a user has a specific permission. diff --git a/lib/src/rbac/role_permissions.dart b/lib/src/rbac/role_permissions.dart index 5222d47..e3cc0b9 100644 --- a/lib/src/rbac/role_permissions.dart +++ b/lib/src/rbac/role_permissions.dart @@ -1,5 +1,5 @@ -import 'package:ht_api/src/rbac/permissions.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:core/core.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/rbac/permissions.dart'; // --- App Role Permissions --- From 66ce0879adc9d2371a0913c5600ee00ae710b6eb Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:20:03 +0100 Subject: [PATCH 10/19] refactor(registry): update imports and package references - Replace `ht_data_client` with `data_client` package - Replace `flutter_news_app_api_server_full_source_code` with `core` package - Update class names and references accordingly --- lib/src/registry/model_registry.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/registry/model_registry.dart b/lib/src/registry/model_registry.dart index bd47462..54622de 100644 --- a/lib/src/registry/model_registry.dart +++ b/lib/src/registry/model_registry.dart @@ -1,9 +1,9 @@ // ignore_for_file: comment_references +import 'package:core/core.dart'; import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/rbac/permissions.dart'; -import 'package:ht_data_client/ht_data_client.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:data_client/data_client.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/rbac/permissions.dart'; /// Defines the type of permission check required for a specific action. enum RequiredPermissionType { @@ -113,7 +113,7 @@ class ModelConfig { /// (like `fromJson`, `getOwnerId`) and authorization metadata needed by the /// generic route handlers (`index.dart`, `[id].dart`) and authorization middleware. /// -/// While individual repositories (`HtDataRepository`, etc.) are provided +/// While individual repositories (`DataRepository`, etc.) are provided /// directly in the main `routes/_middleware.dart`, this registry provides the /// *metadata* needed to work with those repositories generically based on the /// request's `model` parameter. From d67c9eb74e714258b6c96d0eeef78d30454cb515 Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:21:15 +0100 Subject: [PATCH 11/19] refactor(api): rename package and update dependencies - Rename 'ht_api' to 'flutter_news_app_api_server_full_source_code' - Update import paths for core, data_repository, and email_repository packages - Replace HtHttpException with HttpException - Update class and method references according to new package name --- lib/src/services/auth_service.dart | 46 +++++++++---------- lib/src/services/auth_token_service.dart | 2 +- .../services/dashboard_summary_service.dart | 16 +++---- .../services/database_seeding_service.dart | 8 ++-- ...default_user_preference_limit_service.dart | 18 ++++---- lib/src/services/jwt_auth_token_service.dart | 24 +++++----- .../mongodb_token_blacklist_service.dart | 6 +-- ...odb_verification_code_storage_service.dart | 6 +-- lib/src/services/token_blacklist_service.dart | 2 +- .../user_preference_limit_service.dart | 2 +- .../verification_code_storage_service.dart | 2 +- 11 files changed, 66 insertions(+), 66 deletions(-) diff --git a/lib/src/services/auth_service.dart b/lib/src/services/auth_service.dart index 575cf67..ef8fd8d 100644 --- a/lib/src/services/auth_service.dart +++ b/lib/src/services/auth_service.dart @@ -2,14 +2,14 @@ import 'dart:async'; -import 'package:ht_api/src/config/environment_config.dart'; -import 'package:ht_api/src/rbac/permission_service.dart'; -import 'package:ht_api/src/rbac/permissions.dart'; -import 'package:ht_api/src/services/auth_token_service.dart'; -import 'package:ht_api/src/services/verification_code_storage_service.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_email_repository/ht_email_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; +import 'package:email_repository/email_repository.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/config/environment_config.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/rbac/permission_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/rbac/permissions.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/auth_token_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/verification_code_storage_service.dart'; import 'package:logging/logging.dart'; import 'package:mongo_dart/mongo_dart.dart'; @@ -22,12 +22,12 @@ import 'package:mongo_dart/mongo_dart.dart'; class AuthService { /// {@macro auth_service} const AuthService({ - required HtDataRepository userRepository, + required DataRepository userRepository, required AuthTokenService authTokenService, required VerificationCodeStorageService verificationCodeStorageService, - required HtEmailRepository emailRepository, - required HtDataRepository userAppSettingsRepository, - required HtDataRepository + required EmailRepository emailRepository, + required DataRepository userAppSettingsRepository, + required DataRepository userContentPreferencesRepository, required PermissionService permissionService, required Logger log, @@ -40,12 +40,12 @@ class AuthService { _userContentPreferencesRepository = userContentPreferencesRepository, _log = log; - final HtDataRepository _userRepository; + final DataRepository _userRepository; final AuthTokenService _authTokenService; final VerificationCodeStorageService _verificationCodeStorageService; - final HtEmailRepository _emailRepository; - final HtDataRepository _userAppSettingsRepository; - final HtDataRepository + final EmailRepository _emailRepository; + final DataRepository _userAppSettingsRepository; + final DataRepository _userContentPreferencesRepository; final PermissionService _permissionService; final Logger _log; @@ -112,7 +112,7 @@ class AuthService { otpCode: code, ); _log.info('Initiated email sign-in for $email, code sent.'); - } on HtHttpException { + } on HttpException { // Propagate known exceptions from dependencies or from this method's logic. // This ensures that specific errors like ForbiddenException are not // masked as a generic server error. @@ -301,7 +301,7 @@ class AuthService { // Ensure default documents are created for the new user. await _ensureUserDataExists(user); } - } on HtHttpException { + } on HttpException { // Propagate known exceptions from dependencies or from this method's logic. // This ensures that specific errors like ForbiddenException are not // masked as a generic server error. @@ -358,7 +358,7 @@ class AuthService { // Ensure default documents are created for the new anonymous user. await _ensureUserDataExists(user); - } on HtHttpException catch (e) { + } on HttpException catch (e) { _log.severe('Error creating anonymous user: $e'); throw const OperationFailedException('Failed to create anonymous user.'); } catch (e) { @@ -413,7 +413,7 @@ class AuthService { // Invalidate the token using the AuthTokenService await _authTokenService.invalidateToken(token); _log.info('Token invalidation logic executed for user $userId.'); - } on HtHttpException catch (_) { + } on HttpException catch (_) { // Propagate known exceptions from the token service rethrow; } catch (e) { @@ -477,7 +477,7 @@ class AuthService { } on NotFoundException { // Propagate NotFoundException if user doesn't exist rethrow; - } on HtHttpException catch (_) { + } on HttpException catch (_) { // Propagate other known exceptions from dependencies rethrow; } catch (e) { @@ -490,7 +490,7 @@ class AuthService { /// Finds a user by their email address. /// /// Returns the [User] if found, otherwise `null`. - /// Re-throws any [HtHttpException] from the repository. + /// Re-throws any [HttpException] from the repository. Future _findUserByEmail(String email) async { try { final response = await _userRepository.readAll(filter: {'email': email}); @@ -498,7 +498,7 @@ class AuthService { return response.items.first; } return null; - } on HtHttpException { + } on HttpException { rethrow; } } diff --git a/lib/src/services/auth_token_service.dart b/lib/src/services/auth_token_service.dart index f28afa2..2b5ca04 100644 --- a/lib/src/services/auth_token_service.dart +++ b/lib/src/services/auth_token_service.dart @@ -1,4 +1,4 @@ -import 'package:ht_shared/ht_shared.dart'; +import 'package:core/core.dart'; /// {@template auth_token_service} /// Service responsible for generating and validating authentication tokens. diff --git a/lib/src/services/dashboard_summary_service.dart b/lib/src/services/dashboard_summary_service.dart index 478a281..2d9b053 100644 --- a/lib/src/services/dashboard_summary_service.dart +++ b/lib/src/services/dashboard_summary_service.dart @@ -1,5 +1,5 @@ -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; /// {@template dashboard_summary_service} /// A service responsible for calculating the dashboard summary data on demand. @@ -10,16 +10,16 @@ import 'package:ht_shared/ht_shared.dart'; class DashboardSummaryService { /// {@macro dashboard_summary_service} const DashboardSummaryService({ - required HtDataRepository headlineRepository, - required HtDataRepository topicRepository, - required HtDataRepository sourceRepository, + required DataRepository headlineRepository, + required DataRepository topicRepository, + required DataRepository sourceRepository, }) : _headlineRepository = headlineRepository, _topicRepository = topicRepository, _sourceRepository = sourceRepository; - final HtDataRepository _headlineRepository; - final HtDataRepository _topicRepository; - final HtDataRepository _sourceRepository; + final DataRepository _headlineRepository; + final DataRepository _topicRepository; + final DataRepository _sourceRepository; /// Calculates and returns the current dashboard summary. /// diff --git a/lib/src/services/database_seeding_service.dart b/lib/src/services/database_seeding_service.dart index fb58c84..29b102a 100644 --- a/lib/src/services/database_seeding_service.dart +++ b/lib/src/services/database_seeding_service.dart @@ -1,13 +1,13 @@ -import 'package:ht_api/src/services/mongodb_token_blacklist_service.dart'; -import 'package:ht_api/src/services/mongodb_verification_code_storage_service.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:core/core.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/mongodb_token_blacklist_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/mongodb_verification_code_storage_service.dart'; import 'package:logging/logging.dart'; import 'package:mongo_dart/mongo_dart.dart'; /// {@template database_seeding_service} /// A service responsible for seeding the MongoDB database with initial data. /// -/// This service reads data from predefined fixture lists in `ht_shared` and +/// This service reads data from predefined fixture lists in `core` and /// uses `upsert` operations to ensure that the seeding process is idempotent. /// It can be run multiple times without creating duplicate documents. /// {@endtemplate} diff --git a/lib/src/services/default_user_preference_limit_service.dart b/lib/src/services/default_user_preference_limit_service.dart index e464f99..b57d0c2 100644 --- a/lib/src/services/default_user_preference_limit_service.dart +++ b/lib/src/services/default_user_preference_limit_service.dart @@ -1,8 +1,8 @@ -import 'package:ht_api/src/rbac/permission_service.dart'; -import 'package:ht_api/src/rbac/permissions.dart'; -import 'package:ht_api/src/services/user_preference_limit_service.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:core/core.dart'; +import 'package:data_repository/data_repository.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/rbac/permission_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/rbac/permissions.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/user_preference_limit_service.dart'; import 'package:logging/logging.dart'; /// {@template default_user_preference_limit_service} @@ -12,14 +12,14 @@ import 'package:logging/logging.dart'; class DefaultUserPreferenceLimitService implements UserPreferenceLimitService { /// {@macro default_user_preference_limit_service} const DefaultUserPreferenceLimitService({ - required HtDataRepository remoteConfigRepository, + required DataRepository remoteConfigRepository, required PermissionService permissionService, required Logger log, }) : _remoteConfigRepository = remoteConfigRepository, _permissionService = permissionService, _log = log; - final HtDataRepository _remoteConfigRepository; + final DataRepository _remoteConfigRepository; final PermissionService _permissionService; final Logger _log; @@ -76,7 +76,7 @@ class DefaultUserPreferenceLimitService implements UserPreferenceLimitService { 'for your account type ($accountType).', ); } - } on HtHttpException { + } on HttpException { // Propagate known exceptions from repositories rethrow; } catch (e) { @@ -155,7 +155,7 @@ class DefaultUserPreferenceLimitService implements UserPreferenceLimitService { 'for your account type ($accountType).', ); } - } on HtHttpException { + } on HttpException { // Propagate known exceptions from repositories rethrow; } catch (e) { diff --git a/lib/src/services/jwt_auth_token_service.dart b/lib/src/services/jwt_auth_token_service.dart index 9fd2f34..1322cd0 100644 --- a/lib/src/services/jwt_auth_token_service.dart +++ b/lib/src/services/jwt_auth_token_service.dart @@ -1,9 +1,9 @@ +import 'package:core/core.dart'; import 'package:dart_jsonwebtoken/dart_jsonwebtoken.dart'; -import 'package:ht_api/src/config/environment_config.dart'; -import 'package:ht_api/src/services/auth_token_service.dart'; -import 'package:ht_api/src/services/token_blacklist_service.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:data_repository/data_repository.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/config/environment_config.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/auth_token_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/token_blacklist_service.dart'; import 'package:logging/logging.dart'; import 'package:mongo_dart/mongo_dart.dart'; @@ -21,14 +21,14 @@ class JwtAuthTokenService implements AuthTokenService { /// subject claim. /// - [blacklistService]: To manage the blacklist of invalidated tokens. const JwtAuthTokenService({ - required HtDataRepository userRepository, + required DataRepository userRepository, required TokenBlacklistService blacklistService, required Logger log, }) : _userRepository = userRepository, _blacklistService = blacklistService, _log = log; - final HtDataRepository _userRepository; + final DataRepository _userRepository; final TokenBlacklistService _blacklistService; final Logger _log; @@ -179,11 +179,11 @@ class JwtAuthTokenService implements AuthTokenService { ); // Treat other JWT exceptions as invalid tokens throw UnauthorizedException('Invalid token: ${e.message}'); - } on HtHttpException catch (e, s) { + } on HttpException catch (e, s) { // Handle errors from the user repository (e.g., user not found) - // or blacklist check (if it threw HtHttpException) + // or blacklist check (if it threw HttpException) _log.warning( - '[validateToken] CATCH HtHttpException: Error during validation. ' + '[validateToken] CATCH HttpException: Error during validation. ' 'Type: ${e.runtimeType}, Message: $e\n$s', ); // Re-throw repository/blacklist exceptions directly @@ -253,10 +253,10 @@ class JwtAuthTokenService implements AuthTokenService { ); // Treat as invalid input for invalidation purposes throw InvalidInputException('Invalid token format: ${e.message}'); - } on HtHttpException catch (e, s) { + } on HttpException catch (e, s) { // Catch errors from the blacklist service itself _log.warning( - '[invalidateToken] CATCH HtHttpException: Error during blacklisting. ' + '[invalidateToken] CATCH HttpException: Error during blacklisting. ' 'Type: ${e.runtimeType}, Message: $e\n$s', ); // Re-throw blacklist service exceptions diff --git a/lib/src/services/mongodb_token_blacklist_service.dart b/lib/src/services/mongodb_token_blacklist_service.dart index a975636..39325bc 100644 --- a/lib/src/services/mongodb_token_blacklist_service.dart +++ b/lib/src/services/mongodb_token_blacklist_service.dart @@ -1,8 +1,8 @@ import 'dart:async'; -import 'package:ht_api/src/services/token_blacklist_service.dart'; -import 'package:ht_data_mongodb/ht_data_mongodb.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:core/core.dart'; +import 'package:data_mongodb/data_mongodb.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/token_blacklist_service.dart'; import 'package:logging/logging.dart'; import 'package:mongo_dart/mongo_dart.dart'; diff --git a/lib/src/services/mongodb_verification_code_storage_service.dart b/lib/src/services/mongodb_verification_code_storage_service.dart index 59d1d9f..e7bab9b 100644 --- a/lib/src/services/mongodb_verification_code_storage_service.dart +++ b/lib/src/services/mongodb_verification_code_storage_service.dart @@ -1,9 +1,9 @@ import 'dart:async'; import 'dart:math'; -import 'package:ht_api/src/services/verification_code_storage_service.dart'; -import 'package:ht_data_mongodb/ht_data_mongodb.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:core/core.dart'; +import 'package:data_mongodb/data_mongodb.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/verification_code_storage_service.dart'; import 'package:logging/logging.dart'; import 'package:mongo_dart/mongo_dart.dart'; diff --git a/lib/src/services/token_blacklist_service.dart b/lib/src/services/token_blacklist_service.dart index 95bcb7f..fcb087e 100644 --- a/lib/src/services/token_blacklist_service.dart +++ b/lib/src/services/token_blacklist_service.dart @@ -1,6 +1,6 @@ import 'dart:async'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:core/core.dart'; import 'package:logging/logging.dart'; import 'package:meta/meta.dart'; diff --git a/lib/src/services/user_preference_limit_service.dart b/lib/src/services/user_preference_limit_service.dart index 22f7265..566fc8a 100644 --- a/lib/src/services/user_preference_limit_service.dart +++ b/lib/src/services/user_preference_limit_service.dart @@ -1,4 +1,4 @@ -import 'package:ht_shared/ht_shared.dart'; +import 'package:core/core.dart'; /// {@template user_preference_limit_service} /// Service responsible for enforcing user preference limits based on user role. diff --git a/lib/src/services/verification_code_storage_service.dart b/lib/src/services/verification_code_storage_service.dart index dc64635..92278aa 100644 --- a/lib/src/services/verification_code_storage_service.dart +++ b/lib/src/services/verification_code_storage_service.dart @@ -2,7 +2,7 @@ import 'dart:async'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:core/core.dart'; /// {@template verification_code_storage_service} /// Defines the interface for a service that manages verification codes From ddfd42eafa6929a2f9112a54f72d3c07cd0070fd Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:21:34 +0100 Subject: [PATCH 12/19] refactor(dependencies): update import paths and package names - Replace `ht_data_repository` with `data_repository` - Replace `ht_email_repository` with `email_repository` - Update package paths for `flutter_news_app_api_server_full_source_code` - Replace `HtDataRepository` with `DataRepository` - Replace `HtEmailRepository` with `EmailRepository` --- routes/_middleware.dart | 50 +++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/routes/_middleware.dart b/routes/_middleware.dart index 3984ed0..419731c 100644 --- a/routes/_middleware.dart +++ b/routes/_middleware.dart @@ -1,18 +1,18 @@ +import 'package:core/core.dart'; import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/config/app_dependencies.dart'; -import 'package:ht_api/src/middlewares/error_handler.dart'; -import 'package:ht_api/src/models/request_id.dart'; -import 'package:ht_api/src/rbac/permission_service.dart'; -import 'package:ht_api/src/registry/model_registry.dart'; -import 'package:ht_api/src/services/auth_service.dart'; -import 'package:ht_api/src/services/auth_token_service.dart'; -import 'package:ht_api/src/services/dashboard_summary_service.dart'; -import 'package:ht_api/src/services/token_blacklist_service.dart'; -import 'package:ht_api/src/services/user_preference_limit_service.dart'; -import 'package:ht_api/src/services/verification_code_storage_service.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_email_repository/ht_email_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:data_repository/data_repository.dart'; +import 'package:email_repository/email_repository.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/config/app_dependencies.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/middlewares/error_handler.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/models/request_id.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/rbac/permission_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/registry/model_registry.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/auth_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/auth_token_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/dashboard_summary_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/token_blacklist_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/user_preference_limit_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/verification_code_storage_service.dart'; import 'package:logging/logging.dart'; import 'package:mongo_dart/mongo_dart.dart'; @@ -76,42 +76,38 @@ Handler middleware(Handler handler) { return handler .use(provider((_) => modelRegistry)) .use( - provider>( + provider>( (_) => deps.headlineRepository, ), ) // + .use(provider>((_) => deps.topicRepository)) .use( - provider>((_) => deps.topicRepository), - ) - .use( - provider>( - (_) => deps.sourceRepository, - ), + provider>((_) => deps.sourceRepository), ) // .use( - provider>( + provider>( (_) => deps.countryRepository, ), ) // .use( - provider>((_) => deps.userRepository), + provider>((_) => deps.userRepository), ) // .use( - provider>( + provider>( (_) => deps.userAppSettingsRepository, ), ) .use( - provider>( + provider>( (_) => deps.userContentPreferencesRepository, ), ) .use( - provider>( + provider>( (_) => deps.remoteConfigRepository, ), ) - .use(provider((_) => deps.emailRepository)) + .use(provider((_) => deps.emailRepository)) .use( provider( (_) => deps.tokenBlacklistService, From 4aca107dff6b20e391b2868939f68fc3f3e1a356 Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:21:45 +0100 Subject: [PATCH 13/19] build: update import path for authentication middleware - Change import path from 'ht_api' to 'flutter_news_app_api_server_full_source_code' - This update ensures consistency in import paths across the project --- routes/api/v1/_middleware.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/api/v1/_middleware.dart b/routes/api/v1/_middleware.dart index ddef0fe..958d05c 100644 --- a/routes/api/v1/_middleware.dart +++ b/routes/api/v1/_middleware.dart @@ -1,7 +1,7 @@ import 'dart:io' show Platform; // To read environment variables import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/middlewares/authentication_middleware.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/middlewares/authentication_middleware.dart'; import 'package:logging/logging.dart'; import 'package:shelf_cors_headers/shelf_cors_headers.dart' as shelf_cors; From 2432d4aec63c78567a4d377b69abaa1c72af8ff8 Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:22:22 +0100 Subject: [PATCH 14/19] refactor(auth): update imports and exceptions in auth routes - Update import paths to use core package instead of ht_shared - Replace HtHttpException with HttpException - Consolidate import statements and remove duplicates --- routes/api/v1/auth/anonymous.dart | 8 ++++---- routes/api/v1/auth/delete-account.dart | 6 +++--- routes/api/v1/auth/me.dart | 4 ++-- routes/api/v1/auth/request-code.dart | 6 +++--- routes/api/v1/auth/sign-out.dart | 6 +++--- routes/api/v1/auth/verify-code.dart | 10 +++++----- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/routes/api/v1/auth/anonymous.dart b/routes/api/v1/auth/anonymous.dart index 8007d7a..1666475 100644 --- a/routes/api/v1/auth/anonymous.dart +++ b/routes/api/v1/auth/anonymous.dart @@ -1,9 +1,9 @@ import 'dart:io'; +import 'package:core/core.dart'; import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/helpers/response_helper.dart'; -import 'package:ht_api/src/services/auth_service.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/helpers/response_helper.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/auth_service.dart'; import 'package:logging/logging.dart'; // Create a logger for this file. @@ -38,7 +38,7 @@ Future onRequest(RequestContext context) async { data: authPayload, toJsonT: (data) => data.toJson(), ); - } on HtHttpException catch (_) { + } on HttpException catch (_) { // Let the central errorHandler middleware handle known exceptions rethrow; } catch (e, s) { diff --git a/routes/api/v1/auth/delete-account.dart b/routes/api/v1/auth/delete-account.dart index 310e885..fcea4d5 100644 --- a/routes/api/v1/auth/delete-account.dart +++ b/routes/api/v1/auth/delete-account.dart @@ -1,8 +1,8 @@ import 'dart:io'; +import 'package:core/core.dart'; // For User and exceptions import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/services/auth_service.dart'; -import 'package:ht_shared/ht_shared.dart'; // For User and exceptions +import 'package:flutter_news_app_api_server_full_source_code/src/services/auth_service.dart'; import 'package:logging/logging.dart'; // Create a logger for this file. @@ -39,7 +39,7 @@ Future onRequest(RequestContext context) async { // Return 204 No Content indicating successful deletion return Response(statusCode: HttpStatus.noContent); - } on HtHttpException catch (_) { + } on HttpException catch (_) { // Let the central errorHandler middleware handle known exceptions rethrow; } catch (e, s) { diff --git a/routes/api/v1/auth/me.dart b/routes/api/v1/auth/me.dart index dcdb000..8c71647 100644 --- a/routes/api/v1/auth/me.dart +++ b/routes/api/v1/auth/me.dart @@ -1,8 +1,8 @@ import 'dart:io'; +import 'package:core/core.dart'; // For User, SuccessApiResponse etc. import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/helpers/response_helper.dart'; -import 'package:ht_shared/ht_shared.dart'; // For User, SuccessApiResponse etc. +import 'package:flutter_news_app_api_server_full_source_code/src/helpers/response_helper.dart'; /// Handles GET requests to `/api/v1/auth/me`. /// diff --git a/routes/api/v1/auth/request-code.dart b/routes/api/v1/auth/request-code.dart index f809454..c7b45cc 100644 --- a/routes/api/v1/auth/request-code.dart +++ b/routes/api/v1/auth/request-code.dart @@ -1,8 +1,8 @@ import 'dart:io'; +import 'package:core/core.dart'; // For exceptions import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/services/auth_service.dart'; -import 'package:ht_shared/ht_shared.dart'; // For exceptions +import 'package:flutter_news_app_api_server_full_source_code/src/services/auth_service.dart'; import 'package:logging/logging.dart'; // Create a logger for this file. @@ -80,7 +80,7 @@ Future onRequest(RequestContext context) async { // but the processing (email sending) hasn't necessarily completed. // 200 OK is also acceptable if you consider the API call itself complete. return Response(statusCode: HttpStatus.accepted); - } on HtHttpException catch (_) { + } on HttpException catch (_) { // Let the central errorHandler middleware handle known exceptions rethrow; } catch (e, s) { diff --git a/routes/api/v1/auth/sign-out.dart b/routes/api/v1/auth/sign-out.dart index 47eb73e..83220ce 100644 --- a/routes/api/v1/auth/sign-out.dart +++ b/routes/api/v1/auth/sign-out.dart @@ -1,8 +1,8 @@ import 'dart:io'; +import 'package:core/core.dart'; // For User and exceptions import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/services/auth_service.dart'; -import 'package:ht_shared/ht_shared.dart'; // For User and exceptions +import 'package:flutter_news_app_api_server_full_source_code/src/services/auth_service.dart'; import 'package:logging/logging.dart'; // Create a logger for this file. @@ -56,7 +56,7 @@ Future onRequest(RequestContext context) async { // Return 204 No Content indicating successful sign-out action return Response(statusCode: HttpStatus.noContent); - } on HtHttpException catch (_) { + } on HttpException catch (_) { // Let the central errorHandler middleware handle known exceptions rethrow; } catch (e, s) { diff --git a/routes/api/v1/auth/verify-code.dart b/routes/api/v1/auth/verify-code.dart index c4bf7bc..a859d70 100644 --- a/routes/api/v1/auth/verify-code.dart +++ b/routes/api/v1/auth/verify-code.dart @@ -1,10 +1,10 @@ import 'dart:io'; -import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/helpers/response_helper.dart'; -import 'package:ht_api/src/services/auth_service.dart'; // Import exceptions, User, SuccessApiResponse, AND AuthSuccessResponse -import 'package:ht_shared/ht_shared.dart'; +import 'package:core/core.dart'; +import 'package:dart_frog/dart_frog.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/helpers/response_helper.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/auth_service.dart'; import 'package:logging/logging.dart'; // Create a logger for this file. @@ -105,7 +105,7 @@ Future onRequest(RequestContext context) async { data: authPayload, toJsonT: (data) => data.toJson(), ); - } on HtHttpException catch (_) { + } on HttpException catch (_) { // Let the central errorHandler middleware handle known exceptions // (e.g., InvalidInputException if code is wrong/expired) rethrow; From d8bebdfa84f1cf800741401d313c01b669e1605e Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:23:01 +0100 Subject: [PATCH 15/19] refactor(api): update package imports and repository references - Replace `ht_data_repository` with `data_repository` package - Update import paths for `flutter_news_app_api_server_full_source_code` package - Rename `HtDataRepository` to `DataRepository` - Replace `HtHttpException` with `HttpException` --- routes/api/v1/data/[id]/_middleware.dart | 2 +- routes/api/v1/data/[id]/index.dart | 80 ++++++++++++------------ routes/api/v1/data/_middleware.dart | 8 +-- routes/api/v1/data/index.dart | 30 ++++----- 4 files changed, 60 insertions(+), 60 deletions(-) diff --git a/routes/api/v1/data/[id]/_middleware.dart b/routes/api/v1/data/[id]/_middleware.dart index 216a2f1..9f5b218 100644 --- a/routes/api/v1/data/[id]/_middleware.dart +++ b/routes/api/v1/data/[id]/_middleware.dart @@ -1,5 +1,5 @@ import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/middlewares/ownership_check_middleware.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/middlewares/ownership_check_middleware.dart'; /// Middleware specific to the item-level `/api/v1/data/[id]` route path. /// diff --git a/routes/api/v1/data/[id]/index.dart b/routes/api/v1/data/[id]/index.dart index 0ce197f..f3db758 100644 --- a/routes/api/v1/data/[id]/index.dart +++ b/routes/api/v1/data/[id]/index.dart @@ -1,13 +1,13 @@ import 'dart:io'; +import 'package:core/core.dart'; import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/helpers/response_helper.dart'; -import 'package:ht_api/src/rbac/permission_service.dart'; -import 'package:ht_api/src/registry/model_registry.dart'; -import 'package:ht_api/src/services/dashboard_summary_service.dart'; -import 'package:ht_api/src/services/user_preference_limit_service.dart'; // Import UserPreferenceLimitService -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:data_repository/data_repository.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/helpers/response_helper.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/rbac/permission_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/registry/model_registry.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/dashboard_summary_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/services/user_preference_limit_service.dart'; // Import UserPreferenceLimitService import 'package:logging/logging.dart'; // Create a logger for this file. @@ -96,28 +96,28 @@ Future _handleGet( // main onRequest try/catch (which is now removed, so they go to errorHandler). switch (modelName) { case 'headline': - final repo = context.read>(); + final repo = context.read>(); item = await repo.read(id: id, userId: userIdForRepoCall); case 'topic': - final repo = context.read>(); + final repo = context.read>(); item = await repo.read(id: id, userId: userIdForRepoCall); case 'source': - final repo = context.read>(); + final repo = context.read>(); item = await repo.read(id: id, userId: userIdForRepoCall); case 'country': - final repo = context.read>(); + final repo = context.read>(); item = await repo.read(id: id, userId: userIdForRepoCall); case 'user': // Handle User model specifically if needed, or rely on generic - final repo = context.read>(); + final repo = context.read>(); item = await repo.read(id: id, userId: userIdForRepoCall); case 'user_app_settings': // New case for UserAppSettings - final repo = context.read>(); + final repo = context.read>(); item = await repo.read(id: id, userId: userIdForRepoCall); case 'user_content_preferences': // New case for UserContentPreferences - final repo = context.read>(); + final repo = context.read>(); item = await repo.read(id: id, userId: userIdForRepoCall); case 'remote_config': // New case for RemoteConfig (read by admin) - final repo = context.read>(); + final repo = context.read>(); item = await repo.read( id: id, userId: userIdForRepoCall, @@ -240,7 +240,7 @@ Future _handlePut( authenticatedUser, itemToUpdate, ); - } on HtHttpException { + } on HttpException { // Propagate known exceptions from the limit service (e.g., ForbiddenException) rethrow; } catch (e, s) { @@ -275,7 +275,7 @@ Future _handlePut( switch (modelName) { case 'headline': { - final repo = context.read>(); + final repo = context.read>(); updatedItem = await repo.update( id: id, item: itemToUpdate as Headline, @@ -284,7 +284,7 @@ Future _handlePut( } case 'topic': { - final repo = context.read>(); + final repo = context.read>(); updatedItem = await repo.update( id: id, item: itemToUpdate as Topic, @@ -293,7 +293,7 @@ Future _handlePut( } case 'source': { - final repo = context.read>(); + final repo = context.read>(); updatedItem = await repo.update( id: id, item: itemToUpdate as Source, @@ -302,7 +302,7 @@ Future _handlePut( } case 'country': { - final repo = context.read>(); + final repo = context.read>(); updatedItem = await repo.update( id: id, item: itemToUpdate as Country, @@ -311,7 +311,7 @@ Future _handlePut( } case 'user': { - final repo = context.read>(); + final repo = context.read>(); updatedItem = await repo.update( id: id, item: itemToUpdate as User, @@ -320,7 +320,7 @@ Future _handlePut( } case 'user_app_settings': // New case for UserAppSettings { - final repo = context.read>(); + final repo = context.read>(); updatedItem = await repo.update( id: id, item: itemToUpdate as UserAppSettings, @@ -329,7 +329,7 @@ Future _handlePut( } case 'user_content_preferences': // New case for UserContentPreferences { - final repo = context.read>(); + final repo = context.read>(); updatedItem = await repo.update( id: id, item: itemToUpdate as UserContentPreferences, @@ -338,7 +338,7 @@ Future _handlePut( } case 'remote_config': // New case for RemoteConfig (update by admin) { - final repo = context.read>(); + final repo = context.read>(); updatedItem = await repo.update( id: id, item: itemToUpdate as RemoteConfig, @@ -443,28 +443,28 @@ Future _handleDelete( // Repository exceptions (like NotFoundException) will propagate up to the errorHandler. switch (modelName) { case 'headline': - final repo = context.read>(); + final repo = context.read>(); itemToDelete = await repo.read(id: id, userId: userIdForRepoCall); case 'topic': - final repo = context.read>(); + final repo = context.read>(); itemToDelete = await repo.read(id: id, userId: userIdForRepoCall); case 'source': - final repo = context.read>(); + final repo = context.read>(); itemToDelete = await repo.read(id: id, userId: userIdForRepoCall); case 'country': - final repo = context.read>(); + final repo = context.read>(); itemToDelete = await repo.read(id: id, userId: userIdForRepoCall); case 'user': - final repo = context.read>(); + final repo = context.read>(); itemToDelete = await repo.read(id: id, userId: userIdForRepoCall); case 'user_app_settings': // New case for UserAppSettings - final repo = context.read>(); + final repo = context.read>(); itemToDelete = await repo.read(id: id, userId: userIdForRepoCall); case 'user_content_preferences': // New case for UserContentPreferences - final repo = context.read>(); + final repo = context.read>(); itemToDelete = await repo.read(id: id, userId: userIdForRepoCall); case 'remote_config': // New case for RemoteConfig (delete by admin) - final repo = context.read>(); + final repo = context.read>(); itemToDelete = await repo.read( id: id, userId: userIdForRepoCall, @@ -498,42 +498,42 @@ Future _handleDelete( // upwards to be handled by the standard error handling mechanism. switch (modelName) { case 'headline': - await context.read>().delete( + await context.read>().delete( id: id, userId: userIdForRepoCall, ); case 'topic': - await context.read>().delete( + await context.read>().delete( id: id, userId: userIdForRepoCall, ); case 'source': - await context.read>().delete( + await context.read>().delete( id: id, userId: userIdForRepoCall, ); case 'country': - await context.read>().delete( + await context.read>().delete( id: id, userId: userIdForRepoCall, ); case 'user': - await context.read>().delete( + await context.read>().delete( id: id, userId: userIdForRepoCall, ); case 'user_app_settings': // New case for UserAppSettings - await context.read>().delete( + await context.read>().delete( id: id, userId: userIdForRepoCall, ); case 'user_content_preferences': // New case for UserContentPreferences - await context.read>().delete( + await context.read>().delete( id: id, userId: userIdForRepoCall, ); case 'remote_config': // New case for RemoteConfig (delete by admin) - await context.read>().delete( + await context.read>().delete( id: id, userId: userIdForRepoCall, ); // userId should be null for AppConfig diff --git a/routes/api/v1/data/_middleware.dart b/routes/api/v1/data/_middleware.dart index 8697500..2eaa41d 100644 --- a/routes/api/v1/data/_middleware.dart +++ b/routes/api/v1/data/_middleware.dart @@ -1,8 +1,8 @@ +import 'package:core/core.dart'; import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/middlewares/authentication_middleware.dart'; -import 'package:ht_api/src/middlewares/authorization_middleware.dart'; // Import authorization middleware -import 'package:ht_api/src/registry/model_registry.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/middlewares/authentication_middleware.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/middlewares/authorization_middleware.dart'; // Import authorization middleware +import 'package:flutter_news_app_api_server_full_source_code/src/registry/model_registry.dart'; /// Middleware specific to the generic `/api/v1/data` route path. /// diff --git a/routes/api/v1/data/index.dart b/routes/api/v1/data/index.dart index 6a5fd42..664c2d8 100644 --- a/routes/api/v1/data/index.dart +++ b/routes/api/v1/data/index.dart @@ -1,12 +1,12 @@ import 'dart:convert'; import 'dart:io'; +import 'package:core/core.dart'; import 'package:dart_frog/dart_frog.dart'; -import 'package:ht_api/src/helpers/response_helper.dart'; -import 'package:ht_api/src/rbac/permission_service.dart'; -import 'package:ht_api/src/registry/model_registry.dart'; -import 'package:ht_data_repository/ht_data_repository.dart'; -import 'package:ht_shared/ht_shared.dart'; +import 'package:data_repository/data_repository.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/helpers/response_helper.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/rbac/permission_service.dart'; +import 'package:flutter_news_app_api_server_full_source_code/src/registry/model_registry.dart'; import 'package:mongo_dart/mongo_dart.dart'; /// Handles requests for the /api/v1/data collection endpoint. @@ -86,7 +86,7 @@ Future _handleGet(RequestContext context) async { // The query logic is handled by the repository/client. switch (modelName) { case 'headline': - final repo = context.read>(); + final repo = context.read>(); responseData = await repo.readAll( userId: userIdForRepoCall, filter: filter, @@ -94,7 +94,7 @@ Future _handleGet(RequestContext context) async { pagination: pagination, ); case 'topic': - final repo = context.read>(); + final repo = context.read>(); responseData = await repo.readAll( userId: userIdForRepoCall, filter: filter, @@ -102,7 +102,7 @@ Future _handleGet(RequestContext context) async { pagination: pagination, ); case 'source': - final repo = context.read>(); + final repo = context.read>(); responseData = await repo.readAll( userId: userIdForRepoCall, filter: filter, @@ -110,7 +110,7 @@ Future _handleGet(RequestContext context) async { pagination: pagination, ); case 'country': - final repo = context.read>(); + final repo = context.read>(); responseData = await repo.readAll( userId: userIdForRepoCall, filter: filter, @@ -118,7 +118,7 @@ Future _handleGet(RequestContext context) async { pagination: pagination, ); case 'user': - final repo = context.read>(); + final repo = context.read>(); responseData = await repo.readAll( userId: userIdForRepoCall, filter: filter, @@ -178,31 +178,31 @@ Future _handlePost(RequestContext context) async { dynamic createdItem; switch (modelName) { case 'headline': - final repo = context.read>(); + final repo = context.read>(); createdItem = await repo.create( item: itemToCreate as Headline, userId: userIdForRepoCall, ); case 'topic': - final repo = context.read>(); + final repo = context.read>(); createdItem = await repo.create( item: itemToCreate as Topic, userId: userIdForRepoCall, ); case 'source': - final repo = context.read>(); + final repo = context.read>(); createdItem = await repo.create( item: itemToCreate as Source, userId: userIdForRepoCall, ); case 'country': - final repo = context.read>(); + final repo = context.read>(); createdItem = await repo.create( item: itemToCreate as Country, userId: userIdForRepoCall, ); case 'remote_config': - final repo = context.read>(); + final repo = context.read>(); createdItem = await repo.create( item: itemToCreate as RemoteConfig, userId: userIdForRepoCall, From 033fb778dc0a6df225f49f85d31ba9e964d38ce8 Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:24:46 +0100 Subject: [PATCH 16/19] build(dependencies): move core package to dependencies and adjust dotenv - Move core package from dev_dependencies to dependencies - Adjust dotenv package location in dependencies - Reorganize dependencies for better structure and clarity --- pubspec.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pubspec.yaml b/pubspec.yaml index 456e53a..db84c17 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,9 +7,11 @@ environment: sdk: ^3.8.0 dependencies: + core: + git: + url: https://github.com/flutter-news-app-full-source-code/core.git dart_frog: ^1.1.0 dart_jsonwebtoken: ^3.2.0 - dotenv: ^4.2.0 data_client: git: url: https://github.com/flutter-news-app-full-source-code/data-client.git @@ -19,6 +21,7 @@ dependencies: data_repository: git: url: https://github.com/flutter-news-app-full-source-code/data-repository.git + dotenv: ^4.2.0 email_client: git: url: https://github.com/flutter-news-app-full-source-code/email-client.git @@ -27,13 +30,10 @@ dependencies: url: https://github.com/flutter-news-app-full-source-code/email-repository.git email_sendgrid: git: - url: https://github.com/flutter-news-app-full-source-code/email-sendgrid.git + url: https://github.com/flutter-news-app-full-source-code/email-sendgrid.git http_client: git: url: https://github.com/flutter-news-app-full-source-code/http-client.git - core: - git: - url: https://github.com/flutter-news-app-full-source-code/core.git json_annotation: ^4.9.0 logging: ^1.3.0 meta: ^1.16.0 From 8dc33bfa8c9c0c7aa07fc8adc2a10e53d3f100a0 Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:29:17 +0100 Subject: [PATCH 17/19] docs(README): overhaul content and structure for clarity & impact - Restructure README for better flow and readability - Enhance with visual elements and branding - Refine capability descriptions for clarity - Update license information and sponsorship details - Improve setup instructions and environment configuration --- README.md | 146 ++++++++++++++++++++++++------------------------------ 1 file changed, 64 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index 6957c52..e105a0f 100644 --- a/README.md +++ b/README.md @@ -1,126 +1,108 @@ -# flutter_news_app_api_server_full_source_code +
+Flutter News App Toolkit Logo -![coverage: percentage](https://img.shields.io/badge/coverage-xx-green) -[![style: very good analysis](https://img.shields.io/badge/style-very_good_analysis-B22C89.svg)](https://pub.dev/packages/very_good_analysis) -[![License: PolyForm Free Trial](https://img.shields.io/badge/License-PolyForm%20Free%20Trial-blue)](https://polyformproject.org/licenses/free-trial/1.0.0) +# Flutter News App - API Server Full Source Code -πŸš€ Accelerate the development of your news application backend with **flutter_news_app_api_server_full_source_code**, the -dedicated API service for the Headlines Toolkit. Built on the high-performance -Dart Frog framework, `flutter_news_app_api_server_full_source_code` provides the essential server-side infrastructure -specifically designed to power robust and feature-rich news applications. +

+coverage: percentage +DOCS READ +License: Buy +

+
-`flutter_news_app_api_server_full_source_code` is a core component of the **Headlines Toolkit**, a comprehensive, -source-available ecosystem designed for building feature-rich news -applications, which also includes a Flutter [mobile app](https://github.com/flutter-news-app-full-source-code/ht-main) and a web-based [content -management dashboard](https://github.com/flutter-news-app-full-source-code/ht-dashboard). +This is the complete and fully-functional backend API server for the Flutter News App Toolkit. Built with the high-performance Dart Frog framework, it gives you all the server-side features you need to power your news app, right out of the box. It is a key component of the [**flutter news app full source code toolkit**](https://github.com/flutter-news-app-full-source-code), an ecosystem that also includes a Flutter [mobile app](https://github.com/flutter-news-app-full-source-code/flutter-news-app-mobile-client-full-source-code) and a web-based [content dashboard](https://github.com/flutter-news-app-full-source-code/flutter-news-app-web-dashboard-full-source-code). -## ✨ Key Capabilities +## ⭐ Everything You Get, Ready to Go -* πŸ”’ **Flexible & Secure Authentication:** Provide seamless user access with - a unified system supporting passwordless email sign-in and anonymous guest - accounts. The API intelligently handles the conversion from a guest to a - permanent user, preserving all settings and preferences. It also includes - a secure, role-aware login flow for privileged dashboard users. +This API server comes packed with all the features you need to launch a professional, scalable news application. -* ⚑️ **Granular Role-Based Access Control (RBAC):** Implement precise - permissions with a dual-role system (`appRole` for application features, - `dashboardRole` for admin functions) to control access to API features - and data management capabilities. +#### πŸ” **Robust & Flexible Authentication** +* Provides secure, modern authentication flows, including passwordless email sign-in and anonymous guest accounts. +* Intelligently handles converting guest users to permanent accounts, preserving all their settings and saved content. +* Includes a separate, role-aware login flow for privileged dashboard users. +> **Your Advantage:** You get a complete, secure authentication system without the complexity. All the user management logic is done for you. βœ… -* βš™οΈ **Synchronized App Settings:** Ensure a consistent and personalized user - experience across devices by effortlessly syncing application preferences - like theme, language, font styles, and more. +#### ⚑️ **Granular Role-Based Access Control (RBAC)** +* Implement precise permissions with a dual-role system: `appRole` for mobile app features and `dashboardRole` for admin functions. +* Securely control access to API features and data management capabilities based on user roles. +> **Your Advantage:** A powerful, built-in security model that protects your data and ensures users only access what they're supposed to. πŸ›‘οΈ -* πŸ‘€ **Personalized User Preferences:** Enable richer user interactions by - managing and syncing user-specific data such as saved headlines, followed - sources, and followed topics tailored to individual users. +#### βš™οΈ **Centralized App & User Settings** +* Effortlessly sync user-specific settings like theme, language, and font styles across devices. +* Manage personalized content preferences, including saved headlines and followed topics/sources. +> **Your Advantage:** Deliver a seamless, personalized experience that keeps users' settings in sync, boosting engagement and retention. ❀️ -* πŸ’Ύ **Robust Data Management:** Securely manage core news data (headlines, - topics, sources) through a well-structured API that supports flexible - querying and sorting for dynamic content presentation. +#### πŸ’Ύ **Robust Data Management API** +* Securely manage all your core news data, including headlines, topics, sources, and countries. +* The API supports flexible querying, filtering, and sorting, allowing your app to display dynamic content feeds. +> **Your Advantage:** A powerful and secure data backend that's ready to scale with your content needs. πŸ“ˆ -* 🌐 **Dynamic Remote Configuration:** Centrally manage application - behaviorβ€”including ad frequency, feature flags, and maintenance statusβ€”without - requiring a client-side update. +#### 🌐 **Dynamic Remote Configuration** +* Centrally manage your app's behavior without shipping an update. +* Control ad frequency, feature flags, force-update prompts, and maintenance status directly from the server. +> **Your Advantage:** Adapt your app on the fly, run experiments, and respond to issues instantly, giving you maximum operational control. πŸ•ΉοΈ -* πŸ“Š **Dynamic Dashboard Summary:** Access real-time, aggregated metrics on - key data points like total headlines, topics, and sources, providing - an at-a-glance overview for administrative dashboards. +#### πŸ“Š **Real-Time Dashboard Analytics** +* Access real-time, aggregated metrics on key data points like total headlines, topics, and sources. +* Provides an at-a-glance overview perfect for administrative dashboards. +> **Your Advantage:** Instantly feed your content dashboard with the data it needs to provide valuable insights. 🎯 -* πŸ”§ **Solid Technical Foundation:** Built with Dart and the high-performance - Dart Frog framework, offering a maintainable codebase, standardized API - responses, and built-in access control for developers. +#### πŸ—οΈ **Clean & Modern Architecture** +* Built with Dart and the high-performance Dart Frog framework. +* Features a clean, layered architecture with standardized API responses and built-in dependency injection. +> **Your Advantage:** A solid, maintainable codebase that's easy to understand, extend, and build upon. πŸ”§ -## πŸ”Œ API Endpoints +--- -`flutter_news_app_api_server_full_source_code` provides a clear and organized API surface under the `/api/v1/` path. -Key endpoint groups cover authentication, data access, and user settings. +## πŸ”‘ License: Source-Available with a Free Trial -For complete API specifications, detailed endpoint documentation, -request/response schemas, and error codes, please refer to the dedicated -documentation website [todo:Link to the docs website]. +Get started for free and purchase when you're ready to launch! -## πŸ”‘ Access and Licensing +* **TRY IT:** Download and explore the full source code under the PolyForm Free Trial [license](LICENSE). Perfect for evaluation. +* **BUY IT:** Get an unlimited commercial lifetime license with a **one-time payment**. No subscriptions! +* **GET YOURS:** [**Purchase via GitHub Sponsors**](https://github.com/sponsors/flutter-news-app-full-source-code). -`flutter_news_app_api_server_full_source_code` is source-available as part of the Headlines Toolkit ecosystem. +> *

Note: The single purchase provides a comprehensive commercial license covering every repository within the [Flutter News App - Full Source Code Toolkit](https://github.com/flutter-news-app-full-source-code) organization. No separate purchases are needed for the mobile app or dashboard.

* -To acquire a commercial license for building unlimited news applications, please visit -the [Headlines Toolkit GitHub organization page](https://github.com/flutter-news-app-full-source-code) -for more details. +--- -## πŸ’» Setup & Running +## πŸš€ Getting Started & Running Locally 1. **Prerequisites:** * Dart SDK (`>=3.0.0`) * MongoDB (`>=5.0` recommended) * Dart Frog CLI (`dart pub global activate dart_frog_cli`) -2. **Configuration:** - Before running the server, you must configure the necessary environment - variables. +2. **Clone the repository:** + ```bash + git clone https://github.com/flutter-news-app-full-source-code/flutter-news-app-api-server-full-source-code.git + cd flutter-news-app-api-server-full-source-code + ``` +3. **Configure your environment:** Copy the `.env.example` file to a new file named `.env`: ```bash cp .env.example .env ``` - Then, open the new `.env` file and update the variables with your actual - configuration values, such as the `DATABASE_URL`. + Then, open the new `.env` file and update the variables with your actual configuration values (e.g., `DATABASE_URL`). -3. **Clone the repository:** - ```bash - git clone https://github.com/flutter-news-app-full-source-code/flutter-news-app-api-server-full-source-code.git - cd flutter-news-app-api-server-full-source-code - ``` 4. **Get dependencies:** ```bash dart pub get ``` + 5. **Run the development server:** ```bash dart_frog dev ``` - The API will typically be available at `http://localhost:8080`. On startup, - the server will connect to your MongoDB database and seed it with initial - fixture data. This seeding process is idempotent (using `upsert` - operations), so it can be run multiple times without creating duplicates. - + The API will be available at `http://localhost:8080`. On startup, the server will connect to your MongoDB database and seed it with initial data. This process is idempotent, so it can be run multiple times without creating duplicates. - **Note on Web Client Integration (CORS):** To allow web applications (like - the HT Dashboard) to connect to this API in production, the - `CORS_ALLOWED_ORIGIN` environment variable must be set to the specific - origin of your web application (e.g., `https://your-dashboard.com`). - - For local development, the API automatically allows any request - originating from `localhost` on any port, so you do not need to set this - variable. +--- ## βœ… Testing -Ensure the API is robust and meets quality standards by running the test suite: - -```bash -# Ensure very_good_cli is activated: dart pub global activate very_good_cli -very_good test --min-coverage 90 -``` +This project aims for high test coverage to ensure quality and reliability. -Aim for a minimum of 90% line coverage. +* Run tests with: + ```bash + very_good test --min-coverage 90 From 3536bb38bd965cdd69a987f8718e6af5cebbb0f6 Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:34:57 +0100 Subject: [PATCH 18/19] docs(README): update toolkit name and formatting - Updated the name "flutter news app full source code toolkit" to "Flutter News App Toolkit" for consistency - Removed unnecessary bold formatting in the README introduction --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e105a0f..51d953f 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@

-This is the complete and fully-functional backend API server for the Flutter News App Toolkit. Built with the high-performance Dart Frog framework, it gives you all the server-side features you need to power your news app, right out of the box. It is a key component of the [**flutter news app full source code toolkit**](https://github.com/flutter-news-app-full-source-code), an ecosystem that also includes a Flutter [mobile app](https://github.com/flutter-news-app-full-source-code/flutter-news-app-mobile-client-full-source-code) and a web-based [content dashboard](https://github.com/flutter-news-app-full-source-code/flutter-news-app-web-dashboard-full-source-code). +This is the complete and fully-functional backend API server for the Flutter News App Toolkit. Built with the high-performance Dart Frog framework, it gives you all the server-side features you need to power your news app, right out of the box. It is a key component of the [**Flutter News App Toolkit**](https://github.com/flutter-news-app-full-source-code), an ecosystem that also includes a flutter [mobile app](https://github.com/flutter-news-app-full-source-code/flutter-news-app-mobile-client-full-source-code) and a web-based [content dashboard](https://github.com/flutter-news-app-full-source-code/flutter-news-app-web-dashboard-full-source-code). ## ⭐ Everything You Get, Ready to Go @@ -62,7 +62,7 @@ Get started for free and purchase when you're ready to launch! * **BUY IT:** Get an unlimited commercial lifetime license with a **one-time payment**. No subscriptions! * **GET YOURS:** [**Purchase via GitHub Sponsors**](https://github.com/sponsors/flutter-news-app-full-source-code). -> *

Note: The single purchase provides a comprehensive commercial license covering every repository within the [Flutter News App - Full Source Code Toolkit](https://github.com/flutter-news-app-full-source-code) organization. No separate purchases are needed for the mobile app or dashboard.

* +> *

Note: The single purchase provides a comprehensive commercial license covering every repository within the [Flutter News App Toolkit](https://github.com/flutter-news-app-full-source-code) organization. No separate purchases are needed for the mobile app or dashboard.

* --- From af6c78b48cbd65ef6fcc42077fe658321f7066be Mon Sep 17 00:00:00 2001 From: fulleni Date: Wed, 23 Jul 2025 17:36:42 +0100 Subject: [PATCH 19/19] docs(pubspec): update package description - Replace generic description with a more detailed explanation - Highlight key features: authentication, data management, user settings - Mention Dart Frog as the technology used for implementation --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index db84c17..49d8235 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,5 @@ name: flutter_news_app_api_server_full_source_code -description: ... +description: The complete backend API server for the Flutter News App Toolkit, built with Dart Frog. Powers authentication, data management, user settings, and more. repository: https://github.com/flutter-news-app-full-source-code/flutter-news-app-api-server-full-source-code publish_to: none