Skip to content

Commit 4a0647d

Browse files
committed
docs: add data filtering rules documentation
1 parent 48fa7c7 commit 4a0647d

File tree

1 file changed

+134
-0
lines changed

1 file changed

+134
-0
lines changed

routes/api/v1/data/index.dart

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -419,3 +419,137 @@ Future<Response> _handlePost(
419419
// Return 201 Created with the wrapped and serialized response
420420
return Response.json(statusCode: HttpStatus.created, body: responseJson);
421421
}
422+
423+
/*
424+
Simplified Strict Filtering Rules (ALL FILTERS ARE ANDed if present):
425+
426+
1. Headlines (`model=headline`):
427+
- Filterable by any combination (ANDed) of:
428+
- `categories` (plural, comma-separated IDs, matching `headline.category.id`)
429+
- `sources` (plural, comma-separated IDs, matching `headline.source.id`)
430+
- `q` (free-text query, searching `headline.title` only)
431+
- *No other filters (like `countries`) are allowed for headlines.*
432+
433+
2. Sources (`model=source`):
434+
- Filterable by any combination (ANDed) of:
435+
- `countries` (plural, comma-separated ISO codes, matching `source.headquarters.iso_code`)
436+
- `sourceTypes` (plural, comma-separated enum strings, matching `source.sourceType`)
437+
- `languages` (plural, comma-separated language codes, matching `source.language`)
438+
- `q` (free-text query, searching `source.name` only)
439+
440+
3. Categories (`model=category`):
441+
- Filterable __only__ by:
442+
- `q` (free-text query, searching `category.name` only)
443+
444+
4. Countries (`model=country`):
445+
- Filterable __only__ by:
446+
- `q` (free-text query, searching `country.name` only)
447+
448+
------
449+
450+
Explicitly Define Allowed Parameters per Model: When processing the request for a given `modelName`, the handler should have a predefined set of *allowed* query parameter keys for that specific model.
451+
452+
- Example for `modelName == 'headline'`:
453+
- Allowed keys: `categories`, `sources`, `q` (plus standard ones like `limit`, `startAfterId`).
454+
- Example for `modelName == 'source'`:
455+
- Allowed keys: `countries`, `sourceTypes`, `languages`, `q` (plus standard ones).
456+
- And so on for `category` and `country`.
457+
458+
----------------- TESTED FILTERS ---------------
459+
460+
Model: `headline`
461+
462+
1. Filter by single category:
463+
- URL: `/api/v1/data?model=headline&categories=c1a2b3c4-d5e6-f789-0123-456789abcdef`
464+
- Expected: Headlines with category ID `c1a2b3c4-d5e6-f789-0123-456789abcdef`.
465+
466+
2. Filter by multiple comma-separated categories (client-side `_in` implies OR for values):
467+
- URL: `/api/v1/data?model=headline&categories=c1a2b3c4-d5e6-f789-0123-456789abcdef,c2b3c4d5-e6f7-a890-1234-567890abcdef`
468+
- Expected: Headlines whose category ID is *either* of the two provided.
469+
470+
3. Filter by single source:
471+
- URL: `/api/v1/data?model=headline&sources=s1a2b3c4-d5e6-f789-0123-456789abcdef`
472+
- Expected: Headlines with source ID `s1a2b3c4-d5e6-f789-0123-456789abcdef`.
473+
474+
4. Filter by multiple comma-separated sources (client-side `_in` implies OR for values):
475+
- URL: `/api/v1/data?model=headline&sources=s1a2b3c4-d5e6-f789-0123-456789abcdef,s2b3c4d5-e6f7-a890-1234-567890abcdef`
476+
- Expected: Headlines whose source ID is *either* of the two provided.
477+
478+
5. Filter by a category AND a source:
479+
- URL: `/api/v1/data?model=headline&categories=c1a2b3c4-d5e6-f789-0123-456789abcdef&sources=s1a2b3c4-d5e6-f789-0123-456789abcdef`
480+
- Expected: Headlines matching *both* the category ID AND the source ID.
481+
482+
6. Filter by text query `q` (title only):
483+
- URL: `/api/v1/data?model=headline&q=Dart`
484+
- Expected: Headlines where "Dart" (case-insensitive) appears in the title.
485+
486+
7. Filter by `q` AND `categories` (q should take precedence, categories ignored):
487+
- URL: `/api/v1/data?model=headline&q=Flutter&categories=c1a2b3c4-d5e6-f789-0123-456789abcdef`
488+
- Expected: Headlines matching `q=Flutter` (in title), ignoring the category filter.
489+
490+
8. Invalid parameter for headlines (e.g., `countries`):
491+
- URL: `/api/v1/data?model=headline&countries=US`
492+
- Expected: `400 Bad Request` with an error message about an invalid query parameter.
493+
494+
Model: `source`
495+
496+
9. Filter by single country (ISO code):
497+
- URL: `/api/v1/data?model=source&countries=GB`
498+
- Expected: Sources headquartered in 'GB'.
499+
500+
10. Filter by multiple comma-separated countries (client-side `_in` implies OR for values):
501+
- URL: `/api/v1/data?model=source&countries=US,GB`
502+
- Expected: Sources headquartered in 'US' OR 'GB'.
503+
504+
11. Filter by single `sourceType`:
505+
- URL: `/api/v1/data?model=source&sourceTypes=blog`
506+
- Expected: Sources of type 'blog'.
507+
508+
12. Filter by multiple comma-separated `sourceTypes` (client-side `_in` implies OR for values):
509+
- URL: `/api/v1/data?model=source&sourceTypes=blog,specializedPublisher`
510+
- Expected: Sources of type 'blog' OR 'specializedPublisher'.
511+
512+
13. Filter by single `language`:
513+
- URL: `/api/v1/data?model=source&languages=en`
514+
- Expected: Sources in 'en' language.
515+
516+
14. Filter by combination (countries AND sourceTypes AND languages):
517+
- URL: `/api/v1/data?model=source&countries=GB&sourceTypes=nationalNewsOutlet&languages=en`
518+
- Expected: Sources matching all three criteria.
519+
520+
15. Filter by text query `q` for sources (name only):
521+
- URL: `/api/v1/data?model=source&q=Ventures`
522+
- Expected: Sources where "Ventures" appears in the name.
523+
524+
16. Filter by `q` AND `countries` for sources (`q` takes precedence):
525+
- URL: `/api/v1/data?model=source&q=Official&countries=US`
526+
- Expected: Sources matching `q=Official` (in name), ignoring the country filter.
527+
528+
17. Invalid parameter for sources (e.g., `categories`):
529+
- URL: `/api/v1/data?model=source&categories=catId1`
530+
- Expected: `400 Bad Request`.
531+
532+
Model: `category`
533+
534+
18. Filter by text query `q` for categories (name only):
535+
- URL: `/api/v1/data?model=category&q=Mobile`
536+
- Expected: Categories where "Mobile" appears in name.
537+
538+
19. Invalid parameter for categories (e.g., `sources`):
539+
- URL: `/api/v1/data?model=category&sources=sourceId1`
540+
- Expected: `400 Bad Request`.
541+
542+
Model: `country`
543+
544+
20. Filter by text query `q` for countries (name only):
545+
- URL: `/api/v1/data?model=country&q=United`
546+
- Expected: Countries where "United" appears in the name.
547+
548+
21. Filter by text query `q` for countries (name only, to match "US" if a country name contains "US"):
549+
- URL: `/api/v1/data?model=country&q=US`
550+
- 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).
551+
552+
22. Invalid parameter for countries (e.g., `categories`):
553+
- URL: `/api/v1/data?model=country&categories=catId1`
554+
- Expected: `400 Bad Request`.
555+
*/

0 commit comments

Comments
 (0)