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

[](https://pub.dev/packages/very_good_analysis)
[](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
+
+
-
-[](https://pub.dev/packages/very_good_analysis)
-[](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.
+
+
+
+
+
+
-`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