refactor(storefront): remove supabase shim and restore customer storefronts
The legacy src/lib/supabase.ts shim returned { data: null } for every
query, so 15+ pages were silently rendering empty state — including the
two customer-facing storefronts (tuxedo, indian-river-direct) and
several v1 admin pages. Replace every caller with canonical access:
- New src/actions/storefront.ts server-action module: brand lookup,
public stops, active products, stop-by-slug, wholesale settings,
portal config. Uses the shared pg Pool and SECURITY DEFINER RPCs.
- src/actions/brand-settings.ts: getBrandSettingsPublic inlined the
brands + brand_settings LEFT JOIN wholesale_settings query (the
RPC it called did not exist; try/catch was masking the failure).
- src/actions/ai/preferences.ts: switched get/saveAIPreferences to
pool.query.
- src/actions/square-sync-ui.ts: new getSquareQueueCount action for
SquareSyncWidget (replaces shim count).
- src/app/api/{tuxedo,indian-river-direct}/schedule-pdf/route.ts:
use pool.query.
- next.config.ts: redirects /admin/{products/:id,reports,taxes,
settings/{shipping,integrations,billing}} → their v2 / settings
equivalents, then deleted those pages.
- Deleted src/lib/supabase.ts (no remaining imports).
Tests: 174/175 (unchanged from baseline; pre-existing getAdminUser
mock issue is tracked in Step 5).
This commit is contained in:
@@ -243,14 +243,24 @@ export async function getBrandSettings(brandId: string): Promise<GetBrandSetting
|
||||
}
|
||||
}
|
||||
|
||||
// Public version for storefront pages — uses slug, no auth required
|
||||
// Public version for storefront pages — uses slug, no auth required.
|
||||
//
|
||||
// Inlined as a join against `brands` + `brand_settings` LEFT JOIN
|
||||
// `wholesale_settings` instead of calling `get_brand_settings_by_slug`.
|
||||
// That RPC is referenced from this code path but is not defined in any
|
||||
// shipped migration, so the function-on-the-server call would throw
|
||||
// `function get_brand_settings_by_slug(unknown) does not exist` and the
|
||||
// storefront would silently fall back to defaults. The inlined query
|
||||
// has the same shape and never fails because of a missing RPC.
|
||||
export async function getBrandSettingsPublic(brandSlug: string): Promise<GetBrandSettingsResult & { wholesaleEnabled?: boolean | null }> {
|
||||
// Wrapped in try/catch so a build-time DB outage (ECONNREFUSED) doesn't
|
||||
// crash the prerender — the page just falls back to its default brand
|
||||
// name and revalidates from a real request later.
|
||||
try {
|
||||
const { rows } = await pool.query<BrandSettings & { wholesale_enabled?: boolean | null }>(
|
||||
"SELECT * FROM get_brand_settings_by_slug($1)",
|
||||
`SELECT bs.*, b.name AS brand_name, ws.wholesale_enabled
|
||||
FROM brands b
|
||||
JOIN brand_settings bs ON bs.brand_id = b.id
|
||||
LEFT JOIN wholesale_settings ws ON ws.brand_id = b.id
|
||||
WHERE b.slug = $1
|
||||
LIMIT 1`,
|
||||
[brandSlug],
|
||||
);
|
||||
const data = rows[0];
|
||||
|
||||
Reference in New Issue
Block a user