5 min read
Architecture Overview
Technical architecture of FilterIQ for developers.
Architecture Overview
This page describes the technical architecture of FilterIQ for developers who want to understand how the system works, build custom integrations, or troubleshoot issues.
System Diagram
┌──────────────────────────────────────────────────────────────┐
│ SHOPIFY STOREFRONT │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Theme App Extension (JavaScript + Liquid) │ │
│ │ ├── Search Widget (autocomplete, results rendering) │ │
│ │ ├── Filter Sidebar (faceted filtering UI) │ │
│ │ └── Event Tracking (clicks, impressions, conversions) │ │
│ └──────────────────┬─────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────▼─────────────────────────────────────┐ │
│ │ Shopify App Proxy (/apps/search-filter/*) │ │
│ └──────────────────┬─────────────────────────────────────┘ │
└─────────────────────┼────────────────────────────────────────┘
│ HTTPS
┌─────────────────────▼────────────────────────────────────────┐
│ BACKEND API SERVER │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ Search API │ │ Config API │ │ Analytics API │ │
│ │ /api/search │ │ /api/config │ │ /api/analytics │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────────┘ │
│ │ │ │ │
│ ┌──────▼──────────────────▼──────────────────▼───────────┐ │
│ │ Service Layer │ │
│ │ ├── Search Service (query processing, ranking) │ │
│ │ ├── Filter Service (facet configuration) │ │
│ │ ├── Merchandising Service (boost/bury/pin/hide rules) │ │
│ │ ├── Sync Service (Shopify → search engine indexing) │ │
│ │ └── Analytics Service (event aggregation, reporting) │ │
│ └──────┬───────────────────┬─────────────────┬───────────┘ │
│ │ │ │ │
│ ┌──────▼───────┐ ┌───────▼──────┐ ┌───────▼───────────┐ │
│ │ Search │ │ Database │ │ Cache │ │
│ │ Engine │ │ (PostgreSQL) │ │ Layer │ │
│ └──────────────┘ └──────────────┘ └────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ SHOPIFY ADMIN │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Embedded Admin App (React Router) │ │
│ │ ├── Dashboard (overview, sync status) │ │
│ │ ├── Search Config (attributes, synonyms, autocomplete) │ │
│ │ ├── Filter Config (filter types, ordering, presets) │ │
│ │ ├── Merchandising (pin, boost, demote, hide, rules) │ │
│ │ └── Analytics (search reports, filter reports) │ │
│ └──────────────────┬─────────────────────────────────────┘ │
│ │ Authenticated API calls │
│ └─────────────────────────────────────────┘
└──────────────────────────────────────────────────────────────┘
Technology Stack
| Layer | Technology | Purpose |
|---|---|---|
| Storefront | Liquid + JavaScript (Theme App Extension) | Search UI, filter UI, event tracking |
| Admin | React Router 7, Polaris, TypeScript | Admin dashboard |
| API Gateway | Shopify App Proxy | Secure routing from storefront to backend |
| Backend | Python, Pydantic | Business logic, API endpoints |
| Search Engine | Dedicated search engine | Full-text search, faceted filtering |
| Database | PostgreSQL | Configuration, analytics, user data |
| Cache | In-memory cache | Search cache, session data, rate limiting |
| Frontend Hosting | Cloud hosting | Admin app hosting |
| Backend Hosting | Cloud hosting | API hosting |
Multi-Tenant Architecture
FilterIQ is a multi-tenant application. Every data operation is scoped to a shop_domain:
- Database: All queries include a
shop_domainfilter. Row-Level Security (RLS) policies enforce tenant isolation at the database level - Search Engine: Each shop gets its own search index (named by shop domain)
- Cache: Cache keys are prefixed with shop domain
- API: Shop identity is extracted from verified JWT tokens, never from client-provided data
Authentication Flow
1. Merchant installs app → Shopify OAuth flow
2. Shopify provides access token → stored in the database
3. Admin requests use Shopify session tokens (JWT)
4. Storefront requests go through App Proxy (Shopify verifies authenticity)
5. Backend validates JWT on every request → extracts shop_domain
Security rule: The backend never trusts client-provided shop_domain. It's always extracted from the verified session token.
Data Flow: Product Indexing
Shopify Product Webhook (create/update/delete)
↓
Backend Webhook Handler
↓
Validation + shop_domain extraction
↓
Product data transformation (Shopify format → search document)
↓
Search index update (add/update/delete document)
↓
Search results reflect change (< 1 second)
Data Flow: Search Query
Shopper types in search bar
↓
Theme Extension JavaScript debounces input (150ms)
↓
Request to /apps/search-filter/api/search?q=...
↓
Shopify App Proxy forwards to backend
↓
Backend: validate request, check cache
↓ (cache miss)
Backend: apply merchandising rules to query
↓
Search engine: execute search with filters and facets
↓
Backend: format results, cache response
↓
Response to storefront (< 50ms total)
↓
Theme Extension renders results
API Endpoints
Storefront API (via App Proxy)
| Endpoint | Method | Purpose |
|---|---|---|
/apps/search-filter/api/search | GET | Execute search query |
/apps/search-filter/api/autocomplete | GET | Autocomplete suggestions |
/apps/search-filter/api/filters | GET | Get filter configuration |
/apps/search-filter/api/track | POST | Track analytics event |
Admin API (authenticated)
| Endpoint | Method | Purpose |
|---|---|---|
/api/config/search | GET, PUT | Search configuration |
/api/config/filters | GET, PUT | Filter configuration |
/api/config/merchandising | GET, PUT | Merchandising rules |
/api/config/synonyms | GET, PUT, DELETE | Synonym management |
/api/analytics/* | GET | Analytics reports |
/api/sync/status | GET | Product sync status |
Performance Characteristics
| Metric | Target | Typical |
|---|---|---|
| Search query response | < 50ms | 20-40ms |
| Autocomplete response | < 30ms | 10-25ms |
| Product index update | < 1s | 200-500ms |
| Theme Extension JS size | < 30KB gzipped | ~25KB |
| Theme Extension CSS size | < 5KB gzipped | ~3KB |
| Endpoint | Limit |
|---|---|
| Search API | 100 requests/second per shop |
| Autocomplete API | 200 requests/second per shop |
| Analytics tracking | 50 requests/second per shop |
| Admin API | 20 requests/second per shop |
Rate limits are enforced per-shop. Exceeding limits returns HTTP 429.
Was this page helpful?
Related documentation
DeveloperJavaScript APIConfirm JavaScript integration availability and use the supported Theme App Extension.DeveloperREST API ReferencePublic API availability and authentication boundaries for custom FilterIQ integrations.DeveloperEvent TrackingHow analytics events are tracked on the storefront and how to integrate with custom analytics.