[dotenv@17.2.3] injecting env (112) from .env -- tip: ≡ƒæÑ sync secrets across teammates & machines: https://dotenvx.com/ops
[dotenv@17.2.3] injecting env (0) from .env -- tip: ≡ƒöÉ prevent committing .env to code: https://dotenvx.com/precommit
[protected-image] IMAGE_ROOTS = [ 'C:\\Bordales Projects\\giftwrap - Copy\\protected\\images' ]
[protected-image] IMAGE_ROOT = /home/bordales/public_html/v1/protected/images
[protected-image] SKU fallback enabled
[Server] Γ£à Real-Time Monitor: Initialized
[protected-image] Cache initialized with 9638 files
[Schema] PRICE_HAS_COST_MARKUP = true
Γ£à Database synced ΓÇô tables are ready
[Server] Running on port 3000 in development mode
[Server] Health check: http://localhost:3000/healthz
[Server] Ready check: http://localhost:3000/readyz
[Server] Γ£à WhatsApp Service: Loaded
[Server] Γ£à AI Assistant: Loaded
[Server] Γ£à Gate System: Loaded
[GATE DEBUG] Path: /v3/products/1056838 Original URL: /api/v3/products/1056838?_cb=222222
[GATE DEBUG] Session ID: DXTHIPiuKYRpf9UZUdz8J0vuOYemV5o6
[GATE DEBUG] Session: Session {
  cookie: {
    path: '/',
    _expires: null,
    originalMaxAge: null,
    httpOnly: true,
    sameSite: 'lax',
    secure: false
  }
}
[GATE DEBUG] Authenticated: undefined
[ProductService DEBUG] SQL: 
            SELECT DISTINCT
                p.*,
                CAST(
                  CASE
                    WHEN pr.stock_qty IS NOT NULL THEN pr.stock_qty
                    WHEN p.stock_qty IS NULL THEN COALESCE(JSON_UNQUOTE(JSON_EXTRACT(p.attributes_json, '$.stock_qty')), '0')
                    ELSE p.stock_qty
                  END AS SIGNED
                ) as stock_qty,
                CAST(COALESCE(JSON_UNQUOTE(JSON_EXTRACT(p.attributes_json, '$.lead_time')), '') AS CHAR) as lead_time,
                (
                    SELECT pi.path
                    FROM catalog_product_images pi
                    WHERE pi.product_id = p.id
                    ORDER BY pi.is_primary DESC, pi.position ASC
                    LIMIT 1
                ) as primary_image_path,
                COALESCE(pr.price_ex_vat, (
                    SELECT COALESCE(pp.price_ex_vat, 0)
                    FROM catalog_product_prices pp
                    WHERE pp.product_id = p.id AND pp.is_active = 1 AND pp.min_qty = 1
                    ORDER BY pp.effective_from DESC LIMIT 1
                )) as price_ex_vat,
                COALESCE(regions.currency_code, 'ZAR') as currency_code,
                CASE WHEN pr.price_ex_vat IS NOT NULL THEN 'region' ELSE 'default' END as price_source,
                COALESCE(pr.price_inc_vat, (
                    SELECT COALESCE(pp.price_ex_vat, 0) * 1.15
                    FROM catalog_product_prices pp
                    WHERE pp.product_id = p.id AND pp.is_active = 1 AND pp.min_qty = 1
                    ORDER BY pp.effective_from DESC LIMIT 1
                )) as price_inc_vat,
                (
                    SELECT GROUP_CONCAT(DISTINCT pc.category_id)
                    FROM catalog_product_categories pc
                    WHERE pc.product_id = p.id
                ) as category_ids,
                (
                    SELECT GROUP_CONCAT(DISTINCT t.tag)
                    FROM catalog_product_tags t
                    WHERE t.product_id = p.id
                ) as tags_string,
                (
                    SELECT c.slug
                    FROM catalog_product_categories pc_slug
                    JOIN catalog_categories c ON c.id = pc_slug.category_id
                    WHERE pc_slug.product_id = p.id
                    LIMIT 1
                ) as category_slug,
                (
                    SELECT JSON_ARRAYAGG(JSON_OBJECT('id', bm.id, 'name', bm.name, 'slug', bm.slug))
                    FROM catalog_product_branding_methods pm
                    JOIN catalog_branding_methods bm ON bm.id = pm.method_id
                    WHERE pm.product_id = p.id
                ) as branding_methods_json,
                COALESCE(seasonality.score, 0) as seasonal_score,
                COALESCE(relevance.score, 0) as popularity_score
            FROM catalog_products p
            LEFT JOIN product_region pr ON p.id = pr.product_id AND pr.region_code = ?
            LEFT JOIN regions ON regions.code = pr.region_code
            LEFT JOIN product_seasonality seasonality ON p.id = seasonality.product_id AND seasonality.region_code = ? AND seasonality.season = ?
            LEFT JOIN product_relevance relevance ON p.id = relevance.product_id AND relevance.region_code = ?
    
            WHERE p.tenant_id = ?
              AND COALESCE(p.is_active, 1) = 1
              AND (p.status IS NULL OR p.status = '' OR p.status IN ('active','published','live','enabled'))
     AND p.id IN (?)  AND (COALESCE(pr.price_ex_vat, (SELECT pp.price_ex_vat FROM catalog_product_prices pp WHERE pp.product_id = p.id ORDER BY pp.effective_from DESC LIMIT 1), p.base_price) > 0)  AND (p.image_url IS NOT NULL OR EXISTS (SELECT 1 FROM catalog_product_images pi WHERE pi.product_id = p.id) OR (p.attributes_json IS NOT NULL AND (JSON_EXTRACT(p.attributes_json, '$.images') IS NOT NULL OR JSON_EXTRACT(p.attributes_json, '$.image_url') IS NOT NULL))) 
