Skip to content

Commit b245795

Browse files
authored
Merge pull request #53 from flutter-news-app-full-source-code/implement-country-ggregation-service
Implement country ggregation service
2 parents bd92900 + 04d30c6 commit b245795

File tree

8 files changed

+372
-6
lines changed

8 files changed

+372
-6
lines changed

.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,7 @@
5252

5353
# OPTIONAL: Window for the /data API endpoints, in minutes.
5454
# RATE_LIMIT_DATA_API_WINDOW_MINUTES=60
55+
56+
# OPTIONAL: The cache duration for the CountryQueryService, in minutes.
57+
# Defaults to 15 minutes if not specified.
58+
# COUNTRY_SERVICE_CACHE_MINUTES=15

analysis_options.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ analyzer:
1010
avoid_catching_errors: ignore
1111
document_ignores: ignore
1212
one_member_abstracts: ignore
13+
cascade_invocations: ignore
1314
exclude:
1415
- build/**
1516
linter:

lib/src/config/app_dependencies.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'package:flutter_news_app_api_server_full_source_code/src/config/environm
99
import 'package:flutter_news_app_api_server_full_source_code/src/rbac/permission_service.dart';
1010
import 'package:flutter_news_app_api_server_full_source_code/src/services/auth_service.dart';
1111
import 'package:flutter_news_app_api_server_full_source_code/src/services/auth_token_service.dart';
12+
import 'package:flutter_news_app_api_server_full_source_code/src/services/country_query_service.dart';
1213
import 'package:flutter_news_app_api_server_full_source_code/src/services/dashboard_summary_service.dart';
1314
import 'package:flutter_news_app_api_server_full_source_code/src/services/database_seeding_service.dart';
1415
import 'package:flutter_news_app_api_server_full_source_code/src/services/default_user_preference_limit_service.dart';
@@ -69,6 +70,7 @@ class AppDependencies {
6970
late final PermissionService permissionService;
7071
late final UserPreferenceLimitService userPreferenceLimitService;
7172
late final RateLimitService rateLimitService;
73+
late final CountryQueryService countryQueryService;
7274

7375
/// Initializes all application dependencies.
7476
///
@@ -238,6 +240,11 @@ class AppDependencies {
238240
connectionManager: _mongoDbConnectionManager,
239241
log: Logger('MongoDbRateLimitService'),
240242
);
243+
countryQueryService = CountryQueryService(
244+
countryRepository: countryRepository,
245+
log: Logger('CountryQueryService'),
246+
cacheDuration: EnvironmentConfig.countryServiceCacheDuration,
247+
);
241248

242249
_isInitialized = true;
243250
_log.info('Application dependencies initialized successfully.');
@@ -255,6 +262,7 @@ class AppDependencies {
255262
await _mongoDbConnectionManager.close();
256263
tokenBlacklistService.dispose();
257264
rateLimitService.dispose();
265+
countryQueryService.dispose(); // Dispose the new service
258266
_isInitialized = false;
259267
_log.info('Application dependencies disposed.');
260268
}

lib/src/config/environment_config.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,4 +172,14 @@ abstract final class EnvironmentConfig {
172172
int.tryParse(_env['RATE_LIMIT_DATA_API_WINDOW_MINUTES'] ?? '60') ?? 60;
173173
return Duration(minutes: minutes);
174174
}
175+
176+
/// Retrieves the cache duration in minutes for the CountryQueryService.
177+
///
178+
/// The value is read from the `COUNTRY_SERVICE_CACHE_MINUTES` environment
179+
/// variable. Defaults to 15 minutes if not set or if parsing fails.
180+
static Duration get countryServiceCacheDuration {
181+
final minutes =
182+
int.tryParse(_env['COUNTRY_SERVICE_CACHE_MINUTES'] ?? '15') ?? 15;
183+
return Duration(minutes: minutes);
184+
}
175185
}

lib/src/registry/data_operation_registry.dart

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:core/core.dart';
22
import 'package:dart_frog/dart_frog.dart';
33
import 'package:data_repository/data_repository.dart';
44
import 'package:flutter_news_app_api_server_full_source_code/src/middlewares/ownership_check_middleware.dart';
5+
import 'package:flutter_news_app_api_server_full_source_code/src/services/country_query_service.dart';
56
import 'package:flutter_news_app_api_server_full_source_code/src/services/dashboard_summary_service.dart';
67

78
// --- Typedefs for Data Operations ---
@@ -128,12 +129,27 @@ class DataOperationRegistry {
128129
sort: s,
129130
pagination: p,
130131
),
131-
'country': (c, uid, f, s, p) => c.read<DataRepository<Country>>().readAll(
132-
userId: uid,
133-
filter: f,
134-
sort: s,
135-
pagination: p,
136-
),
132+
'country': (c, uid, f, s, p) async {
133+
// Check for special filters that require aggregation.
134+
if (f != null &&
135+
(f.containsKey('hasActiveSources') ||
136+
f.containsKey('hasActiveHeadlines'))) {
137+
// Use the injected CountryQueryService for complex queries.
138+
final countryQueryService = c.read<CountryQueryService>();
139+
return countryQueryService.getFilteredCountries(
140+
filter: f,
141+
pagination: p,
142+
sort: s,
143+
);
144+
}
145+
// Fallback to standard readAll if no special filters are present.
146+
return c.read<DataRepository<Country>>().readAll(
147+
userId: uid,
148+
filter: f,
149+
sort: s,
150+
pagination: p,
151+
);
152+
},
137153
'language': (c, uid, f, s, p) => c
138154
.read<DataRepository<Language>>()
139155
.readAll(userId: uid, filter: f, sort: s, pagination: p),

0 commit comments

Comments
 (0)