propel_api 0.3.2 โ†’ 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a2cc174f214b50c6e5f58829c9136661591fc142a1e14e09aaf7221c0e1ddda
4
- data.tar.gz: ae2f7764a20f7dc8b22b35486c4d1ca68e4910321d98c624306293800326270b
3
+ metadata.gz: 04fb55f19379b238226c473c68009234156cc6f788d54eb29a89155db938556e
4
+ data.tar.gz: 6bb69d00b06c6497d0a6fbbec4d4bafc026cd2b1484eaef48e9b31e9bd20564d
5
5
  SHA512:
6
- metadata.gz: 4ca81a75e2225c0a2bdff55f17aef1e5f6067c7b19c0e815a074201b39a508a0f46d3afa6bcbc54225e7ebc3314cedf46ecdf18cccfa11c15b2031b0afc8c168
7
- data.tar.gz: 2bab3dadb532118c96fbdc76e8fa389be29fa4d58801fc3dc7ab6fbea90cffa9534795035f306dd470f6d89f841b055909a3e582634fbae49c5296cc3f44e335
6
+ metadata.gz: 49af6bb0bbfcad1d62fdf4aada990189a1c1e850df87f1cee4b284ece041bf7c3c777907deff2d2df332b7b44a4563dba6b6f4de29c75c3e4c2e97609345b8d5
7
+ data.tar.gz: 87d70201da1cd3e2630cc1135997dfdb8bcf7c17900a341e4f9337d9accdc446d64dea4a06aeafcf1a7ae6e621daa2366ab5ea7c35e5434f594bd5e2fbb9869a
data/CHANGELOG.md CHANGED
@@ -7,9 +7,75 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.4] - 2025-09-29
11
+
12
+ ### Fixed
13
+ - **Custom `has_scope` definitions**: The dynamic scope generator no longer overrides custom `has_scope` definitions, allowing developers to implement their own filtering logic without interference.
14
+ - **`has_scope` parameter filtering**: All declared `has_scope` parameters (both dynamic and custom) are now automatically permitted, fixing an issue where they were being filtered out as unsafe.
15
+
10
16
  ### Planned Features
11
17
  - GraphQL adapter support
12
18
 
