Files
route-commerce/supabase/migrations/.archived/058_fix_get_wholesale_orders.sql
T
openclaw 916ad39176
Deploy to route.crispygoat.com / deploy (push) Failing after 3m1s
feat(storage): MinIO object storage, Neon Auth, Supabase removal
- Add MinIO/S3-compatible storage client (src/lib/storage.ts) with uploadObject,
  deleteObject, presigned URL helpers, and BUCKETS constant
- Wire product images, brand logos, and water log photos to MinIO via the
  new storage client
- Migrate forgot-password to Neon Auth (remove Supabase /auth/v1/recover call)
- Migrate send-scheduled cron to direct Postgres + Resend (remove Supabase Edge
  Function proxy)
- Add logoUrl to email types (OrderReceipt, Welcome, PasswordReset) and pass
  brand_settings.logo_url from all call sites
- Update email templates to use dynamic logoUrl instead of hardcoded Supabase
  bucket URLs
- Remove hardcoded Supabase URLs from TuxedoVideoHero, TuxedoAboutPage,
  TimeTrackingFieldClient; use brand_settings props + local public/ fallback
- Download brand logos (3) and tuxedo-hero.mp4 (36MB) from Supabase bucket to
  public/ for local development
- Add MinIO env vars to .env.example (endpoint, access key, secret, buckets)
- Fix TimeTrackingFieldClient to destructure logoUrl and brandAccent props
- Fix admin/users.ts logoUrl type (null → undefined for optional string)
- Remove stale sb- cookie from wholesale-auth
- Migrate tuxedo/about page to remove supabase import and use pool query for
  wholesale_settings lookup
2026-06-09 12:23:37 -06:00

163 lines
4.6 KiB
PL/PgSQL

-- Migration 058: Fix get_wholesale_orders and get_wholesale_customer_orders
-- Fixes: jsonb_build_object cannot be used inside jsonb_agg with FILTER.
-- Replaced with correlated subquery approach that is valid in Supabase Postgres.
BEGIN;
-- ── 1. get_wholesale_orders ────────────────────────────────────────────────────
DROP FUNCTION IF EXISTS public.get_wholesale_orders(UUID);
CREATE OR REPLACE FUNCTION public.get_wholesale_orders(p_brand_id UUID DEFAULT NULL)
RETURNS JSONB
LANGUAGE plpgsql SECURITY DEFINER SET search_path = public
AS $$
DECLARE
v_result JSONB;
BEGIN
SELECT jsonb_agg(t ORDER BY t.created_at DESC) INTO v_result
FROM (
SELECT
wo.id,
wo.status,
wo.fulfillment_status,
wo.payment_status,
wo.anticipated_pickup_date,
wo.subtotal,
wo.deposit_required,
wo.deposit_paid,
wo.balance_due,
wo.invoice_number,
wo.assigned_employee_id,
wo.created_at,
wo.updated_at,
wo.fulfilled_at,
wc.company_name,
wc.contact_name,
wc.email AS customer_email,
COALESCE(
(
SELECT jsonb_agg(
CASE WHEN woi.id IS NOT NULL THEN
jsonb_build_object(
'id', woi.id,
'product_name', wp.name,
'quantity', woi.quantity,
'unit_price', woi.unit_price,
'line_total', woi.line_total
)
END
)
FROM wholesale_order_items woi
LEFT JOIN wholesale_products wp ON woi.product_id = wp.id
WHERE woi.wholesale_order_id = wo.id
),
'[]'::JSONB
) AS items
FROM wholesale_orders wo
JOIN wholesale_customers wc ON wo.customer_id = wc.id
WHERE wo.brand_id = p_brand_id
ORDER BY wo.created_at DESC
LIMIT 500
) t;
RETURN COALESCE(v_result, '[]'::JSONB);
END;
$$;
-- ── 2. get_wholesale_customer_orders ─────────────────────────────────────────
DROP FUNCTION IF EXISTS public.get_wholesale_customer_orders(UUID);
CREATE OR REPLACE FUNCTION public.get_wholesale_customer_orders(p_customer_id UUID DEFAULT NULL)
RETURNS JSONB
LANGUAGE plpgsql SECURITY DEFINER SET search_path = public
AS $$
DECLARE
v_result JSONB;
BEGIN
SELECT jsonb_agg(t ORDER BY t.created_at DESC) INTO v_result
FROM (
SELECT
wo.id,
wo.status,
wo.fulfillment_status,
wo.payment_status,
wo.anticipated_pickup_date,
wo.subtotal,
wo.deposit_required,
wo.deposit_paid,
wo.balance_due,
wo.invoice_number,
wo.invoice_token,
wo.created_at,
wo.updated_at,
COALESCE(
(
SELECT jsonb_agg(
CASE WHEN woi.id IS NOT NULL THEN
jsonb_build_object(
'id', woi.id,
'product_name', wp.name,
'quantity', woi.quantity,
'unit_price', woi.unit_price,
'line_total', woi.line_total
)
END
)
FROM wholesale_order_items woi
LEFT JOIN wholesale_products wp ON woi.product_id = wp.id
WHERE woi.wholesale_order_id = wo.id
),
'[]'::JSONB
) AS items
FROM wholesale_orders wo
WHERE wo.customer_id = p_customer_id
ORDER BY wo.created_at DESC
LIMIT 100
) t;
RETURN COALESCE(v_result, '[]'::JSONB);
END;
$$;
-- ── 3. get_wholesale_products — simplified (no aggregate, no join issue) ───────
DROP FUNCTION IF EXISTS public.get_wholesale_products(UUID);
CREATE OR REPLACE FUNCTION public.get_wholesale_products(p_brand_id UUID DEFAULT NULL)
RETURNS JSONB
LANGUAGE plpgsql SECURITY DEFINER SET search_path = public
AS $$
DECLARE
v_result JSONB;
BEGIN
SELECT jsonb_agg(t ORDER BY t.name) INTO v_result
FROM (
SELECT
wp.id,
wp.name,
wp.description,
wp.unit_type,
wp.unit_type_custom,
wp.availability,
wp.qty_available,
wp.season_start,
wp.season_end,
wp.price_tiers,
wp.hp_sku,
wp.hp_item_id,
wp.handling_instructions,
wp.storage_warning,
wp.loading_notes,
wp.product_label,
wp.pack_style,
wp.container_type,
wp.container_size_code,
wp.units_per_container,
wp.default_pickup_location,
wp.created_at
FROM wholesale_products wp
WHERE wp.brand_id = p_brand_id
ORDER BY wp.name
) t;
RETURN COALESCE(v_result, '[]'::JSONB);
END;
$$;
COMMIT;
NOTIFY pgrst, 'reload schema';