@@ -63,21 +63,21 @@ Future<Response> onRequest(RequestContext context) async {
63
63
///
64
64
/// This handler implements model-specific filtering rules:
65
65
/// - **Headlines (`model=headline` ):**
66
- /// - Filterable by `q` (text query on title only).
67
- /// If `q` is present, `categories ` and `sources` are ignored.
66
+ /// - Filterable by `q` (text query on title only). If `q` is present,
67
+ /// `topics ` and `sources` are ignored.
68
68
/// Example: `/api/v1/data?model=headline&q=Dart+Frog`
69
69
/// - OR by a combination of:
70
- /// - `categories ` (comma-separated category IDs).
71
- /// Example: `/api/v1/data?model=headline&categories=catId1,catId2 `
70
+ /// - `topics ` (comma-separated topic IDs).
71
+ /// Example: `/api/v1/data?model=headline&topics=topicId1,topicId2 `
72
72
/// - `sources` (comma-separated source IDs).
73
73
/// Example: `/api/v1/data?model=headline&sources=sourceId1`
74
- /// - Both `categories ` and `sources` can be used together (AND logic).
75
- /// Example: `/api/v1/data?model=headline&categories=catId1 &sources=sourceId1`
74
+ /// - Both `topics ` and `sources` can be used together (AND logic).
75
+ /// Example: `/api/v1/data?model=headline&topics=topicId1 &sources=sourceId1`
76
76
/// - Other parameters for headlines (e.g., `countries` ) will result in a 400 Bad Request.
77
77
///
78
78
/// - **Sources (`model=source` ):**
79
- /// - Filterable by `q` (text query on name only).
80
- /// If `q` is present, `countries`, `sourceTypes`, `languages` are ignored.
79
+ /// - Filterable by `q` (text query on name only). If `q` is present,
80
+ /// `countries`, `sourceTypes`, `languages` are ignored.
81
81
/// Example: `/api/v1/data?model=source&q=Tech+News`
82
82
/// - OR by a combination of:
83
83
/// - `countries` (comma-separated country ISO codes for `source.headquarters.iso_code`).
@@ -89,10 +89,10 @@ Future<Response> onRequest(RequestContext context) async {
89
89
/// - These specific filters are ANDed if multiple are provided.
90
90
/// - Other parameters for sources will result in a 400 Bad Request.
91
91
///
92
- /// - **Categories (`model=category ` ):**
92
+ /// - **Topics (`model=topic ` ):**
93
93
/// - Filterable ONLY by `q` (text query on name only).
94
- /// Example: `/api/v1/data?model=category &q=Technology`
95
- /// - Other parameters for categories will result in a 400 Bad Request.
94
+ /// Example: `/api/v1/data?model=topic &q=Technology`
95
+ /// - Other parameters for topics will result in a 400 Bad Request.
96
96
///
97
97
/// - **Countries (`model=country` ):**
98
98
/// - Filterable ONLY by `q` (text query on name and isoCode).
@@ -156,14 +156,14 @@ Future<Response> _handleGet(
156
156
157
157
switch (modelName) {
158
158
case 'headline' :
159
- allowedKeys = {'categories ' , 'sources' , 'q' };
159
+ allowedKeys = {'topics ' , 'sources' , 'q' };
160
160
final qValue = queryParams['q' ];
161
161
if (qValue != null && qValue.isNotEmpty) {
162
162
specificQueryForClient['title_contains' ] = qValue;
163
163
// specificQueryForClient['description_contains'] = qValue; // Removed
164
164
} else {
165
- if (queryParams.containsKey ('categories ' )) {
166
- specificQueryForClient['category .id_in' ] = queryParams['categories ' ]! ;
165
+ if (queryParams.containsKey ('topics ' )) {
166
+ specificQueryForClient['topic .id_in' ] = queryParams['topics ' ]! ;
167
167
}
168
168
if (queryParams.containsKey ('sources' )) {
169
169
specificQueryForClient['source.id_in' ] = queryParams['sources' ]! ;
@@ -188,7 +188,7 @@ Future<Response> _handleGet(
188
188
specificQueryForClient['language_in' ] = queryParams['languages' ]! ;
189
189
}
190
190
}
191
- case 'category ' :
191
+ case 'topic ' :
192
192
allowedKeys = {'q' };
193
193
final qValue = queryParams['q' ];
194
194
if (qValue != null && qValue.isNotEmpty) {
@@ -217,7 +217,7 @@ Future<Response> _handleGet(
217
217
// Validate received keys against allowed keys for the specific models
218
218
if (modelName == 'headline' ||
219
219
modelName == 'source' ||
220
- modelName == 'category ' ||
220
+ modelName == 'topic ' ||
221
221
modelName == 'country' ) {
222
222
for (final key in receivedKeys) {
223
223
if (! allowedKeys.contains (key)) {
@@ -247,8 +247,8 @@ Future<Response> _handleGet(
247
247
sortBy: sortBy,
248
248
sortOrder: sortOrder,
249
249
);
250
- case 'category ' :
251
- final repo = context.read <HtDataRepository <Category >>();
250
+ case 'topic ' :
251
+ final repo = context.read <HtDataRepository <Topic >>();
252
252
paginatedResponse = await repo.readAllByQuery (
253
253
specificQueryForClient,
254
254
userId: userIdForRepoCall,
@@ -406,10 +406,10 @@ Future<Response> _handlePost(
406
406
item: newItem as Headline ,
407
407
userId: userIdForRepoCall,
408
408
);
409
- case 'category ' :
410
- final repo = context.read <HtDataRepository <Category >>();
409
+ case 'topic ' :
410
+ final repo = context.read <HtDataRepository <Topic >>();
411
411
createdItem = await repo.create (
412
- item: newItem as Category ,
412
+ item: newItem as Topic ,
413
413
userId: userIdForRepoCall,
414
414
);
415
415
case 'source' :
@@ -493,12 +493,12 @@ Simplified Strict Filtering Rules (ALL FILTERS ARE ANDed if present):
493
493
- `q` (free-text query, searching `source.name` only)
494
494
495
495
3. Categories (`model=category`):
496
- - Filterable __only__ by:
497
- - `q` (free-text query, searching `category.name` only)
496
+ - Filterable __only__ by: - `q` (free-text query, searching `topic.name`
497
+ only)
498
498
499
499
4. Countries (`model=country`):
500
- - Filterable __only__ by:
501
- - `q` (free-text query, searching `country.name` only)
500
+ - Filterable __only__ by: - `q` (free-text query, searching `country.name`
501
+ only)
502
502
503
503
------
504
504
@@ -515,12 +515,12 @@ Explicitly Define Allowed Parameters per Model: When processing the request for
515
515
Model: `headline`
516
516
517
517
1. Filter by single category:
518
- - URL: `/api/v1/data?model=headline&categories =c1a2b3c4-d5e6-f789-0123-456789abcdef`
519
- - Expected: Headlines with category ID `c1a2b3c4-d5e6-f789-0123-456789abcdef`.
518
+ - URL: `/api/v1/data?model=headline&topics =c1a2b3c4-d5e6-f789-0123-456789abcdef`
519
+ - Expected: Headlines with topic ID `c1a2b3c4-d5e6-f789-0123-456789abcdef`.
520
520
521
521
2. Filter by multiple comma-separated categories (client-side `_in` implies OR for values):
522
- - URL: `/api/v1/data?model=headline&categories =c1a2b3c4-d5e6-f789-0123-456789abcdef,c2b3c4d5-e6f7-a890-1234-567890abcdef`
523
- - Expected: Headlines whose category ID is *either* of the two provided.
522
+ - URL: `/api/v1/data?model=headline&topics =c1a2b3c4-d5e6-f789-0123-456789abcdef,c2b3c4d5-e6f7-a890-1234-567890abcdef`
523
+ - Expected: Headlines whose topic ID is *either* of the two provided.
524
524
525
525
3. Filter by single source:
526
526
- URL: `/api/v1/data?model=headline&sources=s1a2b3c4-d5e6-f789-0123-456789abcdef`
@@ -531,16 +531,16 @@ Model: `headline`
531
531
- Expected: Headlines whose source ID is *either* of the two provided.
532
532
533
533
5. Filter by a category AND a source:
534
- - URL: `/api/v1/data?model=headline&categories =c1a2b3c4-d5e6-f789-0123-456789abcdef&sources=s1a2b3c4-d5e6-f789-0123-456789abcdef`
535
- - Expected: Headlines matching *both* the category ID AND the source ID.
534
+ - URL: `/api/v1/data?model=headline&topics =c1a2b3c4-d5e6-f789-0123-456789abcdef&sources=s1a2b3c4-d5e6-f789-0123-456789abcdef`
535
+ - Expected: Headlines matching *both* the topic ID AND the source ID.
536
536
537
537
6. Filter by text query `q` (title only):
538
538
- URL: `/api/v1/data?model=headline&q=Dart`
539
539
- Expected: Headlines where "Dart" (case-insensitive) appears in the title.
540
540
541
541
7. Filter by `q` AND `categories` (q should take precedence, categories ignored):
542
- - URL: `/api/v1/data?model=headline&q=Flutter&categories =c1a2b3c4-d5e6-f789-0123-456789abcdef`
543
- - Expected: Headlines matching `q=Flutter` (in title), ignoring the category filter.
542
+ - URL: `/api/v1/data?model=headline&q=Flutter&topics =c1a2b3c4-d5e6-f789-0123-456789abcdef`
543
+ - Expected: Headlines matching `q=Flutter` (in title), ignoring the topic filter.
544
544
545
545
8. Invalid parameter for headlines (e.g., `countries`):
546
546
- URL: `/api/v1/data?model=headline&countries=US`
@@ -580,18 +580,18 @@ Model: `source`
580
580
- URL: `/api/v1/data?model=source&q=Official&countries=US`
581
581
- Expected: Sources matching `q=Official` (in name), ignoring the country filter.
582
582
583
- 17. Invalid parameter for sources (e.g., `categories `):
584
- - URL: `/api/v1/data?model=source&categories=catId1 `
583
+ 17. Invalid parameter for sources (e.g., `topics `):
584
+ - URL: `/api/v1/data?model=source&topics=topicId1 `
585
585
- Expected: `400 Bad Request`.
586
586
587
- Model: `category `
587
+ Model: `topic `
588
588
589
589
18. Filter by text query `q` for categories (name only):
590
- - URL: `/api/v1/data?model=category &q=Mobile`
591
- - Expected: Categories where "Mobile" appears in name.
590
+ - URL: `/api/v1/data?model=topic &q=Mobile`
591
+ - Expected: Topics where "Mobile" appears in name.
592
592
593
593
19. Invalid parameter for categories (e.g., `sources`):
594
- - URL: `/api/v1/data?model=category &sources=sourceId1`
594
+ - URL: `/api/v1/data?model=topic &sources=sourceId1`
595
595
- Expected: `400 Bad Request`.
596
596
597
597
Model: `country`
@@ -605,6 +605,6 @@ Model: `country`
605
605
- Expected: Country with name containing "US". (Note: This test's expectation might need adjustment if no country name contains "US" but its isoCode is "US". The current `q` logic for country only searches name).
606
606
607
607
22. Invalid parameter for countries (e.g., `categories`):
608
- - URL: `/api/v1/data?model=country&categories=catId1 `
608
+ - URL: `/api/v1/data?model=country&topics=topicId1 `
609
609
- Expected: `400 Bad Request`.
610
610
*/
0 commit comments