19
+ ## [0.3.3] - 2025-01-XX
20
+
21
+ ### ๐ŸŽ‰ Major Features Added
22
+ - **Comprehensive Dynamic Filtering System**: Complete implementation of automatic URL query string filtering and scoping using the `has_scope` gem
23
+ - **Multi-Type Filtering Support**: Full filtering support across all data types (string, numeric, boolean, datetime, date, time)
24
+ - **Database-Agnostic Implementation**: Works seamlessly across SQLite, PostgreSQL, and MySQL without database-specific code
25
+ - **Automatic Scope Generation**: Dynamic scope generation based on model column types and filter operators
26
+ - **Intelligent Facet Integration**: Automatic inclusion of filterable fields in JSON facets for API responses
27
+
28
+ ### ๐Ÿ” Advanced Filtering Capabilities
29
+ - **String Filtering**: Exact match (`_eq`), contains (`_contains`), starts with (`_starts_with`), ends with (`_ends_with`), in list (`_in`)
30
+ - **Numeric Filtering**: Comparison operators (`_gt`, `_lt`, `_gte`, `_lte`), range filtering (`_range`), in list (`_in`)
31
+ - **Boolean Filtering**: Multiple value format support (`true`/`false`, `1`/`0`, `yes`/`no`, `on`/`off`)
32
+ - **DateTime Filtering**: Temporal comparisons (`_before`, `_after`), date extraction (`_year`, `_month`, `_day`), date matching (`_date`)
33
+ - **Range Filtering**: Support for both array and string formats (e.g., `"150,350"` or `[150, 350]`)
34
+
35
+ ### ๐Ÿ› ๏ธ Technical Implementation
36
+ - **PropelDynamicScopeGenerator**: New generator class for automatic scope creation based on model columns
37
+ - **PropelModelFiltersConcern**: Model concern for dynamic scope generation and filter parameter validation
38
+ - **PropelControllerFiltersConcern**: Controller concern for has_scope integration and security validation
39
+ - **PropelFilterOperators**: Configuration class defining available operators for each data type
40
+ - **Database-Agnostic Datetime Parsing**: Ruby-based datetime parsing instead of SQL extraction functions
41
+
42
+ ### ๐Ÿ”’ Security & Performance
43
+ - **Input Validation**: Comprehensive validation of filter parameters against allowed field names and operators
44
+ - **SQL Injection Protection**: All parameters properly escaped and parameterized
45
+ - **Multi-Tenancy Integration**: Automatic organization scoping for all filtered queries
46
+ - **Sensitive Field Filtering**: Automatic exclusion of sensitive fields (passwords, tokens, etc.) from filtering
47
+ - **Performance Optimization**: Efficient range queries and indexed field prioritization
48
+
49
+ ### ๐Ÿ“Š Enhanced JSON Facet System
50
+ - **Smart Field Inclusion**: Automatic inclusion of boolean and datetime fields in `:short` facets
51
+ - **Exclusion Lists**: Configurable exclusion of specific fields (e.g., `created_at`, `updated_at`, `internal_flag`)
52
+ - **Consistent Serialization**: Ensures filterable fields are available in API responses for client-side filtering
53
+
54
+ ### ๐Ÿงช Comprehensive Testing
55
+ - **Test-Driven Development**: Complete test suite with 992 tests covering all filtering scenarios
56
+ - **Fixture-Aware Testing**: Unique test data values to avoid conflicts with fixture data
57
+ - **Multi-Tenancy Testing**: Proper testing of organization-scoped filtering
58
+ - **Edge Case Coverage**: Testing of invalid inputs, empty values, and error conditions
59
+ - **Database Compatibility**: Tests pass across SQLite, PostgreSQL, and MySQL
60
+
61
+ ### ๐Ÿ“– Documentation & Examples
62
+ - **Comprehensive API Documentation**: Complete filtering documentation with examples for all operators
63
+ - **Postman Collection Ready**: Detailed query parameter examples for testing
64
+ - **Error Handling Guide**: Common error scenarios and troubleshooting tips
65
+ - **Performance Guidelines**: Optimization recommendations for large datasets
66
+
67
+ ### ๐Ÿ”ง Configuration & Customization
68
+ - **Flexible Operator Configuration**: Easy addition of new filter operators via `PropelFilterOperators`
69
+ - **Customizable Field Exclusions**: Configurable lists for fields to exclude from facets
70
+ - **Template-Based Generation**: All filtering code generated via ERB templates for easy customization
71
+ - **Backward Compatibility**: Existing applications continue to work without changes
72
+
73
+ ### ๐Ÿ› Bug Fixes
74
+ - **Template Syntax Errors**: Fixed ERB template syntax issues with `next` vs `return` in select blocks
75
+ - **Scope Generation Caching**: Resolved issues with cached scopes not updating after template changes
76
+ - **Datetime Parsing Errors**: Fixed datetime scope generation to handle multiple input formats
77
+ - **SQL Compatibility**: Resolved SQLite `EXTRACT` function compatibility issues
78
+
13
79
  ## [0.3.2] - 2025-09-15
14
80
 
15
81
  ### ๐Ÿ› Critical Bug Fixes
