feat(catalog): migrate dev seed data to manufacturer-slug-based global items

Replace brand text field with manufacturerSlug in DEV_GLOBAL_ITEMS,
global-items-seed.json, and seed-global-items.ts. Add DEV_MANUFACTURERS
for dev-only brands not in SEED_MANUFACTURERS. Expand SEED_MANUFACTURERS
with 8 additional manufacturers referenced by seed JSON (Nemo, Therm-a-Rest,
Toaks, Katadyn, HydraPak, Nitecore, Outdoor Research, Exposure Lights).
Update dev-seed.ts to resolve slug→id before insert and use manufacturerId
as the deduplication key.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-18 16:37:27 +02:00
parent 0b4715b80c
commit 44b1eac0ba
4 changed files with 106 additions and 63 deletions

View File

@@ -17,13 +17,34 @@ export const DEV_CATEGORIES = [
{ name: "Navigation", icon: "compass" },
] as const;
// ── Manufacturers ──────────────────────────────────────────────────
// Seeded with onConflictDoNothing — safe to overlap with SEED_MANUFACTURERS.
export const DEV_MANUFACTURERS = [
{ name: "Rockgeist", slug: "rockgeist", website: "https://rockgeist.com", country: "US", tier: 1 },
{ name: "Oveja Negra", slug: "oveja-negra", website: "https://ovejanegrabikewear.com", country: "US", tier: 1 },
{ name: "Durston", slug: "durston", website: "https://durstondesigns.com", country: "US", tier: 1 },
{ name: "Enlightened Equipment", slug: "enlightened-equipment", website: "https://enlightenedequipment.com", country: "US", tier: 1 },
{ name: "BRS", slug: "brs", website: "https://brs-outdoor.com", country: "CN", tier: 1 },
{ name: "Soto", slug: "soto", website: "https://sotostoves.com", country: "JP", tier: 1 },
{ name: "Snow Peak", slug: "snow-peak", website: "https://snowpeak.com", country: "JP", tier: 1 },
{ name: "Lezyne", slug: "lezyne", website: "https://lezyne.com", country: "US", tier: 1 },
{ name: "Fenix", slug: "fenix", website: "https://fenixlighting.com", country: "CN", tier: 1 },
{ name: "Park Tool", slug: "park-tool", website: "https://parktool.com", country: "US", tier: 1 },
{ name: "Gorilla Tape", slug: "gorilla-tape", website: "https://gorillatough.com", country: "US", tier: 1 },
{ name: "Patagonia", slug: "patagonia", website: "https://patagonia.com", country: "US", tier: 1 },
{ name: "Frogg Toggs", slug: "frogg-toggs", website: "https://froggtoggs.com", country: "US", tier: 1 },
{ name: "Buff", slug: "buff", website: "https://buffwear.com", country: "ES", tier: 1 },
{ name: "Anker", slug: "anker", website: "https://anker.com", country: "CN", tier: 1 },
] as const;
// ── Global Items ───────────────────────────────────────────────────
// Index positions are referenced by user items, thread candidates, and tag assignments.
export const DEV_GLOBAL_ITEMS = [
// Bags (indices 0-5)
{
brand: "Revelate Designs",
manufacturerSlug: "revelate-designs",
model: "Terrapin System",
category: "bags",
weightGrams: 529,
@@ -32,7 +53,7 @@ export const DEV_GLOBAL_ITEMS = [
"Waterproof saddle bag with 14L capacity, roll-top closure, and integrated seat bag mount.",
},
{
brand: "Apidura",
manufacturerSlug: "apidura",
model: "Expedition Handlebar Pack",
category: "bags",
weightGrams: 300,
@@ -41,7 +62,7 @@ export const DEV_GLOBAL_ITEMS = [
"14L waterproof handlebar roll bag with internal dry bag and accessory pocket.",
},
{
brand: "Ortlieb",
manufacturerSlug: "ortlieb",
model: "Frame-Pack RC",
category: "bags",
weightGrams: 250,
@@ -50,7 +71,7 @@ export const DEV_GLOBAL_ITEMS = [
"6L waterproof roll-closure frame bag with TIZIP zipper for full-frame bikes.",
},
{
brand: "Rockgeist",
manufacturerSlug: "rockgeist",
model: "BarJam",
category: "bags",
weightGrams: 142,
@@ -59,7 +80,7 @@ export const DEV_GLOBAL_ITEMS = [
"Ultralight handlebar harness with side-loading dry bag compatibility.",
},
{
brand: "Oveja Negra",
manufacturerSlug: "oveja-negra",
model: "Superwedgie",
category: "bags",
weightGrams: 170,
@@ -68,7 +89,7 @@ export const DEV_GLOBAL_ITEMS = [
"Half-frame bag with easy-access zipper and internal organization.",
},
{
brand: "Apidura",
manufacturerSlug: "apidura",
model: "Racing Top Tube Pack",
category: "bags",
weightGrams: 72,
@@ -79,7 +100,7 @@ export const DEV_GLOBAL_ITEMS = [
// Shelter (indices 6-9)
{
brand: "Zpacks",
manufacturerSlug: "zpacks",
model: "Duplex",
category: "shelter",
weightGrams: 539,
@@ -88,7 +109,7 @@ export const DEV_GLOBAL_ITEMS = [
"Dyneema Composite Fabric two-person trekking pole shelter, freestanding with optional poles.",
},
{
brand: "Tarptent",
manufacturerSlug: "tarptent",
model: "Stratospire Li",
category: "shelter",
weightGrams: 737,
@@ -97,7 +118,7 @@ export const DEV_GLOBAL_ITEMS = [
"Two-person double-wall tent in Dyneema with dual vestibules and excellent ventilation.",
},
{
brand: "Durston",
manufacturerSlug: "durston",
model: "X-Mid 1 Solid",
category: "shelter",
weightGrams: 880,
@@ -106,7 +127,7 @@ export const DEV_GLOBAL_ITEMS = [
"Single-wall silpoly trekking pole tent with symmetrical design and two vestibules.",
},
{
brand: "Big Agnes",
manufacturerSlug: "big-agnes",
model: "Copper Spur HV UL1",
category: "shelter",
weightGrams: 936,
@@ -117,7 +138,7 @@ export const DEV_GLOBAL_ITEMS = [
// Sleep System (indices 10-14)
{
brand: "Enlightened Equipment",
manufacturerSlug: "enlightened-equipment",
model: "Enigma 20F",
category: "sleep",
weightGrams: 567,
@@ -126,7 +147,7 @@ export const DEV_GLOBAL_ITEMS = [
"20F down quilt with 850FP DownTek water-resistant fill, sewn footbox option.",
},
{
brand: "Therm-a-Rest",
manufacturerSlug: "therm-a-rest",
model: "NeoAir XLite NXT",
category: "sleep",
weightGrams: 354,
@@ -135,7 +156,7 @@ export const DEV_GLOBAL_ITEMS = [
"R-value 4.5 ultralight inflatable sleeping pad with ThermaCapture reflective technology.",
},
{
brand: "Nemo",
manufacturerSlug: "nemo",
model: "Tensor Insulated Regular",
category: "sleep",
weightGrams: 425,
@@ -144,7 +165,7 @@ export const DEV_GLOBAL_ITEMS = [
"R-value 4.2 insulated sleeping pad with Spaceframe baffles for stability.",
},
{
brand: "Sea to Summit",
manufacturerSlug: "sea-to-summit",
model: "Aeros Premium Pillow",
category: "sleep",
weightGrams: 79,
@@ -153,7 +174,7 @@ export const DEV_GLOBAL_ITEMS = [
"Brushed 50D polyester inflatable pillow with multifunctional valve.",
},
{
brand: "Western Mountaineering",
manufacturerSlug: "western-mountaineering",
model: "NanoLite 22F",
category: "sleep",
weightGrams: 510,
@@ -164,7 +185,7 @@ export const DEV_GLOBAL_ITEMS = [
// Cooking (indices 15-19)
{
brand: "BRS",
manufacturerSlug: "brs",
model: "BRS-3000T",
category: "cooking",
weightGrams: 25,
@@ -173,7 +194,7 @@ export const DEV_GLOBAL_ITEMS = [
"Ultralight titanium canister stove, 25g with piezo ignition, 2700W output.",
},
{
brand: "Soto",
manufacturerSlug: "soto",
model: "WindMaster",
category: "cooking",
weightGrams: 67,
@@ -182,7 +203,7 @@ export const DEV_GLOBAL_ITEMS = [
"Micro-regulator stove with concave burner head for excellent wind resistance.",
},
{
brand: "Toaks",
manufacturerSlug: "toaks",
model: "Light Titanium 750ml",
category: "cooking",
weightGrams: 86,
@@ -191,7 +212,7 @@ export const DEV_GLOBAL_ITEMS = [
"Titanium pot with graduated measurements, lid, and folding bail handle.",
},
{
brand: "Snow Peak",
manufacturerSlug: "snow-peak",
model: "Ti-Mini Solo Combo",
category: "cooking",
weightGrams: 198,
@@ -200,7 +221,7 @@ export const DEV_GLOBAL_ITEMS = [
"Titanium cookset with 850ml pot, lid/pan, and nesting mug for solo cooking.",
},
{
brand: "MSR",
manufacturerSlug: "msr",
model: "PocketRocket Deluxe",
category: "cooking",
weightGrams: 83,
@@ -211,7 +232,7 @@ export const DEV_GLOBAL_ITEMS = [
// Lighting (indices 20-22)
{
brand: "Nitecore",
manufacturerSlug: "nitecore",
model: "NU25 UL",
category: "lighting",
weightGrams: 28,
@@ -220,7 +241,7 @@ export const DEV_GLOBAL_ITEMS = [
"Rechargeable ultralight headlamp with 400 lumens, red/high-CRI aux LEDs.",
},
{
brand: "Lezyne",
manufacturerSlug: "lezyne",
model: "Lite Drive 1200+",
category: "lighting",
weightGrams: 176,
@@ -229,7 +250,7 @@ export const DEV_GLOBAL_ITEMS = [
"1200 lumen USB-C rechargeable bike light with MOR optical lens design.",
},
{
brand: "Fenix",
manufacturerSlug: "fenix",
model: "HL60R",
category: "lighting",
weightGrams: 134,
@@ -240,7 +261,7 @@ export const DEV_GLOBAL_ITEMS = [
// Tools & Repair (indices 23-25)
{
brand: "Park Tool",
manufacturerSlug: "park-tool",
model: "IB-3",
category: "tools",
weightGrams: 175,
@@ -249,7 +270,7 @@ export const DEV_GLOBAL_ITEMS = [
"Folding hex/Torx multi-tool with 3-6mm hex, T25, Phillips and flathead.",
},
{
brand: "Lezyne",
manufacturerSlug: "lezyne",
model: "CNC Chain Breaker",
category: "tools",
weightGrams: 28,
@@ -258,7 +279,7 @@ export const DEV_GLOBAL_ITEMS = [
"CNC-machined aluminum chain tool compatible with 8-12 speed chains.",
},
{
brand: "Gorilla Tape",
manufacturerSlug: "gorilla-tape",
model: "Mini Duct Tape Roll",
category: "tools",
weightGrams: 30,
@@ -268,7 +289,7 @@ export const DEV_GLOBAL_ITEMS = [
// Clothing (indices 26-28)
{
brand: "Patagonia",
manufacturerSlug: "patagonia",
model: "R1 Air Full-Zip",
category: "clothing",
weightGrams: 266,
@@ -277,7 +298,7 @@ export const DEV_GLOBAL_ITEMS = [
"Breathable midlayer fleece with open-knit R1 Air fabric for high-output activities.",
},
{
brand: "Frogg Toggs",
manufacturerSlug: "frogg-toggs",
model: "Ultra-Lite2 Rain Suit",
category: "clothing",
weightGrams: 340,
@@ -286,7 +307,7 @@ export const DEV_GLOBAL_ITEMS = [
"Budget ultralight rain jacket and pants set, DriPore breathable material.",
},
{
brand: "Buff",
manufacturerSlug: "buff",
model: "Merino Wool Multifunctional",
category: "clothing",
weightGrams: 43,
@@ -297,7 +318,7 @@ export const DEV_GLOBAL_ITEMS = [
// Water (indices 29-31)
{
brand: "Sawyer",
manufacturerSlug: "sawyer",
model: "Squeeze SP129",
category: "water",
weightGrams: 85,
@@ -306,7 +327,7 @@ export const DEV_GLOBAL_ITEMS = [
"0.1 micron hollow-fiber water filter with high flow rate and backflush capability.",
},
{
brand: "Katadyn",
manufacturerSlug: "katadyn",
model: "BeFree 1L",
category: "water",
weightGrams: 63,
@@ -315,7 +336,7 @@ export const DEV_GLOBAL_ITEMS = [
"EZ-Clean membrane filter with collapsible Hydrapak flask, 2L/min flow rate.",
},
{
brand: "HydraPak",
manufacturerSlug: "hydrapak",
model: "Seeker 2L",
category: "water",
weightGrams: 76,
@@ -326,7 +347,7 @@ export const DEV_GLOBAL_ITEMS = [
// Electronics (indices 32-33)
{
brand: "Anker",
manufacturerSlug: "anker",
model: "Nano Power Bank 10000 PD",
category: "electronics",
weightGrams: 220,
@@ -335,7 +356,7 @@ export const DEV_GLOBAL_ITEMS = [
"10000mAh 30W USB-C PD power bank with built-in display and passthrough charging.",
},
{
brand: "Garmin",
manufacturerSlug: "garmin",
model: "inReach Mini 2",
category: "electronics",
weightGrams: 100,
@@ -346,7 +367,7 @@ export const DEV_GLOBAL_ITEMS = [
// Navigation (indices 34-35)
{
brand: "Wahoo",
manufacturerSlug: "wahoo",
model: "ELEMNT BOLT V2",
category: "navigation",
weightGrams: 68,
@@ -355,7 +376,7 @@ export const DEV_GLOBAL_ITEMS = [
"GPS cycling computer with color display, turn-by-turn navigation, and smart trainer integration.",
},
{
brand: "Ortlieb",
manufacturerSlug: "ortlieb",
model: "Ultimate Six Classic",
category: "navigation",
weightGrams: 500,