[ProductService DEBUG] allParams: [ 'ZA', 'ZA', '', 'ZA', 1, 1056838 ]
[GATE DEBUG] Path: /v3/products/1056838 Original URL: /api/v3/products/1056838?_cb=222222
[GATE DEBUG] Session ID: 1Wnz-hjK4MXxHM2Z36t0BYNdeU_RhXmO
[GATE DEBUG] Session: Session {
  cookie: {
    path: '/',
    _expires: null,
    originalMaxAge: null,
    httpOnly: true,
    sameSite: 'lax',
    secure: false
  }
}
[GATE DEBUG] Authenticated: undefined
[ProductService DEBUG] SQL: 
            SELECT DISTINCT
                p.*,
                CAST(
                  CASE
                    WHEN pr.stock_qty IS NOT NULL THEN pr.stock_qty
                    WHEN p.stock_qty IS NULL THEN COALESCE(JSON_UNQUOTE(JSON_EXTRACT(p.attributes_json, '$.stock_qty')), '0')
                    ELSE p.stock_qty
                  END AS SIGNED
                ) as stock_qty,
                CAST(COALESCE(JSON_UNQUOTE(JSON_EXTRACT(p.attributes_json, '$.lead_time')), '') AS CHAR) as lead_time,
                (
                    SELECT pi.path
                    FROM catalog_product_images pi
                    WHERE pi.product_id = p.id
                    ORDER BY pi.is_primary DESC, pi.position ASC
                    LIMIT 1
                ) as primary_image_path,
                COALESCE(pr.price_ex_vat, (
                    SELECT COALESCE(pp.price_ex_vat, 0)
                    FROM catalog_product_prices pp
                    WHERE pp.product_id = p.id AND pp.is_active = 1 AND pp.min_qty = 1
                    ORDER BY pp.effective_from DESC LIMIT 1
                )) as price_ex_vat,
                COALESCE(regions.currency_code, 'ZAR') as currency_code,
                CASE WHEN pr.price_ex_vat IS NOT NULL THEN 'region' ELSE 'default' END as price_source,
                COALESCE(pr.price_inc_vat, (
                    SELECT COALESCE(pp.price_ex_vat, 0) * 1.15
                    FROM catalog_product_prices pp
                    WHERE pp.product_id = p.id AND pp.is_active = 1 AND pp.min_qty = 1
                    ORDER BY pp.effective_from DESC LIMIT 1
                )) as price_inc_vat,
                (
                    SELECT GROUP_CONCAT(DISTINCT pc.category_id)
                    FROM catalog_product_categories pc
                    WHERE pc.product_id = p.id
                ) as category_ids,
                (
                    SELECT GROUP_CONCAT(DISTINCT t.tag)
                    FROM catalog_product_tags t
                    WHERE t.product_id = p.id
                ) as tags_string,
                (
                    SELECT c.slug
                    FROM catalog_product_categories pc_slug
                    JOIN catalog_categories c ON c.id = pc_slug.category_id
                    WHERE pc_slug.product_id = p.id
                    LIMIT 1
                ) as category_slug,
                (
                    SELECT JSON_ARRAYAGG(JSON_OBJECT('id', bm.id, 'name', bm.name, 'slug', bm.slug))
                    FROM catalog_product_branding_methods pm
                    JOIN catalog_branding_methods bm ON bm.id = pm.method_id
                    WHERE pm.product_id = p.id
                ) as branding_methods_json,
                COALESCE(seasonality.score, 0) as seasonal_score,
                COALESCE(relevance.score, 0) as popularity_score
            FROM catalog_products p
            LEFT JOIN product_region pr ON p.id = pr.product_id AND pr.region_code = ?
            LEFT JOIN regions ON regions.code = pr.region_code
            LEFT JOIN product_seasonality seasonality ON p.id = seasonality.product_id AND seasonality.region_code = ? AND seasonality.season = ?
            LEFT JOIN product_relevance relevance ON p.id = relevance.product_id AND relevance.region_code = ?
    
            WHERE p.tenant_id = ?
              AND COALESCE(p.is_active, 1) = 1
              AND (p.status IS NULL OR p.status = '' OR p.status IN ('active','published','live','enabled'))
     AND p.id IN (?)  AND (COALESCE(pr.price_ex_vat, (SELECT pp.price_ex_vat FROM catalog_product_prices pp WHERE pp.product_id = p.id ORDER BY pp.effective_from DESC LIMIT 1), p.base_price) > 0)  AND (p.image_url IS NOT NULL OR EXISTS (SELECT 1 FROM catalog_product_images pi WHERE pi.product_id = p.id) OR (p.attributes_json IS NOT NULL AND (JSON_EXTRACT(p.attributes_json, '$.images') IS NOT NULL OR JSON_EXTRACT(p.attributes_json, '$.image_url') IS NOT NULL))) 
