diff --git a/src/routes/settings.import.tsx b/src/routes/settings.import.tsx index 00d1060..1949ed0 100644 --- a/src/routes/settings.import.tsx +++ b/src/routes/settings.import.tsx @@ -92,97 +92,43 @@ const toDateTime = (v: any): string | null => { }; const IMPORTERS: ImporterConfig[] = [ - // Companies → clients + // Unified Contacts importer (all groups). When group=client, also mirrors into clients table. { - key: "companies", - label: "Companies → Clients", - description: "HOAs and corporate clients.", - table: "clients", - conflict: "external_id", - required: ["name"], - aliases: { - id: "external_id", companyid: "external_id", externalid: "external_id", - name: "name", companyname: "name", company: "name", - type: "client_type", clienttype: "client_type", - addressline1: "address_line1", address1: "address_line1", address: "address_line1", - addressline2: "address_line2", address2: "address_line2", - city: "city", state: "state", - zip: "postal_code", zipcode: "postal_code", postalcode: "postal_code", - phone: "primary_contact_phone", primaryphone: "primary_contact_phone", - email: "primary_contact_email", primaryemail: "primary_contact_email", - contactname: "primary_contact_name", primarycontact: "primary_contact_name", - management: "management_company", managementcompany: "management_company", - units: "num_units", numunits: "num_units", - notes: "notes", - archived: "_archived", isarchived: "_archived", status: "_archived", - }, - numeric: ["num_units", "annual_interest_rate"], - transform: (r) => { - const t = String(r.client_type ?? "").toLowerCase(); - r.client_type = t.includes("condo") ? "condo" : t.includes("hoa") ? "hoa" : "hoa"; - return r; - }, - postInsert: (rows, ctx) => { - for (const r of rows) { - if (r.external_id && r.id) ctx.clientByExt.set(r.external_id, r.id); - if (r.name && r.id) ctx.clientByName.set(r.name.toLowerCase(), r.id); - } - }, - }, - // People → contacts - { - key: "people", - label: "People → Contacts", - description: "Individual contacts (board members, vendors, etc.).", + key: "contacts", + label: "Contacts → Contacts", + description: "Upload one CSV per contact group. Rows tagged 'Client' also get mirrored into the Clients table.", table: "contacts", conflict: "external_id", required: ["name"], aliases: { - id: "external_id", personid: "external_id", externalid: "external_id", - name: "name", fullname: "name", + id: "external_id", contactid: "external_id", personid: "external_id", companyid: "external_id", externalid: "external_id", + name: "name", fullname: "name", companyname: "name", firstname: "_first", lastname: "_last", - email: "email", phone: "phone", - company: "company", title: "title", - addressline1: "address_line1", address1: "address_line1", address: "address_line1", - addressline2: "address_line2", address2: "address_line2", - city: "city", state: "state", + email: "email", emailaddress: "email", + phone: "phone", phonenumber: "phone", mobile: "phone", + company: "company", firm: "company", organization: "company", + title: "title", role: "title", + addressline1: "address_line1", address1: "address_line1", address: "address_line1", street: "address_line1", + addressline2: "address_line2", address2: "address_line2", suite: "address_line2", apt: "address_line2", + city: "city", state: "state", province: "state", zip: "postal_code", zipcode: "postal_code", postalcode: "postal_code", type: "contact_type", contacttype: "contact_type", - notes: "notes", + notes: "notes", comments: "notes", archived: "_archived", isarchived: "_archived", }, - transform: (r) => { + transform: (r, ctx) => { if (!r.name && (r._first || r._last)) { r.name = [r._first, r._last].filter(Boolean).join(" ").trim(); } delete r._first; delete r._last; - if (!r.contact_type) r.contact_type = "other"; + // Force the group selected by the user (overrides any per-row contact_type column) + r.contact_type = ctx.defaultContactType || r.contact_type || "other"; return r; }, - }, - // Lawyers → contacts (type=attorney) - { - key: "lawyers", - label: "Lawyers → Contacts", - description: "Opposing counsel & external attorneys (added as contacts).", - table: "contacts", - conflict: "external_id", - required: ["name"], - aliases: { - id: "external_id", lawyerid: "external_id", externalid: "external_id", - name: "name", fullname: "name", - firstname: "_first", lastname: "_last", - email: "email", phone: "phone", - firm: "company", company: "company", - addressline1: "address_line1", address: "address_line1", - city: "city", state: "state", zip: "postal_code", postalcode: "postal_code", - notes: "notes", - }, - transform: (r) => { - if (!r.name && (r._first || r._last)) r.name = [r._first, r._last].filter(Boolean).join(" ").trim(); - delete r._first; delete r._last; - r.contact_type = "attorney"; - return r; + postInsert: (rows, ctx) => { + for (const r of rows) { + if (r.external_id && r.id) ctx.contactByExt.set(r.external_id, r.id); + } }, }, // Locations → homeowners (units)