Fulfillment – Daily Changelog – October 17, 2025

Changelog – October 17, 2025

Blank Category System Implementation

New Category-Based Blank Selection

  • Problem: Need to group interchangeable blank styles for flexible inventory management
  • Solution: Implemented comprehensive category system for blank products
  • Created 3 new database tables:
    • blank_categories – Define categories (e.g., “Black Short Sleeve Tee – Cotton – Standard Quality”)
    • blank_category_styles – Map styles to categories with preference ranking
    • warehouse_category_items – Track inventory by category instead of specific style
  • Added blank_category_id to mama_tried_product_variants for category assignment
  • Features:
  • Full CRUD API for category management (/api/blank-categories)
  • Style assignment with preference ranking (rank 1 = preferred, rank 2 = fallback)
  • Auto-generation of category names from form fields (material + quality + color + garment type)
  • Updated batch production to auto-select SKUs from categories based on availability
  • Built category management UI at /blank-categories
  • Migration: Migrated 68 black Jerzees variants to new category system
  • Category includes Jerzees 29MR (rank 1) and Gildan 8000 (rank 2) as interchangeable options
  • Files Created:
  • database_migrations/add_blank_categories.sql
  • scripts/migrate_to_black_category.sql
  • scripts/verify_category_migration.sql
  • src/app/blank-categories/page.tsx
  • src/components/blank-categories/category-form.tsx
  • src/components/blank-categories/category-styles-manager.tsx
  • src/components/products/category-selector.tsx
  • Multiple API routes under /api/blank-categories/
  • Documentation:
  • BLANK_CATEGORY_IMPLEMENTATION_SUMMARY.md
  • BLANK_CATEGORY_QUICKSTART.md
  • BLANK_CATEGORY_SYSTEM.md

Blank Categories API Fix

  • Problem: Category list/detail endpoints failing with 500 errors
  • Root Cause: API tried to join with non-existent blank_colors table
  • Solution: Removed LEFT JOIN references to blank_colors table
  • Files Modified:
  • src/app/api/blank-categories/[id]/route.ts
  • src/app/api/blank-categories/route.ts

Category Name Auto-Generation

  • Feature: Category names now auto-populate as user fills form fields
  • Behavior:
  • Only auto-generates if name field is empty or matches previous auto-generated name
  • Allows manual override by typing directly in name field
  • Impact: Reduces manual typing and ensures consistent naming conventions
  • File Modified: src/components/blank-categories/category-form.tsx

Critical QuickBooks Rate Limiting Fix

QuickBooks API Throttling Issue

  • Problem: Attempting to send 25+ invoices to QuickBooks resulted in HTTP 429 “ThrottleExceeded” errors
  • Root Cause: October 3rd commit changed invoice sending from sequential with delays to parallel execution using Promise.all()
  • Previous code sent invoices one at a time with 500ms delays
  • “Optimization” removed delays and sent all invoices simultaneously
  • Worked with 14 invoices on Oct 3, failed with 25+ invoices today
  • QuickBooks API limits: ~30 calls per minute, 500 calls per 5 minutes
  • Impact: Unable to send 80 uninvoiced shipped orders to QuickBooks, system throttled for extended period
  • Solution:
  • Reverted to sequential processing with increased 2-second delays between requests
  • Applied fix to both invoice sending code paths:
    • invoice-creation-success.tsx – “Send All to QuickBooks” button in creation dialog
    • send-selected-to-quickbooks-button.tsx – Bulk send button on invoices page
  • Added progress indicators showing “Sending X/Y…” so users can track progress
  • Files Modified:
  • src/components/orders/invoice-creation-success.tsx
  • src/components/invoices/send-selected-to-quickbooks-button.tsx
  • Deployments: v871, v876, v877
  • Result: Invoices now send reliably without hitting rate limits, users can see progress during bulk sends

Database Investigation & Upgrade

Shipped Orders Without Invoices Audit

  • Query: Identified 80 orders marked as “shipped” status that hadn’t been invoiced yet
  • Findings:
  • Most orders from Oct 2-17, 2025 (expected to be uninvoiced)
  • One older order #5346 from Sept 19, 2025 – potentially had status changed manually
  • All had invoiced = false and no records in mama_tried_invoice_orders junction table
  • Action: Prepared for batch invoicing once rate limit issues resolved

Database Plan Upgrade

  • Action: Upgraded Heroku Postgres from Essential-0 to Essential-1
  • Cost: $5/mo → $9/mo (+$4/mo)
  • Expected: 60 database connections (3x increase)
  • Actual: 20 connections (no change)
  • Essential-0: $5/mo, 20 connections, 1 GB storage
  • Essential-1: $9/mo, 20 connections, 10 GB storage
  • Lesson Learned: Connection limit increase requires Standard-0 plan ($50/mo, 120 connections)
  • Note: Storage increase not needed (was at 9.67% of 1 GB limit)
  • Status: May downgrade back to Essential-0 as upgrade provided minimal benefit for cost

Order Data Fixes

Order #5405 Variant Correction

  • Problem: Order 629 (Shopify #5405) showed XXL variant instead of L variant
  • Customer ordered 2 shirts in size L
  • Database showed line item 669 with XXL variant (5687) after variant data restoration
  • Would have been invoiced incorrectly for more expensive XXL size
  • Solution: Updated line item 669 to correct L size variant (5685)
  • Impact: Order will now invoice correctly for the size that was actually ordered
  • Related: This order already had reprint #5405-REPRINT created for the incorrect 2XL that was shipped

Minor Fixes

Reprint Dialog Import Path

  • Fixed: Corrected toast hook import path in create-reprint-dialog.tsx
  • Changed: @/hooks/use-toast@/components/ui/use-toast

Shipment API Error Logging

  • Enhanced: Added error logging to batch lock failure in mark-as-shipped/route.ts
  • File: src/app/api/shipments/mark-as-shipped/route.ts

Temporary Files Cleanup

  • Removed experimental scripts created during troubleshooting:
  • scripts/send_draft_invoices_to_qb.js
  • scripts/send_draft_invoices_to_qb.cjs

Outstanding Issues

API Endpoint Errors

  • Observation: Some API endpoints returning 500 errors when loading order details
  • /api/orders/629 – Failed to load order data
  • /api/orders/629/line-items – Failed to load line items
  • Suspected Cause: Possibly related to raffle sticker orders with no variants, or snapshot system changes not yet deployed
  • Impact: UI errors but invoicing still functions correctly
  • Status: Deferred for future fix

Lessons Learned

  1. Rate Limiting: Always preserve delays/throttling when interfacing with external APIs – “optimizations” can break integration limits
  2. Cloud Service Pricing: Always verify current Heroku pricing/features rather than relying on assumptions
  3. Progress Indicators: Critical for long-running operations so users know system is working
  4. Database Connections: Issue was connection pool size (5), not total limit (20) – code optimizations may be more valuable than plan upgrades

Next Steps

  • Monitor QuickBooks integration for rate limiting issues
  • Consider downgrading database back to Essential-0 if connection limits remain adequate
  • Deploy remaining connection pool optimizations from undeployed commits when ready
  • Address API 500 errors for order detail pages (low priority)