fix(vehicles): canonicalise brand casing (case-insensitive brand match)
Decode persist looked brands up with a case-sensitive eq(), so an
uppercase decode string ("FORD") missed canonical "Ford" → brand_id
NULL + raw uppercase stored as brand_name, splitting one brand across
casing variants in analytics/catalog. Now matches brands
case-insensitively and stores the canonical name. Migration
0013_fix_brand_casing backfills existing rows (60 on prod, 1 on dev).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
28
apps/api/drizzle/0013_fix_brand_casing.sql
Normal file
28
apps/api/drizzle/0013_fix_brand_casing.sql
Normal file
@@ -0,0 +1,28 @@
|
||||
-- Canonicalise vehicle brand casing + backfill missing brand_id.
|
||||
--
|
||||
-- Root cause: the decode persist (vehicles.service.ts) looked brands up with a
|
||||
-- case-SENSITIVE `eq(brands.name, brandName)`. A decode source that yields an
|
||||
-- uppercase brand string (e.g. "FORD", "MERCEDES-BENZ") missed the canonical
|
||||
-- "Ford" / "Mercedes-Benz" row → brand_id stayed NULL and the raw uppercase
|
||||
-- string was stored as brand_name. That split the same brand across casing
|
||||
-- variants in analytics + the catalog ("Ford" vs "FORD"). The companion code
|
||||
-- fix makes the lookup case-insensitive and stores the canonical name; this
|
||||
-- migration repairs the rows already written.
|
||||
--
|
||||
-- Backfill every vehicle whose brand_name matches a canonical brand
|
||||
-- case-insensitively: set the FK and the canonical-cased name. (catalog_vehicles
|
||||
-- is intentionally untouched — its brand_name namespace does not match the
|
||||
-- brands table, so 0 rows would qualify.)
|
||||
UPDATE "vehicles" v
|
||||
SET brand_id = b.id, brand_name = b.name
|
||||
FROM "brands" b
|
||||
WHERE v.brand_id IS NULL AND lower(v.brand_name) = lower(b.name);
|
||||
--> statement-breakpoint
|
||||
|
||||
-- Defensive: realign any vehicle whose brand_id is set but whose denormalised
|
||||
-- brand_name has drifted from the canonical brands.name (none today, but keeps
|
||||
-- the FK and the denormalised name consistent going forward).
|
||||
UPDATE "vehicles" v
|
||||
SET brand_name = b.name
|
||||
FROM "brands" b
|
||||
WHERE v.brand_id = b.id AND v.brand_name <> b.name;
|
||||
Reference in New Issue
Block a user