@@ -0,0 +1,470 @@
1
+ # Propel Rails Filtering System Documentation
2
+
3
+ ## Overview
4
+
5
+ The Propel Rails filtering system provides automatic URL query string filtering and scoping using the `has_scope` gem. It supports filtering across multiple data types with various operators, making it easy to build powerful search and filter interfaces.
6
+
7
+ ## Base URL Structure
8
+
9
+ ```
10
+ GET {{base_url}}/api/v1/{resource}
11
+ ```
12
+
13
+ ## Authentication
14
+
15
+ All API requests require authentication via JWT token in the Authorization header:
16
+
17
+ ```
18
+ Authorization: Bearer <your_jwt_token>
19
+ ```
20
+
21
+ ## Data Types and Supported Operators
22
+
23
+ ### 1. String Fields
24
+
25
+ String fields support text-based filtering with multiple operators.
26
+
27
+ #### Supported Operators
28
+
29
+ | Operator | Description | Example |
30
+ |----------|-------------|---------|
31
+ | `_eq` | Exact match | `name_eq=Acme Corporation` |
32
+ | `_contains` | Contains substring | `title_contains=Project` |
33
+ | `_starts_with` | Starts with substring | `name_starts_with=Acme` |
34
+ | `_ends_with` | Ends with substring | `email_ends_with=@company.com` |
35
+ | `_in` | In list of values | `status_in=active,pending` |
36
+
37
+ #### Examples
38
+
39
+ ```bash
40
+ # Exact match
41
+ GET /api/v1/meetings?title_eq=Important Meeting
42
+
43
+ # Contains search
44
+ GET /api/v1/meetings?title_contains=Project
45
+
46
+ # Starts with
47
+ GET /api/v1/organizations?name_starts_with=Acme
48
+
49
+ # Ends with
50
+ GET /api/v1/users?email_ends_with=@company.com
51
+
52
+ # Multiple values
53
+ GET /api/v1/meetings?status_in=active,pending,cancelled
54
+ ```
55
+
56
+ ### 2. Numeric Fields (Integer, Decimal, Float)
57
+
58
+ Numeric fields support mathematical comparisons and range operations.
59
+
60
+ #### Supported Operators
61
+
62
+ | Operator | Description | Example |
63
+ |----------|-------------|---------|
64
+ | `_eq` | Equal to | `max_participants_eq=50` |
65
+ | `_gt` | Greater than | `max_participants_gt=100` |
66
+ | `_lt` | Less than | `max_participants_lt=500` |
67
+ | `_gte` | Greater than or equal | `max_participants_gte=200` |
68
+ | `_lte` | Less than or equal | `max_participants_lte=400` |
69
+ | `_min` | Alias for `_gte` | `max_participants_min=100` |
70
+ | `_max` | Alias for `_lte` | `max_participants_max=500` |
71
+ | `_range` | Between two values | `max_participants_range=150,350` |
72
+ | `_in` | In list of values | `room_id_in=1,2,3,4` |
73
+
74
+ #### Examples
75
+
76
+ ```bash
77
+ # Exact match
78
+ GET /api/v1/meetings?max_participants_eq=50
79
+
80
+ # Greater than
81
+ GET /api/v1/meetings?max_participants_gt=100
82
+
83
+ # Less than
84
+ GET /api/v1/meetings?max_participants_lt=500
85
+
86
+ # Range filtering
87
+ GET /api/v1/meetings?max_participants_range=150,350
88
+
89
+ # Multiple values
90
+ GET /api/v1/meetings?room_id_in=1,2,3
91
+
92
+ # Combined numeric filters
93
+ GET /api/v1/meetings?max_participants_gte=20&max_participants_lte=100
94
+ ```
95
+
96
+ ### 3. Boolean Fields
97
+
98
+ Boolean fields support true/false filtering with multiple value formats.
99
+
100
+ #### Supported Operators
101
+
102
+ | Operator | Description | Example |
103
+ |----------|-------------|---------|
104
+ | `_eq` | Equal to boolean value | `recording_enabled_eq=true` |
105
+
106
+ #### Supported Boolean Values
107
+
108
+ | Value | Description |
109
+ |-------|-------------|
110
+ | `true`, `false` | Standard boolean |
111
+ | `1`, `0` | Numeric boolean |
112
+ | `yes`, `no` | Text boolean |
113
+ | `on`, `off` | Toggle boolean |
114
+
115
+ #### Examples
116
+
117
+ ```bash
118
+ # Standard boolean
119
+ GET /api/v1/meetings?recording_enabled_eq=true
120
+ GET /api/v1/meetings?ai_research_enabled_eq=false
121
+
122
+ # Numeric boolean
123
+ GET /api/v1/meetings?auto_agenda_eq=1
124
+ GET /api/v1/meetings?follow_up_enabled_eq=0
125
+
126
+ # Text boolean
127
+ GET /api/v1/meetings?transcription_enabled_eq=yes
128
+ GET /api/v1/meetings?auto_presentation_eq=no
129
+ ```
130
+
131
+ ### 4. DateTime Fields
132
+
133
+ DateTime fields support temporal filtering with various operators.
134
+
135
+ #### Supported Operators
136
+
137
+ | Operator | Description | Example |
138
+ |----------|-------------|---------|
139
+ | `_before` | Before datetime | `start_time_before=2024-12-31T23:59:59Z` |
140
+ | `_after` | After datetime | `start_time_after=2024-01-01T00:00:00Z` |
141
+ | `_year` | Specific year | `start_time_year=2024` |
142
+ | `_month` | Specific month | `start_time_month=6` |
143
+ | `_day` | Specific day | `start_time_day=15` |
144
+ | `_date` | Specific date | `start_time_date=2024-06-15` |
145
+
146
+ #### Supported DateTime Formats
147
+
148
+ | Format | Example | Description |
149
+ |--------|---------|-------------|
150
+ | ISO 8601 | `2024-06-15T14:30:00Z` | Full datetime with timezone |
151
+ | Date only | `2024-06-15` | Date without time |
152
+ | Local format | `2024-06-15 14:30:00` | Local datetime format |
153
+ | Array format | `[2024, 6, 15]` | Year, month, day array |
154
+
155
+ #### Examples
156
+
157
+ ```bash
158
+ # Before specific datetime
159
+ GET /api/v1/meetings?start_time_before=2024-12-31T23:59:59Z
160
+
161
+ # After specific datetime
162
+ GET /api/v1/meetings?start_time_after=2024-01-01T00:00:00Z
163
+
164
+ # Specific year
165
+ GET /api/v1/meetings?start_time_year=2024
166
+
167
+ # Specific month
168
+ GET /api/v1/meetings?start_time_month=6
169
+
170
+ # Specific day
171
+ GET /api/v1/meetings?start_time_day=15
172
+
173
+ # Specific date
174
+ GET /api/v1/meetings?start_time_date=2024-06-15
175
+
176
+ # Expiration filtering
177
+ GET /api/v1/rooms?expiration_date_after=2024-12-31T23:59:59Z
178
+ ```
179
+
180
+ ### 5. Date Fields
181
+
182
+ Date fields support date-specific filtering (without time components).
183
+
184
+ #### Supported Operators
185
+
186
+ Same as DateTime fields, but optimized for date-only operations.
187
+
188
+ #### Examples
189
+
190
+ ```bash
191
+ # Date range
192
+ GET /api/v1/events?event_date_after=2024-01-01&event_date_before=2024-12-31
193
+
194
+ # Specific year
195
+ GET /api/v1/events?event_date_year=2024
196
+
197
+ # Specific month
198
+ GET /api/v1/events?event_date_month=6
199
+ ```
200
+
201
+ ### 6. Time Fields
202
+
203
+ Time fields support time-of-day filtering.
204
+
205
+ #### Supported Operators
206
+
207
+ Same as DateTime fields, but focused on time components.
208
+
209
+ #### Examples
210
+
211
+ ```bash
212
+ # Time range
213
+ GET /api/v1/schedules?start_time_after=09:00:00&end_time_before=17:00:00
214
+
215
+ # Specific hour
216
+ GET /api/v1/schedules?start_time_hour=14
217
+ ```
218
+
219
+ ## Sorting
220
+
221
+ All resources support sorting by any filterable field.
222
+
223
+ ### Sorting Syntax
224
+
225
+ | Format | Description | Example |
226
+ |--------|-------------|---------|
227
+ | `order_by=field` | Ascending order | `order_by=title` |
228
+ | `order_by=-field` | Descending order | `order_by=-created_at` |
229
+
230
+ ### Examples
231
+
232
+ ```bash
233
+ # Sort by title ascending
234
+ GET /api/v1/meetings?order_by=title
235
+
236
+ # Sort by start time descending
237
+ GET /api/v1/meetings?order_by=-start_time
238
+
239
+ # Sort by multiple fields (if supported)
240
+ GET /api/v1/meetings?order_by=status,start_time
241
+ ```
242
+
243
+ ## Pagination
244
+
245
+ All list endpoints support pagination parameters.
246
+
247
+ ### Pagination Parameters
248
+
249
+ | Parameter | Description | Example |
250
+ |-----------|-------------|---------|
251
+ | `page` | Page number (1-based) | `page=2` |
252
+ | `limit` | Records per page | `limit=10` |
253
+ | `per_page` | Alias for limit | `per_page=25` |
254
+
255
+ ### Examples
256
+
257
+ ```bash
258
+ # First page with 10 records
259
+ GET /api/v1/meetings?page=1&limit=10
260
+
261
+ # Second page with 25 records
262
+ GET /api/v1/meetings?page=2&per_page=25
263
+
264
+ # Large page size
265
+ GET /api/v1/meetings?limit=100
266
+ ```
267
+
268
+ ## Complex Query Examples
269
+
270
+ ### Multi-Parameter Filtering
271
+
272
+ ```bash
273
+ # Find large meetings with recording enabled, starting after June 1st
274
+ GET /api/v1/meetings?max_participants_gte=50&recording_enabled_eq=true&start_time_after=2024-06-01T00:00:00Z
275
+
276
+ # Find project meetings in 2024, sorted by start time
277
+ GET /api/v1/meetings?title_contains=Project&start_time_year=2024&order_by=start_time
278
+
279
+ # Find meetings in specific room range with pagination
280
+ GET /api/v1/meetings?room_id_range=1,5&page=1&limit=20
281
+ ```
282
+
283
+ ### Organization Filtering
284
+
285
+ ```bash
286
+ # Find organizations with names starting with "Acme"
287
+ GET /api/v1/organizations?name_starts_with=Acme
288
+
289
+ # Find organizations with specific names
290
+ GET /api/v1/organizations?name_in=Acme Corporation,Tech Corp
291
+ ```
292
+
293
+ ### Action Item Report Filtering
294
+
295
+ ```bash
296
+ # Find reports due before end of year with specific status
297
+ GET /api/v1/action_item_reports?follow_up_date_before=2024-12-31T23:59:59Z&status_in=active,pending
298
+
299
+ # Find reports from specific year and month
300
+ GET /api/v1/action_item_reports?follow_up_date_year=2024&follow_up_date_month=6
301
+ ```
302
+
303
+ ### Room Availability
304
+
305
+ ```bash
306
+ # Find available rooms with sufficient capacity
307
+ GET /api/v1/rooms?expiration_date_after=2024-12-31T23:59:59Z&max_capacity_gte=50&order_by=max_capacity
308
+ ```
309
+
310
+ ## Response Format
311
+
312
+ All filtered responses follow this structure:
313
+
314
+ ```json
315
+ {
316
+ "data": [
317
+ {
318
+ "id": 1,
319
+ "title": "Meeting Title",
320
+ "start_time": "2024-06-15T14:30:00Z",
321
+ "max_participants": 50,
322
+ "recording_enabled": true,
323
+ // ... other fields based on facet configuration
324
+ }
325
+ ],
326
+ "pagination": {
327
+ "current_page": 1,
328
+ "per_page": 10,
329
+ "total_pages": 5,
330
+ "total_count": 50,
331
+ "next_page": 2,
332
+ "prev_page": null
333
+ }
334
+ }
335
+ ```
336
+
337
+ ## Error Handling
338
+
339
+ ### Common Error Responses
340
+
341
+ #### 400 Bad Request
342
+ ```json
343
+ {
344
+ "error": "Invalid filter parameter",
345
+ "message": "Invalid datetime format for start_time_before",
346
+ "code": "INVALID_FILTER"
347
+ }
348
+ ```
349
+
350
+ #### 401 Unauthorized
351
+ ```json
352
+ {
353
+ "error": "Authentication required",
354
+ "message": "Valid JWT token must be provided",
355
+ "code": "MISSING_AUTH_TOKEN"
356
+ }
357
+ ```
358
+
359
+ #### 403 Forbidden
360
+ ```json
361
+ {
362
+ "error": "Organization context required",
363
+ "message": "Valid organization_id must be provided in JWT token",
364
+ "code": "MISSING_ORGANIZATION_CONTEXT"
365
+ }
366
+ ```
367
+
368
+ ## Testing Tips
369
+
370
+ ### 1. Start Simple
371
+ Begin with single parameter tests to verify basic functionality.
372
+
373
+ ### 2. Combine Gradually
374
+ Add multiple parameters to test complex filtering scenarios.
375
+
376
+ ### 3. Test Edge Cases
377
+ - Invalid dates: `start_time_before=invalid-date`
378
+ - Empty strings: `title_eq=`
379
+ - Special characters: `title_contains=Project%20Meeting`
380
+ - Large numbers: `max_participants_gt=999999`
381
+
382
+ ### 4. Verify Sorting
383
+ Test both ascending and descending order for each sortable field.
384
+
385
+ ### 5. Check Pagination
386
+ Test different page sizes and verify pagination metadata.
387
+
388
+ ### 6. Test Boolean Variations
389
+ Try different boolean value formats: `true`, `1`, `yes`, `on`
390
+
391
+ ## Performance Considerations
392
+
393
+ ### 1. Use Indexed Fields
394
+ Filtering on indexed fields (like `id`, `organization_id`) is faster than unindexed fields.
395
+
396
+ ### 2. Limit Result Sets
397
+ Use pagination to limit large result sets and improve response times.
398
+
399
+ ### 3. Combine Filters Efficiently
400
+ Multiple filters are combined with AND logic, so more specific filters reduce the result set faster.
401
+
402
+ ### 4. Avoid Wildcard Searches
403
+ `_contains` operations are slower than exact matches (`_eq`) or prefix matches (`_starts_with`).
404
+
405
+ ## Security Notes
406
+
407
+ ### 1. Input Validation
408
+ All filter parameters are validated against allowed field names and operators.
409
+
410
+ ### 2. SQL Injection Protection
411
+ All parameters are properly escaped and parameterized to prevent SQL injection.
412
+
413
+ ### 3. Multi-tenancy
414
+ All queries are automatically scoped to the user's organization context.
415
+
416
+ ### 4. Sensitive Field Filtering
417
+ Sensitive fields (passwords, tokens, etc.) are automatically excluded from filtering.
418
+
419
+ ## Troubleshooting
420
+
421
+ ### Common Issues
422
+
423
+ #### No Results Returned
424
+ - Check if the field name is correct
425
+ - Verify the operator is supported for that field type
426
+ - Ensure the value format matches the expected type
427
+
428
+ #### Invalid Filter Error
429
+ - Verify the field name exists on the model
430
+ - Check that the operator is supported for the field type
431
+ - Ensure the value can be parsed correctly
432
+
433
+ #### Authentication Errors
434
+ - Verify the JWT token is valid and not expired
435
+ - Check that the organization context is properly set
436
+ - Ensure the user has access to the requested resource
437
+
438
+ #### Performance Issues
439
+ - Use more specific filters to reduce result sets
440
+ - Add database indexes for frequently filtered fields
441
+ - Consider using pagination for large datasets
442
+
443
+ ## API Endpoints
444
+
445
+ ### Available Resources
446
+
447
+ | Resource | Endpoint | Description |
448
+ |----------|----------|-------------|
449
+ | Meetings | `/api/v1/meetings` | Meeting management |
450
+ | Organizations | `/api/v1/organizations` | Organization data |
451
+ | Users | `/api/v1/users` | User management |
452
+ | Rooms | `/api/v1/rooms` | Room management |
453
+ | Action Item Reports | `/api/v1/action_item_reports` | Action item tracking |
454
+ | Meeting Links | `/api/v1/meeting_links` | Meeting link management |
455
+ | Dossiers | `/api/v1/dossiers` | Document management |
456
+
457
+ ### Field Reference
458
+
459
+ Each resource has different available fields for filtering. Check the individual resource documentation for the complete list of filterable fields.
460
+
461
+ ## Changelog
462
+
463
+ ### Version 0.3.2
464
+ - Added comprehensive datetime filtering support
465
+ - Implemented database-agnostic datetime parsing
466
+ - Added boolean field filtering with multiple value formats
467
+ - Enhanced string filtering with pattern matching
468
+ - Added range filtering for numeric fields
469
+ - Implemented multi-tenancy filtering
470
+ - Added comprehensive error handling and validation
data/README.md CHANGED
@@ -1,6 +1,51 @@
1
1
  # PropelApi
