Multi-Brand Shopify Integration with Inventory Management
Database: Nova_StaX_DB | Documentation for Justin & Development Team
Single database managing products for 8+ brands, each with dedicated Shopify stores.
Real-time synchronization between local database and Shopify stores (create, update, delete).
Multi-location inventory tracking with automated reorder points and low-stock alerts.
Complete CRUD operations for products, variants, inventory, and analytics.
Shopify webhooks for order events, product updates, and inventory changes.
Azure SQL Database, Blob Storage for images, Key Vault for secrets.
| Component | Technology | Purpose |
|---|---|---|
| Backend API | Flask (Python) | RESTful API endpoints for product operations |
| Database | Azure SQL (Nova_StaX_DB) | Centralized product catalog and inventory |
| E-commerce Platform | Shopify (8 stores) | Online storefronts for each brand |
| Image Storage | Azure Blob Storage | Product images with CDN delivery |
| Secrets Management | Azure Key Vault | Shopify API tokens, database connection strings |
| Authentication | Azure AD (Tenant-only) | Secure product management access |
| Frontend | HTML/JavaScript | Product SKU Entry interface |
| Table Name | Purpose | Key Fields |
|---|---|---|
Brands |
Brand definitions | BrandID, BrandName, BrandCode, ShopifyStoreURL, ShopifyAccessToken |
Categories |
Hierarchical product categories | CategoryID, CategoryName, ParentCategoryID, DisplayOrder |
Products |
Master product catalog | ProductID, SKU, ProductName, BasePrice, ShopifyProductID, IsShopifySync |
ProductVariants |
Product variations (size/color) | VariantID, VariantSKU, Size, Color, Price, ShopifyVariantID |
ProductImages |
Product images (Azure Blob URLs) | ImageID, ProductID, ImageURL, IsPrimary, DisplayOrder |
InventoryLocations |
Warehouse/fulfillment centers | LocationID, LocationName, LocationCode, LocationType |
Inventory |
Multi-location stock levels | InventoryID, VariantID, LocationID, QuantityAvailable, ReorderPoint |
ShopifySyncLog |
Audit trail for Shopify operations | LogID, ProductID, SyncType, SyncStatus, ErrorMessage, SyncedAt |
ProductPricingHistory |
Price change tracking | HistoryID, ProductID, OldPrice, NewPrice, ChangedAt |
| View Name | Purpose |
|---|---|
vw_ProductCatalog |
Denormalized product data (products + brands + categories + primary images) |
vw_InventoryStatus |
Current inventory levels across all locations |
vw_LowStockAlerts |
Products below reorder point (automated alerts) |
| Procedure | Purpose | Parameters |
|---|---|---|
sp_AdjustInventory |
Safely adjust inventory quantities | @VariantID, @LocationID, @Adjustment, @UpdatedBy, @Reason |
sp_CreateProductWithVariant |
Create product + default variant atomically | @SKU, @ProductName, @BrandID, @CategoryID, @BasePrice, @CreatedBy |
Brands (1) → (M) Products
Categories (1) → (M) Products (hierarchical, self-referencing)
Products (1) → (M) ProductVariants
Products (1) → (M) ProductImages
ProductVariants (1) → (M) Inventory
InventoryLocations (1) → (M) Inventory
Products (1) → (M) ShopifySyncLog
Products (1) → (M) ProductPricingHistory
apps/production_ready/drantechai_developer_flaskapp/database/schemas/product_catalog_schema.sqlEach brand has a dedicated Shopify store with unique credentials. Products are filtered by BrandID
to ensure proper routing.
| Brand | Code | Shopify Store | Primary Products | Status |
|---|---|---|---|---|
| CellJourney | CJ |
celljourney.myshopify.com | Supplements, wellness products | Active |
| EnableYou | EY |
enableyou.myshopify.com | AI services, QSpective products | Active |
| QSpective | QS |
qspective.myshopify.com | Business intelligence tools | Active |
| Nova_X | NX |
novax.myshopify.com | Astrology, wellness tech | Active |
| LuckyFig | LF |
luckyfig.myshopify.com | Lifestyle products | Active |
| SarcasticMushroom | SM |
sarcasticmushroom.myshopify.com | Novelty items | Active |
| 5WhyGlobal | 5W |
5whyglobal.myshopify.com | Consulting services | Pending |
| DranTech.ai | DT |
drantech.myshopify.com | Enterprise AI solutions | Active |
# CellJourney Example
SHOPIFY_CJ_ACCESS_TOKEN=shpat_xxxxxxxxxxxxxxxxxxxxx
SHOPIFY_CJ_STORE_URL=celljourney.myshopify.com
SHOPIFY_CJ_LOCATION_ID=12345678901 # Primary fulfillment location ID
# Repeat for each brand:
SHOPIFY_EY_ACCESS_TOKEN=...
SHOPIFY_QS_ACCESS_TOKEN=...
SHOPIFY_NX_ACCESS_TOKEN=...
SHOPIFY_LF_ACCESS_TOKEN=...
SHOPIFY_SM_ACCESS_TOKEN=...
SHOPIFY_5W_ACCESS_TOKEN=...
SHOPIFY_DT_ACCESS_TOKEN=...
Base URL: https://www.drantech.ai/api/products
Authentication: Azure AD tenant authentication required (Authorization header with JWT token)
List all products with optional filters.
| Parameter | Type | Description |
|---|---|---|
brandId |
int (optional) | Filter by brand |
categoryId |
int (optional) | Filter by category |
isActive |
bool (default: true) | Filter by active status |
shopifySync |
bool (optional) | Filter by Shopify sync status |
page |
int (default: 1) | Page number |
pageSize |
int (default: 50, max: 200) | Results per page |
GET /api/products?brandId=1&categoryId=5&page=1&pageSize=20
Response:
{
"products": [
{
"productId": 1,
"sku": "CJ-SUP-1732022400",
"name": "CellOptimize Pro",
"basePrice": 49.99,
"brand": "CellJourney",
"category": "Supplements",
"shopifySync": true,
"shopifyProductId": 7891234567890,
"variantCount": 3,
"primaryImageUrl": "https://..."
}
],
"total": 45,
"page": 1,
"pageSize": 20,
"totalPages": 3
}
Create new product with optional Shopify sync.
POST /api/products
Content-Type: application/json
Authorization: Bearer {token}
{
"name": "CellOptimize Pro",
"description": "Advanced cellular optimization supplement",
"brandId": 1,
"categoryId": 5,
"basePrice": 49.99,
"tags": ["supplement", "wellness", "cellular"],
"shopifySync": true,
"seoTitle": "CellOptimize Pro - Cellular Health Supplement",
"seoDescription": "Scientifically formulated for optimal cellular health"
}
Response (201 Created):
{
"success": true,
"productId": 123,
"sku": "CJ-SUP-1732022400",
"shopifyProductId": 7891234567890
}
Get detailed product information including variants and images.
GET /api/products/123
Response:
{
"productId": 123,
"sku": "CJ-SUP-1732022400",
"name": "CellOptimize Pro",
"description": "...",
"brand": {
"id": 1,
"name": "CellJourney",
"code": "CJ",
"shopifyStoreUrl": "celljourney.myshopify.com"
},
"category": {
"id": 5,
"name": "Supplements"
},
"variants": [
{
"variantId": 456,
"sku": "CJ-SUP-1732022400-30CT",
"name": "30 capsules",
"price": 49.99,
"inventoryQuantity": 150
}
],
"images": [...]
}
Update product details (partial updates supported).
Soft delete product (sets IsActive = 0).
Get inventory levels across all locations.
Adjust inventory quantity.
POST /api/products/variants/456/inventory/adjust
{
"locationId": 1,
"adjustment": -5,
"reason": "Order fulfillment"
}
Response:
{
"success": true,
"newQuantity": 145
}
Manually trigger Shopify sync.
Get products below reorder point.
Product count summary by brand.
List all active brands.
List all categories (hierarchical).
from shopify_sync_service import ShopifyClient
# Initialize client for CellJourney
client = ShopifyClient('CJ')
# Create product
shopify_product_id = client.create_product({
"title": "CellOptimize Pro",
"body_html": "Advanced supplement...",
"vendor": "CellJourney",
"product_type": "Supplements",
"tags": ["supplement", "wellness"],
"variants": [
{
"sku": "CJ-SUP-1732022400",
"price": "49.99",
"option1": "30 capsules"
}
]
})
# Update product
client.update_product(shopify_product_id, {
"title": "CellOptimize Pro (Updated)"
})
# Sync inventory
client.update_inventory(
shopify_inventory_item_id=12345,
shopify_location_id=67890,
quantity=150
)
| Webhook Topic | Endpoint | Purpose |
|---|---|---|
orders/create |
/webhooks/shopify/orders/create |
Reduce inventory when order placed |
orders/cancelled |
/webhooks/shopify/orders/cancelled |
Restore inventory when order cancelled |
products/update |
/webhooks/shopify/products/update |
Sync product changes from Shopify to database |
X-Shopify-Hmac-SHA256 header to prevent spoofing.
POST /api/products/123/sync-shopify
read_products, write_productsread_inventory, write_inventoryread_ordersSHOPIFY-CJ-ACCESS-TOKENshpat_xxxxxxxxxxxxxSHOPIFY_CJ_ACCESS_TOKEN = @Microsoft.KeyVault(SecretUri=https://qi3ci-keyvault.vault.azure.net/secrets/SHOPIFY-CJ-ACCESS-TOKEN)
Symptoms: Product created in database but not appearing in Shopify store.
Diagnosis:
SELECT TOP 10 * FROM ShopifySyncLog
WHERE SyncStatus = 'Failed'
ORDER BY SyncedAt DESC;
ErrorMessage column for API errorsSolutions:
Cause: Duplicate SKU in Products table.
Solution:
SELECT SKU, ProductName FROM Products WHERE SKU = 'CJ-SUP-1732022400';
Diagnosis:
ShopifyVariantID:
SELECT VariantSKU, ShopifyVariantID FROM ProductVariants WHERE VariantID = 456;
echo $env:SHOPIFY_CJ_LOCATION_ID
Solution: Ensure variant is synced to Shopify first, then inventory sync will work.
Symptoms: API returns "Failed to fetch products".
Solution:
AZURE_SQL_CONNECTIONSTRING
sqlcmd -S dranschak-family-server.database.windows.net -d Nova_StaX_DB -U {user} -P {pass}
Diagnosis:
product-imagesAZURE_STORAGE_CONNECTIONSTRING| Tool | Purpose |
|---|---|
| Azure Portal → SQL Database Query Editor | Run SQL queries directly on Nova_StaX_DB |
| Shopify Admin → Settings → Notifications → Webhooks | View webhook delivery status |
| Azure App Service → Log stream | Real-time API logs |
SELECT * FROM ShopifySyncLog |
Audit trail of all Shopify operations |
SELECT * FROM vw_LowStockAlerts |
Inventory alerts |
product_catalog_schema.sql on Nova_StaX_DBproduct-imagescd backend/blueprints/ecomm_flows
git add product_catalog_api.py shopify_sync_service.py __init__.py
git commit -m "Add Product Catalog API with Shopify integration"
git push origin main
app.py to import register_ecomm_blueprintsorders/create → https://www.drantech.ai/webhooks/shopify/orders/createorders/cancelled → https://www.drantech.ai/webhooks/shopify/orders/cancelledproducts/update → https://www.drantech.ai/webhooks/shopify/products/update# List brands
curl https://www.drantech.ai/api/products/brands
# Create test product
curl -X POST https://www.drantech.ai/api/products \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"name": "Test Product", "brandId": 1, "categoryId": 5, "basePrice": 19.99}'
apps/production_ready/drantechai_developer_flaskapp/docs/PRODUCT_CATALOG_DATABASE_PLAN.md
apps/production_ready/drantechai_developer_flaskapp/database/schemas/product_catalog_schema.sql
backend/blueprints/ecomm_flows/product_catalog_api.pybackend/blueprints/ecomm_flows/shopify_sync_service.py