The app is a Shopify embedded app on React Router 7 with Polaris, Postgres with pgvector, and a Redis-backed BullMQ worker. The storefront side is a theme app embed: a framework-free web component in a Shadow DOM that talks to the app only through the HMAC-signed Shopify App Proxy. The AI engine is the Google Gemini API.
Key design decisions
- Order lookup as authentication. An order is shown only to the signed-in customer who owns it (the App Proxy's signed
logged_in_customer_id) or to a guest whose order number and checkout email both match. Emails are compared in constant time, and an unknown order and a wrong email return the same generic message.
- Layered rate limits. Lookups are limited per session (5 per 15 minutes), per hashed IP (15 per hour) and per order number across sessions (8 per hour). Chat itself is limited per IP and per session, and a conversation bound to one customer can't be continued by another on the same browser.
- Retrieval that can refuse. Policies, pages and merchant-added URLs on the shop's own domain are chunked and embedded with
gemini-embedding-001 at 768 dimensions into pgvector, behind a halfvec HNSW expression index. If no passage clears the similarity threshold, the assistant says it doesn't know without calling the model. If passages do clear it, a structured-output answer can still decline, and the answers it gives cite their sources.
- Structured order cards. The model writes one or two sentences from a short factual summary. Items, tracking links and shipment history are rendered from Shopify data, not generated text.
- Hand-off with context. Refund disputes, requests for a person, very negative sentiment and repeated misses create a ticket by email, in Zendesk or in Gorgias with the transcript attached. Failed deliveries are retried by the worker, and helpdesk credentials are encrypted at rest with AES-256-GCM.
- Privacy by default. Order objects are fetched live and not stored, emails typed into forms are stored masked, and IPs are used only as hashed rate-limit keys. GDPR
customers/data_request, customers/redact and shop/redact handlers export or delete every linked conversation.
Architecture
App Proxy routes (/apps/concierge/config, /history, /chat) verify the signature and pass to one chat orchestrator. It applies rate limits and the plan's conversation limit, then classifies intent and sentiment with a keyword fallback and routes to the verified order lookup, the knowledge-base answer or the hand-off. Admin API 2026-10 has no webhook topics for pages or policies, so the worker runs a daily staggered re-ingest per shop, and merchants can also sync on demand. The admin offers a dashboard, searchable transcripts, knowledge-base management with a test question box, widget branding with a live preview, and business hours.