Skip to main content
Preview availability
Menu
Type to search across all documentation
↑↓NavigateEnterOpenEscClose
6 min read

Architecture Overview

Technical architecture of FilterIQ for developers.

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

LayerTechnologyPurpose
StorefrontLiquid + JavaScript (Theme App Extension)Search UI, filter UI, event tracking
AdminReact Router 7, Polaris, TypeScriptAdmin dashboard
API GatewayShopify App ProxySecure routing from storefront to backend
BackendPython, PydanticBusiness logic, API endpoints
Search EngineDedicated search engineFull-text search, faceted filtering
DatabasePostgreSQLConfiguration, analytics, user data
CacheIn-memory cacheSearch cache, session data, rate limiting
Frontend HostingCloud hostingAdmin app hosting
Backend HostingCloud hostingAPI hosting

Multi-Tenant Architecture

FilterIQ is a multi-tenant application. Shop identity is the isolation boundary; the following describes the intended shop-scoped design, not a claim of dedicated infrastructure:

  • Database: All queries include a shop_domain filter. 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: Authentication depends on the entry point: Shopify session JWT, verified app-proxy HMAC, verified webhook signature or authenticated internal service context. An unsigned shop identifier does not establish identity.

Separate product indexes do not mean separate servers or clusters. Confirm deployment-specific isolation evidence for your security review.

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; the signed request must be verified
5. The receiving service validates its supported authentication context
6. Webhooks have a separate signature-verification path

Security rule: Use the verified context for the relevant entry point. Do not treat an unsigned shop_domain parameter as authentication.

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 the completed index update; verify sync state

Data Flow: Search Query

Shopper types in search bar
    ↓
Theme Extension JavaScript applies its configured input handling
    ↓
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 returns to the storefront; network and rendering time still apply
    ↓
Theme Extension renders results

API Endpoints

Storefront API (via App Proxy)

EndpointMethodPurpose
/apps/search-filter/api/searchGETExecute search query
/apps/search-filter/api/autocompleteGETAutocomplete suggestions
/apps/search-filter/api/filtersGETGet filter configuration
/apps/search-filter/api/trackPOSTTrack analytics event

Admin API (authenticated)

EndpointMethodPurpose
/api/config/searchGET, PUTSearch configuration
/api/config/filtersGET, PUTFilter configuration
/api/config/merchandisingGET, PUTMerchandising rules
/api/config/synonymsGET, PUT, DELETESynonym management
/api/analytics/*GETAnalytics reports
/api/sync/statusGETProduct sync status

Performance Characteristics

No repeatable benchmark artifact is linked for the earlier typical timings or bundle-size figures. Those figures are not established production measurements and should not be used as buying guarantees.

Measure distinct intervals separately:

IntervalWhat it establishesWhat it excludes
Search-engine processingWork inside the search engine for a specified queryProxy, network, browser and rendering
HTTP round tripRequest through the measured endpoint to responseInput handling and rendering after receipt
Input-to-visible resultsShopper input through visible settled resultsOther themes, devices or catalogues not tested
Index freshnessSource update through verified searchable outputA guarantee for every webhook or sync

Record the release, device, location, catalogue, query/filter set, concurrency, cold/warm cache state and sample count. Include errors and tail latency, not only the fastest response. Measure transferred assets from the actual published theme; a source-file size is not the page's total network cost.

Interface and Request Limits

The endpoint names above describe internal architecture, not a generally available public API. See the REST API boundary before building an integration. Confirm actual paths, authentication and versioning with the team.

Request limits depend on the route, configuration and environment. A rate-limit response must be handled as a limit, not an empty result. Use the supported client path and bounded retries; do not infer a throughput entitlement from this architecture guide. See the performance guide for a storefront measurement checklist.

Was this page helpful?