# Proposal: Remove Unnecessary Normalizers ## Problem We have unnecessary abstraction layers that convert between identical data structures multiple times: ``` Frontend State → build*Selections() → OrderSelections → toSearchParams() → URLSearchParams → paramsToRecord() → normalizeSelections() → OrderSelections → BFF ``` ## Unnecessary Functions to Remove ### 1. `packages/domain/orders/checkout.ts` **Remove these:** - `buildInternetCheckoutSelections()` - Lines 103-129 - `deriveInternetCheckoutState()` - Lines 134-156 - `buildSimCheckoutSelections()` - Lines 161-216 - `deriveSimCheckoutState()` - Lines 221-282 - `coalescePlanSku()` - Lines 81-97 (now obsolete after plan/planSku cleanup) - `normalizeString()` - Lines 56-60 - `normalizeSkuList()` - Lines 62-71 - `parseAddonList()` - Lines 73-79 - All Draft/Patch interfaces - Lines 10-54 **Keep:** - Nothing from this file is needed in domain layer ### 2. `apps/portal/src/features/catalog/services/catalog.store.ts` **Simplify:** - `buildInternetCheckoutParams()` - Lines 202-217 - `buildSimCheckoutParams()` - Lines 219-238 - `selectionsToSearchParams()` - Lines 124-136 - `paramsToSelectionRecord()` - Lines 114-122 **Replace with:** Direct URL param construction from state ## What Frontend Should Do Instead ### For Internet Checkout: ```typescript // BEFORE (current mess): const selections = buildInternetCheckoutSelections({ planSku: internet.planSku, accessMode: internet.accessMode, installationSku: internet.installationSku, addonSkus: internet.addonSkus, }); return selectionsToSearchParams(selections, "internet"); // AFTER (clean): const params = new URLSearchParams({ type: "internet", planSku: internet.planSku, accessMode: internet.accessMode, installationSku: internet.installationSku, addons: internet.addonSkus.join(","), // Only transform is array → CSV }); return params; ``` ### For SIM Checkout: ```typescript // BEFORE: const selections = buildSimCheckoutSelections({...}); return selectionsToSearchParams(selections, "sim"); // AFTER: const params = new URLSearchParams(); params.set("type", "sim"); params.set("planSku", sim.planSku); if (sim.simType) params.set("simType", sim.simType); // ... only add non-empty values return params; ``` ### For Restoring from Params: ```typescript // BEFORE: const selections = normalizeOrderSelections(paramsToSelectionRecord(params)); const derived = deriveInternetCheckoutState(selections); set({ internet: { ...state.internet, ...derived } }); // AFTER: set({ internet: { planSku: params.get("planSku") ?? undefined, accessMode: params.get("accessMode") ?? undefined, installationSku: params.get("installationSku") ?? undefined, addonSkus: params.get("addons")?.split(",") ?? [], } }); ``` ## Benefits 1. **Fewer lines of code** - Remove ~300+ lines 2. **Clearer data flow** - No mysterious transformations 3. **Better type safety** - Direct property access, not dynamic string manipulation 4. **Easier debugging** - Fewer layers to trace through 5. **Frontend owns frontend data** - Domain layer isn't polluted with UI concerns ## What Domain Layer SHOULD Have Only these helpers: - `normalizeOrderSelections(value: unknown): OrderSelections` - Zod validation from API/params - `buildOrderConfigurations(selections: OrderSelections): OrderConfigurations` - Extract config from selections That's it! Frontend handles its own URL param serialization. ## Migration Plan 1. Update catalog store to directly build URL params 2. Update checkout param service to directly parse params 3. Remove all build/derive functions from domain 4. Remove Draft/Patch interfaces 5. Test all checkout flows (Internet, SIM, VPN) ## Files to Change ### Remove entirely: - Most of `packages/domain/orders/checkout.ts` (keep only types if needed) ### Simplify: - `apps/portal/src/features/catalog/services/catalog.store.ts` - `apps/portal/src/features/checkout/services/checkout-params.service.ts` ### Update imports in: - `apps/portal/src/features/catalog/hooks/useInternetConfigure.ts` - `apps/portal/src/features/catalog/hooks/useSimConfigure.ts` - Any component using these functions