🎯 Quick Reference: Filter Patterns for AI Agents
Last Updated: 2025-10-15
Confidence: 95%+ (Multi-model validated)
✅ THE ONE TRUE WAY
Use This Pattern (PRIMARY)
const endpoint = create('list_users', 'GET')
.input('status', 'text', { required: false })
.input('page', 'int', { default: 1 })
.input('per_page', 'int', { default: 20 })
.dbQuery('users', {
filters: { status: '$input.status' }, // Auto ==? operator
page: '$input.page', // FLAT pagination
per_page: '$input.per_page',
totals: true // For itemsTotal
}, 'result')
.response({
data: '$result.items',
page: '$result.curPage', // NOT currentPage!
total: '$result.itemsReceived' // NOT itemsTotal!
});
return endpoint.build().script;
📋 Quick Decision Tree
Need to filter data?
│
├─ Simple equality + all values dynamic ($input.field)?
│ → Use OBJECT FILTERS
│
├─ Have static values or comparisons (>, <)?
│ → Use SEARCH STRING
│
└─ Complex AND/OR logic?
→ Use SEARCH STRING
❌ Common Mistakes
// ❌ WRONG: Static values in filters
filters: { status: 'active' } // ERROR!
// ✅ RIGHT: Use search string
search: '$db.users.status == "active"'
// ❌ WRONG: Nested pagination
pagination: { page: '$input.page' } // Warning
// ✅ RIGHT: Flat pagination
page: '$input.page'
// ❌ WRONG: Response field typos
page: '$result.currentPage' // Should be curPage
total: '$result.itemsTotal' // Need totals: true
// ✅ RIGHT: Correct field names
page: '$result.curPage'
total: '$result.itemsReceived' // Always available
🔧 When to Use Search Strings
// Complex conditions
search: '$db.products.price >= $input.min && $db.products.price <= $input.max'
// Comparisons
search: '$db.users.age > 18'
// Static values
search: '$db.users.status == "active"'
// Mixed static + dynamic
search: '$db.products.price >= $input.min_price && $db.products.category == "electronics"'
🎯 Pagination Best Practices
// ✅ RECOMMENDED: Always include pagination
.input('page', 'int', { default: 1 })
.input('per_page', 'int', { default: 20 })
.dbQuery('table', {
filters: { /* ... */ },
page: '$input.page', // Flat structure
per_page: '$input.per_page',
totals: true // Optional: for itemsTotal
}, 'result')
// Response fields available:
// - $result.items (array of records)
// - $result.curPage (current page number)
// - $result.itemsReceived (count on current page - ALWAYS available)
// - $result.itemsTotal (total count - ONLY with totals: true)
// - $result.pageTotal (total pages - ONLY with totals: true)
🚨 Critical Notes
- Object Filters: ONLY for dynamic values (
$input.*,$auth.*) - Search Strings: For static values, comparisons, complex logic
- Flat Pagination: NEVER nest under
pagination: {} - totals: true: Required for
itemsTotalandpageTotal - itemsReceived: ALWAYS available, no flag needed
📚 Complete Investigation
See FILTER_PATTERN_INVESTIGATION_FINDINGS.md for:
- Full multi-model analysis
- Feature flag documentation
- Auto-fix status
- Code flow diagrams
- Phase 2 normalizer details