Fulfillment – Daily Changelog – October 13, 2025

Changelog – October 13, 2025

UI Improvements

Fixed Product Title Display on Orders Page

  • Problem: Orders were showing “(Default Title)” where size/variant information should be displayed
  • Root Cause Investigation:
  • Initially thought the issue was in item.title field showing “Default Title”
  • Database investigation revealed the actual problem: Shopify was storing “Default Title” in the variant.size field for raffle stickers and other items without actual sizes
  • This caused inconsistent display – some orders showed it (newer syncs with “Default Title” in size), others didn’t (older syncs with NULL/empty size)
  • Solution: Filter out “Default Title” from both product titles AND variant sizes across all order views
  • Check both item.title === 'Default Title' and item.variant.size === 'Default Title'
  • Only show variant information (parentheses) when there’s actually meaningful size or color data
  • Updated getVariantDisplay() helper function to exclude “Default Title” sizes
  • Files Modified:
  • src/app/(authenticated)/orders/page.tsx – Main orders listing page
  • src/app/(authenticated)/store-manager/orders/page.tsx – Store manager orders view
  • src/app/(authenticated)/admin-dashboard/page.tsx – Admin dashboard orders
  • src/app/(authenticated)/store-manager/orders/[id]/page.tsx – Store manager order details
  • src/app/(authenticated)/orders/[id]/page.tsx – Order details page (including getVariantDisplay function)
  • Impact: Clean display without Shopify’s placeholder text – items without sizes/colors show just the product name, items with actual variant data show it properly
  • Why It Started Suddenly: Shopify changed how they sync variants for products without sizes, now explicitly setting size to “Default Title” instead of NULL

Temporarily Removed “Address Updated” Badge

  • Problem: Badge was showing up incorrectly on orders that didn’t have address changes
  • Root Cause: Known issue with address comparison logic in updateOrderShippingAddress function (documented in changelog_09192025.md)
  • Solution: Removed the badge display temporarily until the underlying comparison logic can be fixed
  • Files Modified: src/app/(authenticated)/orders/page.tsx
  • Impact: Eliminates false positive indicators that were requiring manual resets
  • Follow-up Required: Need to debug and fix the address comparison logic in updateOrderShippingAddress before re-enabling the badge

Bug Fixes

Fixed Database Pool Configuration TypeScript Error

  • Problem: TypeScript compilation error – min property not recognized in Pool configuration
  • Root Cause: The node-postgres pg library’s PoolConfig doesn’t support min (minimum pool size) or acquireTimeoutMillis properties
  • Solution: Removed invalid min and acquireTimeoutMillis properties from Pool configuration
  • Files Modified: src/lib/db.ts
  • Impact: TypeScript compilation now passes without errors, ready for deployment

Fixed JSX Syntax Error in Store Manager Order Details

  • Problem: TypeScript parsing error due to missing closing brace in JSX return statement
  • Root Cause: When fixing the “Default Title” display issue, the closing brace for the map function’s return statement was accidentally removed
  • Solution: Properly structured the JSX with correct closing braces
  • Files Modified: src/app/(authenticated)/store-manager/orders/[id]/page.tsx
  • Impact: Build errors resolved, page renders correctly

Fixed Unused Variables in Product Sync Tools

  • Problem: ESLint errors for unused confirmationText and setConfirmationText variables
  • Root Cause: Legacy state variables left over from previous confirmation dialog implementation
  • Solution: Removed unused state variables
  • Files Modified: src/components/products/product-sync-tools.tsx
  • Impact: Clean linting, no warnings

New Features

Shopify Product Price Change Webhooks

  • Purpose: Automatically track and notify when product variant prices change in Shopify
  • Implementation:
  • Added support for products/update webhook topic to existing webhook handler
  • Compares incoming variant prices with stored prices in database
  • Only triggers notifications when prices actually change (avoids false positives)
  • Handles new variants by storing prices without notification (first-time setup)
  • Updates prices in mama_tried_product_variants table after change detection
  • Email Notifications:
  • Sends one email per product with all variant price changes listed
  • Includes: store name, product title, old → new price for each variant, percentage change
  • Shows compare at price changes if applicable
  • Provides direct link to Shopify admin product page
  • Beautiful branded HTML email template with color-coded price increases/decreases
  • Files Created:
  • src/lib/emails/types/price-change.ts – TypeScript type definitions
  • src/lib/emails/templates/price-change.ts – HTML email template
  • src/lib/emails/senders/price-change.ts – Email sending logic
  • database_migrations/048_add_price_changes_alert_type.sql – Database migration
  • docs/shopify-price-change-webhooks.md – Comprehensive documentation
  • Files Modified:
  • src/app/api/webhooks/shopify/route.ts – Added products/update handler
  • Setup Required:
  1. Run database migration to add price_changes alert type
  2. Configure email recipients via Settings → Email Notifications
  3. Add products/update webhook in Shopify admin (URL: existing webhook endpoint)
  • Security: Uses same HMAC signature verification as existing order webhooks
  • Documentation: Full setup, testing, and troubleshooting guide in /docs/shopify-price-change-webhooks.md

Added Manual Step Tracker to Raffle Sticker Batches

  • Problem: Raffle sticker batches didn’t have the manual status tracker that regular batches have, making it impossible to manually complete steps when needed
  • Solution: Added BatchStatusTerminal component to raffle sticker batch page
  • Implementation:
  • Uncommented BatchStatusTerminal import
  • Enabled batch stages query to fetch stage data
  • Added data formatting for stages and batch status
  • Placed component below shipping panel in right column
  • Files Modified: src/app/(authenticated)/batches/[id]/raffle-page.tsx
  • Impact: Raffle sticker batches now have the same manual tracker functionality as regular batches for manually completing steps when database timeouts or other issues occur

Database Fixes

Manually Updated Batch Status for Failed Completions

  • Problem: Batches 498, 506, and 511 didn’t get updated to “fulfilled” status, likely due to database timeouts/stalls during shipment sync
  • Root Cause: Database was getting stalled during ShippingEasy shipment sync operations
  • Solution: Manually updated database to set all affected batches to “fulfilled” status
  • Batches Updated:
  • Batch 498 (D251009-2) – raffle_stickers → fulfilled ✅
  • Batch 506 (D251009-6) – raffle_stickers → fulfilled ✅
  • Batch 511 (D251010-1) – raffle_stickers → fulfilled ✅
  • SQL Executed:
  UPDATE mama_tried_batches 
  SET batch_status = 'fulfilled', updated_at = CURRENT_TIMESTAMP 
  WHERE id IN (498, 506, 511);
  • Note: All affected batches were raffle_stickers type; batches before 498 were working normally

Fixed Raffle Sticker Order Type Assignment

  • Problem: After variant data reset, raffle sticker orders weren’t being classified correctly and didn’t show up when filtering for “Raffle Sticker” orders
  • Root Cause:
  • assignOrderType() function wasn’t selecting is_raffle_sticker field from products table
  • Newer orders never got their order type assigned
  • Immediate Fix (Database):
  • Updated 176 orders (86 + 90) to have correct raffle-sticker order type
  • Removed 4 bogus variants created during variant reset from raffle sticker products
  • Cleared variant references from 112 raffle sticker line items
  • Raffle stickers are now simple products without variants (as intended)
  • Code Fix (Deploy Tomorrow):
  • Updated assignOrderType() in src/lib/orderUtils.ts to include is_raffle_sticker field
  • Files Modified: src/lib/orderUtils.ts
  • Impact: Raffle sticker orders now show up correctly in filtered views