| name | Knack Filter Sort |
| description | Dynamic filtering, sorting, and query optimization for HTI dashboards and compliance reports. Reduces API payload size and improves dashboard perfo... |
| allowed-tools | Read, Edit |
Knack Filter Sort
Purpose
Dynamic filtering, sorting, and query optimization for HTI dashboards and compliance reports. Reduces API payload size and improves dashboard performance.
Filter Syntax
Basic Structure
{
"match": "and",
"rules": [
{
"field": "field_123",
"operator": "is",
"value": "Ready for Donation"
}
]
}
Multiple Conditions
{
"match": "and",
"rules": [
{
"field": "field_status",
"operator": "is",
"value": "Ready"
},
{
"field": "field_county",
"operator": "is",
"value": "Wake"
}
]
}
Operators
Text Fields
is- Exact matchis not- Exclusioncontains- Substring matchstarts with- Prefix matchends with- Suffix match
Number Fields
is- Equal tois not- Not equal>- Greater than<- Less than>=- Greater than or equal<=- Less than or equal
Date Fields
is- Specific dateis before- Earlier thanis after- Later thanis during- Date rangeis todayis this weekis this monthis this year
Boolean Fields
is- True/False
Core Functions
build_filter
Purpose: Construct Knack-compatible filter objects
Example:
const filter = build_filter({
match: "and",
rules: [
{ field: "field_5", operator: "is", value: "Converted" },
{ field: "field_12", operator: "is after", value: "2025-01-01" }
]
});
apply_sort
Purpose: Sort results by field and direction
Parameters:
sort_field(string): Field identifier (e.g., "field_7")sort_order(string): "asc" or "desc"
Example:
const sort = apply_sort({
sort_field: "field_acquisition_date",
sort_order: "desc"
});
combine_filters
Purpose: Merge multiple filter sets (AND/OR logic)
Example:
const combined = combine_filters({
operator: "or",
filters: [wake_filter, durham_filter, vance_filter]
});
HTI-Specific Filters
Grant Reporting Filters
Acquired This Quarter
const q1_acquired = build_filter({
match: "and",
rules: [
{
field: "field_acquisition_date",
operator: "is during",
range: { start: "2025-01-01", end: "2025-03-31" }
}
]
});
Ready for Donation
const ready_devices = build_filter({
match: "and",
rules: [
{ field: "field_status", operator: "is", value: "Ready for Donation" },
{ field: "field_tested", operator: "is", value: true }
]
});
By County (15-County Coverage)
const wake_county = build_filter({
match: "and",
rules: [
{ field: "field_target_county", operator: "is", value: "Wake" }
]
});
Recurring Donors (2026 Goal: 6+ with 50+ laptops)
const recurring_donors = build_filter({
match: "and",
rules: [
{ field: "field_donation_count", operator: ">=", value: 3 },
{ field: "field_total_laptops", operator: ">=", value: 50 }
]
});
Training Sessions (156+ Hours Goal)
const training_hours = build_filter({
match: "and",
rules: [
{ field: "field_session_date", operator: "is this year", value: "2025" },
{ field: "field_session_status", operator: "is", value: "Completed" }
]
});
Dashboard Filters
Devices Needing Action
const needs_action = build_filter({
match: "or",
rules: [
{ field: "field_status", operator: "is", value: "Acquired - Needs Testing" },
{ field: "field_status", operator: "is", value: "Failed Testing" },
{ field: "field_status", operator: "is", value: "Awaiting Parts" }
]
});
High-Value Donors (>$500)
const major_donors = build_filter({
match: "and",
rules: [
{ field: "field_donation_value", operator: ">", value: 500 }
]
});
Sort Configurations
Common Sorts
Most Recent First
apply_sort({
sort_field: "field_acquisition_date",
sort_order: "desc"
});
Alphabetical by County
apply_sort({
sort_field: "field_county",
sort_order: "asc"
});
Highest Donation Value
apply_sort({
sort_field: "field_donation_value",
sort_order: "desc"
});
Query Optimization
Best Practices
- Filter at API level (not client-side) to reduce payload
- Use indexed fields for faster queries
- Combine filters rather than chaining requests
- Cache filtered results for repeated dashboard loads
Performance Comparison
// ❌ BAD: Fetch all, filter client-side
const all = await get_records("object_1"); // 3,500+ records
const ready = all.filter(d => d.status === "Ready"); // Slow, wasteful
// ✅ GOOD: Filter at API level
const ready = await get_records("object_1", {
filters: build_filter({
rules: [{ field: "field_status", operator: "is", value: "Ready" }]
})
}); // Only returns ~200 records
Integration with Pagination
// Filter + paginate for large result sets
const all_wake_devices = await fetch_all_pages("object_1", {
filters: build_filter({
rules: [{ field: "field_county", operator: "is", value: "Wake" }]
}),
sort: apply_sort({ sort_field: "field_date", sort_order: "desc" })
});
Error Handling
try {
const filtered = await get_records("object_1", { filters: my_filter });
} catch (error) {
if (error.message.includes("invalid field")) {
console.error("Filter references non-existent field");
}
}
Integration Points
- knack_reader: Apply filters to get_records calls
- knack_pagination: Consistent filters across paginated requests
- knack_dashboard_ai: Dynamic filter generation based on user input
- knack_reporting_sync: Quarterly report filtering (dates, counties, statuses)
- knack_goal_tracker: Filter by goal-relevant criteria
NCDIT Compliance
- Filter by reporting period (quarterly)
- Exclude test/dummy records
- Include only grant-funded devices
- Separate operational vs. financial data