import type { User } from "@/lib/types"; const POCKETBASE_RECORD_ID = /^[a-z0-9]{15}$/i; type RepUser = Pick; export interface ResolveRepDisplayNameOptions { /** Expanded `customer.rep` record, when PocketBase returned it. */ expandedCustomerRep?: Partial | null; /** Raw relation id stored in `customer.rep`. */ customerRepId?: string | null; /** Legacy/free-text snapshot stored in `orders.rep`. */ orderRep?: string | null; /** Admin-resolved users, keyed by PocketBase user id. */ usersById?: ReadonlyMap; } function userLabel(user?: Partial | null): string { return (user?.name || user?.email || "").trim(); } /** * Resolves the sales rep shown on order surfaces without ever leaking an * opaque PocketBase record id into the UI. * * Customer ownership is authoritative, so its expanded/user-map value wins. * `orders.rep` remains the fallback because company-only and older orders can * carry a manually entered name there. Some older rows stored a user id in * that text field; those ids are resolved through `usersById`, or hidden when * the related user no longer exists. */ export function resolveRepDisplayName({ expandedCustomerRep, customerRepId, orderRep, usersById, }: ResolveRepDisplayNameOptions): string { const expandedLabel = userLabel(expandedCustomerRep); if (expandedLabel) return expandedLabel; const customerRef = (customerRepId || "").trim(); if (customerRef) { const customerUserLabel = userLabel(usersById?.get(customerRef)); if (customerUserLabel) return customerUserLabel; } const orderValue = (orderRep || "").trim(); if (!orderValue) return ""; const orderUserLabel = userLabel(usersById?.get(orderValue)); if (orderUserLabel) return orderUserLabel; // A free-text name is safe to show. An unresolved PB id is not useful to // an operator, so suppress it instead of regressing to the old ID display. return POCKETBASE_RECORD_ID.test(orderValue) ? "" : orderValue; }