Files
GearBox/src/db/dev-seed-data.ts
Jean-Luc Makiola 44b1eac0ba 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>
2026-04-18 16:37:27 +02:00

1117 lines
28 KiB
TypeScript

// ── Dev Seed Data ──────────────────────────────────────────────────
// All seed data as typed constants for local development.
// Realistic bikepacking gear with accurate weights and prices.
// ── Categories ─────────────────────────────────────────────────────
export const DEV_CATEGORIES = [
{ name: "Bags", icon: "briefcase" },
{ name: "Shelter", icon: "tent" },
{ name: "Sleep System", icon: "moon" },
{ name: "Cooking", icon: "flame" },
{ name: "Lighting", icon: "flashlight" },
{ name: "Tools & Repair", icon: "wrench" },
{ name: "Clothing", icon: "shirt" },
{ name: "Water", icon: "droplets" },
{ name: "Electronics", icon: "battery" },
{ 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)
{
manufacturerSlug: "revelate-designs",
model: "Terrapin System",
category: "bags",
weightGrams: 529,
priceCents: 18500,
description:
"Waterproof saddle bag with 14L capacity, roll-top closure, and integrated seat bag mount.",
},
{
manufacturerSlug: "apidura",
model: "Expedition Handlebar Pack",
category: "bags",
weightGrams: 300,
priceCents: 16000,
description:
"14L waterproof handlebar roll bag with internal dry bag and accessory pocket.",
},
{
manufacturerSlug: "ortlieb",
model: "Frame-Pack RC",
category: "bags",
weightGrams: 250,
priceCents: 12000,
description:
"6L waterproof roll-closure frame bag with TIZIP zipper for full-frame bikes.",
},
{
manufacturerSlug: "rockgeist",
model: "BarJam",
category: "bags",
weightGrams: 142,
priceCents: 9900,
description:
"Ultralight handlebar harness with side-loading dry bag compatibility.",
},
{
manufacturerSlug: "oveja-negra",
model: "Superwedgie",
category: "bags",
weightGrams: 170,
priceCents: 7500,
description:
"Half-frame bag with easy-access zipper and internal organization.",
},
{
manufacturerSlug: "apidura",
model: "Racing Top Tube Pack",
category: "bags",
weightGrams: 72,
priceCents: 5500,
description:
"Bolt-on 1L top tube pack for nutrition and essentials during racing.",
},
// Shelter (indices 6-9)
{
manufacturerSlug: "zpacks",
model: "Duplex",
category: "shelter",
weightGrams: 539,
priceCents: 67900,
description:
"Dyneema Composite Fabric two-person trekking pole shelter, freestanding with optional poles.",
},
{
manufacturerSlug: "tarptent",
model: "Stratospire Li",
category: "shelter",
weightGrams: 737,
priceCents: 62500,
description:
"Two-person double-wall tent in Dyneema with dual vestibules and excellent ventilation.",
},
{
manufacturerSlug: "durston",
model: "X-Mid 1 Solid",
category: "shelter",
weightGrams: 880,
priceCents: 22000,
description:
"Single-wall silpoly trekking pole tent with symmetrical design and two vestibules.",
},
{
manufacturerSlug: "big-agnes",
model: "Copper Spur HV UL1",
category: "shelter",
weightGrams: 936,
priceCents: 42000,
description:
"Freestanding ultralight one-person tent with high-volume architecture and DAC poles.",
},
// Sleep System (indices 10-14)
{
manufacturerSlug: "enlightened-equipment",
model: "Enigma 20F",
category: "sleep",
weightGrams: 567,
priceCents: 35500,
description:
"20F down quilt with 850FP DownTek water-resistant fill, sewn footbox option.",
},
{
manufacturerSlug: "therm-a-rest",
model: "NeoAir XLite NXT",
category: "sleep",
weightGrams: 354,
priceCents: 21000,
description:
"R-value 4.5 ultralight inflatable sleeping pad with ThermaCapture reflective technology.",
},
{
manufacturerSlug: "nemo",
model: "Tensor Insulated Regular",
category: "sleep",
weightGrams: 425,
priceCents: 17000,
description:
"R-value 4.2 insulated sleeping pad with Spaceframe baffles for stability.",
},
{
manufacturerSlug: "sea-to-summit",
model: "Aeros Premium Pillow",
category: "sleep",
weightGrams: 79,
priceCents: 4500,
description:
"Brushed 50D polyester inflatable pillow with multifunctional valve.",
},
{
manufacturerSlug: "western-mountaineering",
model: "NanoLite 22F",
category: "sleep",
weightGrams: 510,
priceCents: 46000,
description:
"Premium 850+ FP goose down mummy bag with continuous baffles and draft collar.",
},
// Cooking (indices 15-19)
{
manufacturerSlug: "brs",
model: "BRS-3000T",
category: "cooking",
weightGrams: 25,
priceCents: 2000,
description:
"Ultralight titanium canister stove, 25g with piezo ignition, 2700W output.",
},
{
manufacturerSlug: "soto",
model: "WindMaster",
category: "cooking",
weightGrams: 67,
priceCents: 7500,
description:
"Micro-regulator stove with concave burner head for excellent wind resistance.",
},
{
manufacturerSlug: "toaks",
model: "Light Titanium 750ml",
category: "cooking",
weightGrams: 86,
priceCents: 3200,
description:
"Titanium pot with graduated measurements, lid, and folding bail handle.",
},
{
manufacturerSlug: "snow-peak",
model: "Ti-Mini Solo Combo",
category: "cooking",
weightGrams: 198,
priceCents: 5500,
description:
"Titanium cookset with 850ml pot, lid/pan, and nesting mug for solo cooking.",
},
{
manufacturerSlug: "msr",
model: "PocketRocket Deluxe",
category: "cooking",
weightGrams: 83,
priceCents: 6000,
description:
"Pressure-regulated canister stove with built-in wind clip and push-start ignition.",
},
// Lighting (indices 20-22)
{
manufacturerSlug: "nitecore",
model: "NU25 UL",
category: "lighting",
weightGrams: 28,
priceCents: 3600,
description:
"Rechargeable ultralight headlamp with 400 lumens, red/high-CRI aux LEDs.",
},
{
manufacturerSlug: "lezyne",
model: "Lite Drive 1200+",
category: "lighting",
weightGrams: 176,
priceCents: 8500,
description:
"1200 lumen USB-C rechargeable bike light with MOR optical lens design.",
},
{
manufacturerSlug: "fenix",
model: "HL60R",
category: "lighting",
weightGrams: 134,
priceCents: 7000,
description:
"950 lumen rechargeable headlamp with neutral white LED and red light mode.",
},
// Tools & Repair (indices 23-25)
{
manufacturerSlug: "park-tool",
model: "IB-3",
category: "tools",
weightGrams: 175,
priceCents: 3500,
description:
"Folding hex/Torx multi-tool with 3-6mm hex, T25, Phillips and flathead.",
},
{
manufacturerSlug: "lezyne",
model: "CNC Chain Breaker",
category: "tools",
weightGrams: 28,
priceCents: 2300,
description:
"CNC-machined aluminum chain tool compatible with 8-12 speed chains.",
},
{
manufacturerSlug: "gorilla-tape",
model: "Mini Duct Tape Roll",
category: "tools",
weightGrams: 30,
priceCents: 500,
description: "1-inch wide mini roll for emergency repairs, 5-yard length.",
},
// Clothing (indices 26-28)
{
manufacturerSlug: "patagonia",
model: "R1 Air Full-Zip",
category: "clothing",
weightGrams: 266,
priceCents: 15900,
description:
"Breathable midlayer fleece with open-knit R1 Air fabric for high-output activities.",
},
{
manufacturerSlug: "frogg-toggs",
model: "Ultra-Lite2 Rain Suit",
category: "clothing",
weightGrams: 340,
priceCents: 2500,
description:
"Budget ultralight rain jacket and pants set, DriPore breathable material.",
},
{
manufacturerSlug: "buff",
model: "Merino Wool Multifunctional",
category: "clothing",
weightGrams: 43,
priceCents: 2800,
description:
"Seamless 100% merino wool neck gaiter with natural odor resistance.",
},
// Water (indices 29-31)
{
manufacturerSlug: "sawyer",
model: "Squeeze SP129",
category: "water",
weightGrams: 85,
priceCents: 3500,
description:
"0.1 micron hollow-fiber water filter with high flow rate and backflush capability.",
},
{
manufacturerSlug: "katadyn",
model: "BeFree 1L",
category: "water",
weightGrams: 63,
priceCents: 4500,
description:
"EZ-Clean membrane filter with collapsible Hydrapak flask, 2L/min flow rate.",
},
{
manufacturerSlug: "hydrapak",
model: "Seeker 2L",
category: "water",
weightGrams: 76,
priceCents: 1600,
description:
"Ultralight collapsible water storage with wide mouth and Plug-N-Play cap.",
},
// Electronics (indices 32-33)
{
manufacturerSlug: "anker",
model: "Nano Power Bank 10000 PD",
category: "electronics",
weightGrams: 220,
priceCents: 3000,
description:
"10000mAh 30W USB-C PD power bank with built-in display and passthrough charging.",
},
{
manufacturerSlug: "garmin",
model: "inReach Mini 2",
category: "electronics",
weightGrams: 100,
priceCents: 39999,
description:
"Satellite communicator with SOS, two-way messaging, tracking, and weather forecasts.",
},
// Navigation (indices 34-35)
{
manufacturerSlug: "wahoo",
model: "ELEMNT BOLT V2",
category: "navigation",
weightGrams: 68,
priceCents: 27999,
description:
"GPS cycling computer with color display, turn-by-turn navigation, and smart trainer integration.",
},
{
manufacturerSlug: "ortlieb",
model: "Ultimate Six Classic",
category: "navigation",
weightGrams: 500,
priceCents: 9000,
description:
"5L handlebar bag with integrated map case and magnetic closure, IP64 rated.",
},
] as const;
// ── Tag Assignments ────────────────────────────────────────────────
// Maps global item index -> tag names. Tags are seeded by seedGlobalItems().
export const DEV_TAG_ASSIGNMENTS = [
// Bags — bikepacking/cycling gear
{
globalItemIndex: 0,
tagNames: ["saddlebag", "bike-bag", "bikepacking", "cycling"],
},
{
globalItemIndex: 1,
tagNames: ["handlebar-bag", "bike-bag", "bikepacking", "cycling"],
},
{
globalItemIndex: 2,
tagNames: ["framebag", "bike-bag", "bikepacking", "cycling"],
},
{
globalItemIndex: 3,
tagNames: ["handlebar-bag", "bike-bag", "bikepacking", "cycling"],
},
{
globalItemIndex: 4,
tagNames: ["framebag", "bike-bag", "bikepacking", "cycling"],
},
{
globalItemIndex: 5,
tagNames: ["top-tube-bag", "bike-bag", "bikepacking", "cycling"],
},
// Shelter — camping/hiking/bikepacking
{
globalItemIndex: 6,
tagNames: ["tent", "camping", "hiking", "bikepacking", "backpacking"],
},
{
globalItemIndex: 7,
tagNames: ["tent", "camping", "hiking", "bikepacking", "backpacking"],
},
{
globalItemIndex: 8,
tagNames: ["tent", "camping", "hiking", "backpacking"],
},
{
globalItemIndex: 9,
tagNames: [
"tent",
"camping",
"hiking",
"backpacking",
"climbing",
"mountaineering",
],
},
// Sleep — camping/hiking/bikepacking
{
globalItemIndex: 10,
tagNames: ["quilt", "camping", "hiking", "bikepacking", "backpacking"],
},
{
globalItemIndex: 11,
tagNames: [
"sleeping-pad",
"camping",
"hiking",
"bikepacking",
"backpacking",
],
},
{
globalItemIndex: 12,
tagNames: ["sleeping-pad", "camping", "hiking", "backpacking"],
},
{
globalItemIndex: 13,
tagNames: ["pillow", "camping", "hiking", "bikepacking", "backpacking"],
},
{
globalItemIndex: 14,
tagNames: ["sleeping-bag", "camping", "hiking", "backpacking", "climbing"],
},
// Cooking — camping/hiking/bikepacking
{
globalItemIndex: 15,
tagNames: ["stove", "camping", "hiking", "bikepacking", "backpacking"],
},
{
globalItemIndex: 16,
tagNames: ["stove", "camping", "hiking", "backpacking"],
},
{
globalItemIndex: 17,
tagNames: ["cookware", "mug", "camping", "hiking", "bikepacking"],
},
{
globalItemIndex: 18,
tagNames: ["cookware", "camping", "hiking", "backpacking"],
},
{
globalItemIndex: 19,
tagNames: ["stove", "camping", "hiking", "backpacking", "climbing"],
},
// Lighting — general outdoor
{
globalItemIndex: 20,
tagNames: [
"headlamp",
"camping",
"hiking",
"climbing",
"backpacking",
"running",
"trail-running",
],
},
{
globalItemIndex: 21,
tagNames: [
"bike-light",
"bikepacking",
"cycling",
"road-cycling",
"gravel",
],
},
{
globalItemIndex: 22,
tagNames: ["headlamp", "camping", "hiking", "climbing", "backpacking"],
},
// Water — hiking/camping/bikepacking
{
globalItemIndex: 29,
tagNames: [
"water-filter",
"hiking",
"camping",
"bikepacking",
"backpacking",
],
},
{
globalItemIndex: 30,
tagNames: ["water-filter", "hiking", "camping", "backpacking"],
},
{
globalItemIndex: 31,
tagNames: ["water-bottle", "hiking", "camping", "cycling", "running"],
},
// Tools — bikepacking/cycling
{
globalItemIndex: 32,
tagNames: ["multi-tool", "repair-kit", "bikepacking", "cycling"],
},
// Clothing — general outdoor
{
globalItemIndex: 33,
tagNames: [
"rain-jacket",
"hiking",
"camping",
"bikepacking",
"climbing",
"running",
],
},
// Electronics — bikepacking/cycling
{
globalItemIndex: 34,
tagNames: ["bike-computer", "gps", "bikepacking", "cycling", "gravel"],
},
{
globalItemIndex: 35,
tagNames: [
"handlebar-bag",
"bike-bag",
"dry-bag",
"bikepacking",
"cycling",
],
},
] as const;
// ── Category name mapping (for FK lookups by category name) ────────
const CATEGORY_MAP: Record<string, string> = {
bags: "Bags",
shelter: "Shelter",
sleep: "Sleep System",
cooking: "Cooking",
lighting: "Lighting",
tools: "Tools & Repair",
clothing: "Clothing",
water: "Water",
electronics: "Electronics",
navigation: "Navigation",
};
export function categoryDisplayName(seedCategory: string): string {
return CATEGORY_MAP[seedCategory] ?? seedCategory;
}
// ── User Items ─────────────────────────────────────────────────────
// globalItemIndex: index into DEV_GLOBAL_ITEMS (null = standalone item)
// categoryName: matches DEV_CATEGORIES name for FK lookup
export const DEV_USER_ITEMS = [
// Catalog-linked items (10)
{
globalItemIndex: 0 as number | null,
categoryName: "Bags",
name: "Revelate Designs Terrapin System",
weightGrams: 529,
priceCents: 18500,
purchasePriceCents: 16200,
notes: "Bought used on r/BikeparkingMarket, great condition.",
quantity: 1,
},
{
globalItemIndex: 2,
categoryName: "Bags",
name: "Ortlieb Frame-Pack RC",
weightGrams: 250,
priceCents: 12000,
purchasePriceCents: 12000,
notes: null,
quantity: 1,
},
{
globalItemIndex: 5,
categoryName: "Bags",
name: "Apidura Racing Top Tube Pack",
weightGrams: 72,
priceCents: 5500,
purchasePriceCents: 4900,
notes: null,
quantity: 1,
},
{
globalItemIndex: 8,
categoryName: "Shelter",
name: "Durston X-Mid 1 Solid",
weightGrams: 880,
priceCents: 22000,
purchasePriceCents: 22000,
notes: "Drop 2 batch, arrived March 2025.",
quantity: 1,
},
{
globalItemIndex: 10,
categoryName: "Sleep System",
name: "Enlightened Equipment Enigma 20F",
weightGrams: 567,
priceCents: 35500,
purchasePriceCents: 31000,
notes: "Custom order: 20F, 850FP, regular/regular, teal/charcoal.",
quantity: 1,
},
{
globalItemIndex: 11,
categoryName: "Sleep System",
name: "Therm-a-Rest NeoAir XLite NXT",
weightGrams: 354,
priceCents: 21000,
purchasePriceCents: null,
notes: null,
quantity: 1,
},
{
globalItemIndex: 15,
categoryName: "Cooking",
name: "BRS BRS-3000T",
weightGrams: 25,
priceCents: 2000,
purchasePriceCents: 1800,
notes: null,
quantity: 1,
},
{
globalItemIndex: 20,
categoryName: "Lighting",
name: "Nitecore NU25 UL",
weightGrams: 28,
priceCents: 3600,
purchasePriceCents: 3600,
notes: "Swapped stock strap for Litesmith strap (-5g).",
quantity: 1,
},
{
globalItemIndex: 29,
categoryName: "Water",
name: "Sawyer Squeeze SP129",
weightGrams: 85,
priceCents: 3500,
purchasePriceCents: 3500,
notes: null,
quantity: 1,
},
{
globalItemIndex: 34,
categoryName: "Navigation",
name: "Wahoo ELEMNT BOLT V2",
weightGrams: 68,
priceCents: 27999,
purchasePriceCents: 23999,
notes: "Refurbished from Wahoo directly.",
quantity: 1,
},
// Standalone items (7) - no global item link
{
globalItemIndex: null,
categoryName: "Bags",
name: "Custom Frame Bag (Wanderlust Gear Co)",
weightGrams: 145,
priceCents: 8500,
purchasePriceCents: 8500,
notes: "Custom-fitted to Surly Bridge Club 54cm frame.",
quantity: 1,
},
{
globalItemIndex: null,
categoryName: "Cooking",
name: "Folding Titanium Spork",
weightGrams: 18,
priceCents: 1200,
purchasePriceCents: null,
notes: null,
quantity: 2,
},
{
globalItemIndex: null,
categoryName: "Tools & Repair",
name: "Spare Inner Tubes 700x28-35",
weightGrams: 125,
priceCents: 800,
purchasePriceCents: null,
notes: "Schwalbe SV17, presta valve.",
quantity: 2,
},
{
globalItemIndex: null,
categoryName: "Clothing",
name: "Pearl Izumi AmFIB Lobster Gloves",
weightGrams: 180,
priceCents: 6000,
purchasePriceCents: 4500,
notes: "Essential for shoulder-season rides below 5C.",
quantity: 1,
},
{
globalItemIndex: null,
categoryName: "Electronics",
name: "USB-C to Micro-USB Adapter",
weightGrams: 3,
priceCents: 500,
purchasePriceCents: null,
notes: "For charging Garmin inReach Mini 2.",
quantity: 2,
},
{
globalItemIndex: null,
categoryName: "Sleep System",
name: "Sea to Summit Aeros UL Pillow",
weightGrams: 60,
priceCents: 4000,
purchasePriceCents: 3800,
notes: null,
quantity: 1,
},
{
globalItemIndex: null,
categoryName: "Water",
name: "Nalgene Wide Mouth 1L",
weightGrams: 179,
priceCents: 1200,
purchasePriceCents: null,
notes:
"Backup water carry, also doubles as hot water bottle in sleep system.",
quantity: 1,
},
] as const;
// ── Threads ────────────────────────────────────────────────────────
export const DEV_THREADS = [
{
name: "Handlebar Bag Upgrade",
status: "active",
categoryName: "Bags",
candidates: [
{
name: "Apidura Expedition Handlebar Pack",
globalItemIndex: 1 as number | null,
weightGrams: 300,
priceCents: 16000,
status: "researching",
pros: "Proven waterproof design, 14L capacity, integrated dry bag",
cons: "Heavier than competitors, price premium",
notes: "Widely used in ultra-endurance racing.",
sortOrder: 1,
},
{
name: "Rockgeist BarJam",
globalItemIndex: 3,
weightGrams: 142,
priceCents: 9900,
status: "researching",
pros: "Ultra-light, modular, supports various dry bags",
cons: "Requires separate dry bag, less total protection",
notes: "Need to factor in dry bag weight.",
sortOrder: 2,
},
{
name: "Oveja Negra Bootlegger 2.0",
globalItemIndex: null,
weightGrams: 200,
priceCents: 11500,
status: "researching",
pros: "Good build quality, middle-weight option",
cons: "Smaller capacity than Apidura",
notes: null,
sortOrder: 3,
},
],
},
{
name: "Navigation Computer",
status: "active",
categoryName: "Navigation",
candidates: [
{
name: "Wahoo ELEMNT ROAM V2",
globalItemIndex: null,
weightGrams: 95,
priceCents: 39999,
status: "researching",
pros: "Color display, long battery, excellent navigation",
cons: "Expensive, heavier than BOLT",
notes: "Considering upgrading from BOLT V2.",
sortOrder: 1,
},
{
name: "Hammerhead Karoo 3",
globalItemIndex: null,
weightGrams: 132,
priceCents: 49999,
status: "researching",
pros: "Touchscreen, Android-based, great mapping",
cons: "Heaviest option, most expensive, battery life concerns",
notes: null,
sortOrder: 2,
},
],
},
{
name: "Camp Stove",
status: "resolved",
categoryName: "Cooking",
candidates: [
{
name: "Soto WindMaster",
globalItemIndex: 16 as number | null,
weightGrams: 67,
priceCents: 7500,
status: "arrived",
pros: "Excellent wind performance, micro-regulator, reliable ignition",
cons: "Slightly heavier than BRS-3000T",
notes: "Winner! Ordered from REI.",
sortOrder: 1,
},
{
name: "MSR PocketRocket Deluxe",
globalItemIndex: 19,
weightGrams: 83,
priceCents: 6000,
status: "researching",
pros: "Pressure regulator, push-start ignition",
cons: "Heaviest option, no clear wind advantage over Soto",
notes: null,
sortOrder: 2,
},
],
// resolvedCandidateIndex: 0 — the Soto WindMaster wins
resolvedCandidateIndex: 0,
},
] as const;
// ── Setups ─────────────────────────────────────────────────────────
// itemIndices: indices into DEV_USER_ITEMS for FK lookup
export const DEV_SETUPS = [
{
name: "Weekend Overnighter",
visibility: "public" as const,
items: [
{ userItemIndex: 0, classification: "base" }, // Terrapin saddle bag
{ userItemIndex: 3, classification: "base" }, // X-Mid 1
{ userItemIndex: 4, classification: "base" }, // EE Enigma
{ userItemIndex: 5, classification: "base" }, // NeoAir XLite
{ userItemIndex: 6, classification: "consumable" }, // BRS stove
{ userItemIndex: 7, classification: "worn" }, // Nitecore NU25
{ userItemIndex: 8, classification: "consumable" }, // Sawyer Squeeze
{ userItemIndex: 9, classification: "base" }, // Wahoo BOLT
],
},
{
name: "Ultra-Light Day Ride",
visibility: "private" as const,
items: [
{ userItemIndex: 2, classification: "base" }, // Top tube pack
{ userItemIndex: 7, classification: "worn" }, // Nitecore NU25
{ userItemIndex: 9, classification: "base" }, // Wahoo BOLT
{ userItemIndex: 16, classification: "consumable" }, // Nalgene
],
},
] as const;
// ── Market Prices ─────────────────────────────────────────────────
// Multi-market UVP/MSRP prices for global items.
// globalItemIndex references DEV_GLOBAL_ITEMS array positions.
export const DEV_MARKET_PRICES = [
// Revelate Designs Terrapin (index 0)
{
globalItemIndex: 0,
market: "EU",
currency: "EUR",
priceCents: 18500,
source: "manufacturer",
},
{
globalItemIndex: 0,
market: "US",
currency: "USD",
priceCents: 19900,
source: "manufacturer",
},
{
globalItemIndex: 0,
market: "UK",
currency: "GBP",
priceCents: 16500,
source: "manufacturer",
},
// Apidura Expedition Handlebar Pack (index 1)
{
globalItemIndex: 1,
market: "EU",
currency: "EUR",
priceCents: 16000,
source: "manufacturer",
},
{
globalItemIndex: 1,
market: "US",
currency: "USD",
priceCents: 17500,
source: "manufacturer",
},
{
globalItemIndex: 1,
market: "UK",
currency: "GBP",
priceCents: 14000,
source: "manufacturer",
},
// Ortlieb Frame-Pack RC (index 2)
{
globalItemIndex: 2,
market: "EU",
currency: "EUR",
priceCents: 12000,
source: "manufacturer",
},
{
globalItemIndex: 2,
market: "US",
currency: "USD",
priceCents: 14500,
source: "manufacturer",
},
// Zpacks Duplex (index 6) — US brand, different pricing per market
{
globalItemIndex: 6,
market: "US",
currency: "USD",
priceCents: 67900,
source: "manufacturer",
},
{
globalItemIndex: 6,
market: "EU",
currency: "EUR",
priceCents: 72000,
source: "retailer",
},
{
globalItemIndex: 6,
market: "UK",
currency: "GBP",
priceCents: 62000,
source: "retailer",
},
// Tarptent Stratospire Li (index 7)
{
globalItemIndex: 7,
market: "US",
currency: "USD",
priceCents: 62500,
source: "manufacturer",
},
{
globalItemIndex: 7,
market: "EU",
currency: "EUR",
priceCents: 68000,
source: "retailer",
},
// MSR Hubba Hubba (index 8)
{
globalItemIndex: 8,
market: "EU",
currency: "EUR",
priceCents: 49000,
source: "manufacturer",
},
{
globalItemIndex: 8,
market: "US",
currency: "USD",
priceCents: 47000,
source: "manufacturer",
},
{
globalItemIndex: 8,
market: "UK",
currency: "GBP",
priceCents: 42000,
source: "manufacturer",
},
// Enlightened Equipment Enigma (index 10)
{
globalItemIndex: 10,
market: "US",
currency: "USD",
priceCents: 29500,
source: "manufacturer",
},
{
globalItemIndex: 10,
market: "EU",
currency: "EUR",
priceCents: 33000,
source: "retailer",
},
// Therm-a-Rest NeoAir XLite (index 13)
{
globalItemIndex: 13,
market: "EU",
currency: "EUR",
priceCents: 22000,
source: "manufacturer",
},
{
globalItemIndex: 13,
market: "US",
currency: "USD",
priceCents: 21000,
source: "manufacturer",
},
{
globalItemIndex: 13,
market: "UK",
currency: "GBP",
priceCents: 19000,
source: "manufacturer",
},
// BRS-3000T Stove (index 15) — cheap item, big market variance
{
globalItemIndex: 15,
market: "EU",
currency: "EUR",
priceCents: 1500,
source: "retailer",
},
{
globalItemIndex: 15,
market: "US",
currency: "USD",
priceCents: 2000,
source: "retailer",
},
{
globalItemIndex: 15,
market: "UK",
currency: "GBP",
priceCents: 1300,
source: "retailer",
},
// Wahoo ELEMNT BOLT (index 24)
{
globalItemIndex: 24,
market: "EU",
currency: "EUR",
priceCents: 27900,
source: "manufacturer",
},
{
globalItemIndex: 24,
market: "US",
currency: "USD",
priceCents: 27999,
source: "manufacturer",
},
{
globalItemIndex: 24,
market: "UK",
currency: "GBP",
priceCents: 24999,
source: "manufacturer",
},
] as const;
// ── Settings ───────────────────────────────────────────────────────
export const DEV_SETTINGS = [
{ key: "weightUnit", value: "g" },
{ key: "currency", value: "EUR" },
] as const;