Skip to Content
Deals Pipeline — Engineering Deep Dive

Deals Pipeline — Engineering Deep Dive

How deals flow from Dutchie POS and Odoo PTL through Redis to the frontend. Covers deal sources, sync pipeline, discount matching, and customer-facing pages.

Responsible Juan Palomino
Last Update 04/06/2026
Completion Time 1 day 16 hours
Members 1
Deals Pipeline — Engineering Deep Dive

4-Tier Discount Matching Algorithm

5. Key Gotchas
View all
New Content
Deals Pipeline — Engineering Deep Dive
4-Tier Discount Matching Algorithm
New Content
Deals Pipeline — Engineering Deep Dive
Dutchie to Redis Sync Pipeline

10-Minute BullMQ Sync Cycle

The inventory sync runs every 10 minutes on the mintinvsvc Railway service as a BullMQ repeating job with 6 phases:

  1. Phase 1: Inventory Sync — Fetches product inventory from Dutchie Backoffice API per store
  2. Phase 2: Product Enrichment — Adds Odoo images and metadata to products
  3. Phase 3: Discount Sync — Fetches discounts from Dutchie POS/Backoffice API
  4. Phase 3b: Odoo Discount Sync — (conditional) Pushes discounts to Odoo mint.discount records
  5. Phase 4: Cache Refresh — Writes PostgreSQL data to Redis
  6. Phase 5: Odoo Sync — Pushes inventory data back to Odoo (if enabled)

Phase 3 Detail: Discount Sync

Two API strategies tried in order:

  1. POS API (primary): GET api.pos.dutchie.com/discounts/v2/list with per-LSP Basic auth key (env var: DUTCHIE_POS_API_KEY_{lspId}). Used for AZ stores.
  2. Backoffice API (fallback): POST v2/discount/get-discount via authenticated Backoffice session. Used for FL, IL, MI, MO, NV stores where POS API keys are not configured.

Code: packages/inventory-service/services/discountSync.js lines 411-436

Data Flow

Dutchie POS/Backoffice API
      |
      v
  PostgreSQL (discounts table)
  - Composite PK: {locationUUID}_{discountId}
  - JSONB fields: products, brands, product_categories
  - Day-of-week booleans: monday..sunday
  - source column: dutchie or ptl
      |
      v  (Phase 4: cacheSync.js)
  Redis Cache
  - Key: discounts:{locationUUID}
  - Value: JSON array of all active discounts
      |
      v  (HTTP GET /api/locations/:id/discounts)
  Frontend (Cloudflare Pages)

Infrastructure

  • Service: mintinvsvc on Railway (Nixpacks, Node 20)
  • Domain: mintinvsvc-production-6aa5.up.railway.app
  • Redis: Railway Redis at nozomi.proxy.rlwy.net:18208
  • PostgreSQL: Railway Postgres at mainline.proxy.rlwy.net:40686
  • Job System: BullMQ with concurrency=1 (prevents overlapping)

Key Code References

  • Job schedule: packages/inventory-service/jobs/queues.js:100
  • Job processor: packages/inventory-service/jobs/processors/inventorySync.js:50-142
  • Discount sync: packages/inventory-service/services/discountSync.js:398-485
  • Cache refresh: packages/inventory-service/services/cacheSync.js:10-44
New Content
Deals Pipeline — Engineering Deep Dive
Dutchie POS Backoffice (Primary Source)