2
2
 
3
- A comprehensive Rails generator that creates complete API resources with models, controllers, tests, and realistic seed data. Supports both PropelFacets (JSON Facet) and Graphiti serialization engines with **fixed route insertion** and proper indentation.
3
+ A comprehensive Rails generator that creates complete API resources with models, controllers, tests, and realistic seed data. Supports both PropelFacets (JSON Facet) and Graphiti serialization engines with **fixed route insertion**, proper indentation, and **comprehensive dynamic filtering system**.
4
+
5
+ ## ๐ŸŽ‰ NEW in v0.3.3: Dynamic Filtering System
6
+
7
+ PropelApi now includes a complete automatic URL query string filtering and scoping system using the `has_scope` gem. This provides powerful, database-agnostic filtering across all data types with zero configuration required.
8
+
9
+ ### Quick Filtering Examples
10
+
11
+ ```bash
12
+ # String filtering
13
+ GET /api/v1/meetings?title_contains=Project&status_in=active,pending
14
+
15
+ # Numeric filtering
16
+ GET /api/v1/meetings?max_participants_gte=50&max_participants_lte=200
17
+
18
+ # Boolean filtering
19
+ GET /api/v1/meetings?recording_enabled_eq=true&ai_research_enabled_eq=false
20
+
21
+ # DateTime filtering
22
+ GET /api/v1/meetings?start_time_after=2024-01-01T00:00:00Z&start_time_before=2024-12-31T23:59:59Z
23
+
24
+ # Range filtering
25
+ GET /api/v1/meetings?max_participants_range=150,350
26
+
27
+ # Combined filtering with sorting and pagination
28
+ GET /api/v1/meetings?title_contains=Project&max_participants_gte=50&order_by=start_time&page=1&limit=20
29
+ ```
30
+
31
+ ### Supported Filter Operators
32
+
33
+ | Data Type | Operators | Examples |
34
+ |-----------|-----------|----------|
35
+ | **String** | `_eq`, `_contains`, `_starts_with`, `_ends_with`, `_in` | `name_eq=Acme`, `title_contains=Project` |
36
+ | **Numeric** | `_eq`, `_gt`, `_lt`, `_gte`, `_lte`, `_range`, `_in` | `max_participants_gte=50`, `price_range=100,500` |
37
+ | **Boolean** | `_eq` (supports `true`/`false`, `1`/`0`, `yes`/`no`, `on`/`off`) | `recording_enabled_eq=true` |
38
+ | **DateTime** | `_before`, `_after`, `_year`, `_month`, `_day`, `_date` | `start_time_after=2024-01-01`, `created_at_year=2024` |
39
+ | **Date** | Same as DateTime | `event_date_after=2024-01-01` |
40
+ | **Time** | Same as DateTime | `start_time_hour=14` |
41
+
42
+ ### Automatic Features
43
+
44
+ - **Zero Configuration**: Filtering works automatically for all generated resources
45
+ - **Database Agnostic**: Works with SQLite, PostgreSQL, and MySQL
46
+ - **Security Built-in**: SQL injection protection and input validation
47
+ - **Multi-tenancy Ready**: Automatic organization scoping
48
+ - **Performance Optimized**: Efficient queries with proper indexing support
4
49
 
5
50
  ## Installation
6
51