a metric shit ton. fixed a lot of part_role issues. removed almost all hardcoded categories and used db roles.

This commit is contained in:
2025-12-15 20:59:19 -05:00
parent 0f10ff4e09
commit 607939c468
16 changed files with 1538 additions and 1065 deletions
+56 -10
View File
@@ -1,11 +1,27 @@
import type { CategoryId } from "@/types/gunbuilder";
/**
* Normalize backend part roles into a canonical kebab-case form.
* - trims whitespace
* - lowercases
* - converts snake_case / ENUM_CASE to kebab-case
*/
export const normalizePartRole = (role: string) =>
role.trim().toLowerCase().replace(/_/g, "-");
/**
* Maps canonical kebab-case CategoryIds to their associated part roles from the backend.
*
* Notes:
* - Keep the list here as the *source of truth*.
* - The derived `PART_ROLE_TO_CATEGORY` map below stores both the original and normalized keys.
*/
export const CATEGORY_TO_PART_ROLES: Partial<Record<CategoryId, string[]>> = {
// ===== UPPER =====
upper: ["upper-receiver", "upper"],
"upper-receiver": ["upper-receiver"],
// (optional) Back-compat if anything still uses the old ids:
// upper: ["upper-receiver", "upper"],
"complete-upper": ["complete-upper"],
barrel: ["barrel"],
"gas-block": ["gas-block"],
@@ -17,7 +33,10 @@ export const CATEGORY_TO_PART_ROLES: Partial<Record<CategoryId, string[]>> = {
bcg: ["bcg", "bolt-carrier-group"],
// ===== LOWER =====
"lower-receiver": ["lower-receiver", "lower", "LOWER_RECEIVER_STRIPPED"],
// (optional) Back-compat if anything still uses the old ids:
lower: ["lower-receiver", "lower", "LOWER_RECEIVER_STRIPPED"],
"complete-lower": ["complete-lower"],
"lower-parts": ["lower-parts-kit", "lower-parts"],
trigger: ["trigger", "trigger-kit"],
@@ -32,24 +51,51 @@ export const CATEGORY_TO_PART_ROLES: Partial<Record<CategoryId, string[]>> = {
// ===== ACCESSORIES =====
magazine: ["magazine", "mag", "magazine-ar15", "magazine-308", "drum-magazine"],
"weapon-light": ["weapon-light", "light", "weapon-light-laser", "light-laser-combo", "laser"],
"weapon-light": [
"weapon-light",
"light",
"weapon-light-laser",
"light-laser-combo",
"laser",
],
foregrip: ["vertical-grip", "angled-foregrip", "foregrip", "handstop"],
bipod: ["bipod"],
sling: ["sling", "sling-mount", "sling-swivel", "qd-sling-mount"],
"rail-accessory": ["rail-section", "picatinny-rail-section", "m-lok-rail-section", "keymod-rail-section", "rail-cover", "rail-panel"],
tools: ["tool", "armorer-tool", "armorer-wrench", "cleaning-kit", "bore-snake", "vise-block", "torque-wrench"],
"rail-accessory": [
"rail-section",
"picatinny-rail-section",
"m-lok-rail-section",
"keymod-rail-section",
"rail-cover",
"rail-panel",
],
tools: [
"tool",
"armorer-tool",
"armorer-wrench",
"cleaning-kit",
"bore-snake",
"vise-block",
"torque-wrench",
],
};
/**
* Reverse lookup: backend partRole -> CategoryId.
*
* Implementation details:
* - Stores BOTH the original role and its normalized version as keys.
* - De-dupes role lists per category.
*/
export const PART_ROLE_TO_CATEGORY: Record<string, CategoryId> = Object.entries(
CATEGORY_TO_PART_ROLES
).reduce((acc, [categoryId, roles]) => {
for (const role of roles) {
// store the original string
acc[role] = categoryId as CategoryId;
const unique = Array.from(new Set(roles ?? []));
// also store a normalized version (handles ENUM_CASE and snake_case)
const normalized = role.trim().toLowerCase().replace(/_/g, "-");
acc[normalized] = categoryId as CategoryId;
for (const role of unique) {
acc[role] = categoryId as CategoryId;
acc[normalizePartRole(role)] = categoryId as CategoryId;
}
return acc;
}, {} as Record<string, CategoryId>);