[ProductService DEBUG] allParams: [ 'ZA', 'ZA', '', 'ZA', 1, 1056838 ]
Running periodic AI performance monitoring...
Running periodic AI performance monitoring...
[GATE DEBUG] Path: /v3/catalog/geoip Original URL: /api/v3/catalog/geoip
[GATE DEBUG] Session ID: _2AIsgPi6QjYafMwJoqzFFdA9P3NnIjl
[GATE DEBUG] Session: Session {
  cookie: {
    path: '/',
    _expires: null,
    originalMaxAge: null,
    httpOnly: true,
    sameSite: 'lax',
    secure: false
  }
}
[GATE DEBUG] Authenticated: undefined
Running periodic AI performance monitoring...
[GATE DEBUG] Path: /v3/catalog/geoip Original URL: /api/v3/catalog/geoip
[GATE DEBUG] Session ID: 6TOZUtzV1wK84aEEQA6YFHmjzoWEm7hS
[GATE DEBUG] Session: Session {
  cookie: {
    path: '/',
    _expires: null,
    originalMaxAge: null,
    httpOnly: true,
    sameSite: 'lax',
    secure: false
  }
}
[GATE DEBUG] Authenticated: undefined
Running periodic AI performance monitoring...
Running periodic AI performance monitoring...
