Mapped MyCase CSV headers

X-Lovable-Edit-ID: edt-a1da8be0-9bad-4bca-b10d-c34a4b79f9c5
Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
gpt-engineer-app[bot]
2026-04-19 17:51:12 +00:00
co-authored by renee-png
+37 -8
View File
@@ -190,40 +190,52 @@ const IMPORTERS: ImporterConfig[] = [
conflict: "external_id",
required: ["case_number", "title", "client_id"],
aliases: {
// Identifiers
id: "external_id", caseid: "external_id", externalid: "external_id", mycaseid: "external_id",
casenumber: "case_number", number: "case_number", mattercode: "case_number",
caseno: "case_number", casenum: "case_number",
// Title / matter name
name: "title", title: "title", mattername: "title",
casemattername: "title", casename: "title",
// Client linkage — prefer association name; client number takes precedence over name
companyid: "_clientext", clientid: "_clientext",
clientno: "_clientext", clientnumber: "_clientext",
company: "_clientname", client: "_clientname",
company: "_clientname", client: "_clientname", client1: "_clientname",
communityassociation: "_clientname", associationname: "_clientname",
managementcompany: "_clientname",
managementcompany: "_mgmtcompany",
// Descriptions
description: "description", casedescription: "description",
summary: "case_summary", casesummary: "case_summary",
// Practice area
practicearea: "practice_area", area: "practice_area",
caseinquirytype: "practice_area", representation: "practice_area",
associationtype: "practice_area",
// Status / stage
status: "status", casestage: "status",
// Dates
opened: "opened_at", openedat: "opened_at", dateopened: "opened_at", opendate: "opened_at",
closed: "closed_at", closedat: "closed_at", dateclosed: "closed_at", closeddate: "closed_at",
caseclosed: "_closedflag",
// Court info
court: "court", judge: "judge", jurisdiction: "jurisdiction",
district: "jurisdiction", county: "jurisdiction", countylocation: "jurisdiction",
courtinformation: "court", primarycaselocation: "court",
caseCaption: "case_caption", caption: "case_caption",
casecaption: "case_caption", caption: "case_caption",
courtcasenumber: "court_case_number",
filingdate: "filing_date",
nexthearing: "next_hearing_date", nexthearingdate: "next_hearing_date",
pretrialconference: "next_hearing_date", trial: "next_hearing_date",
// Opposing
opposingparty: "opposing_party",
defendants: "opposing_party", plaintiffs: "opposing_party",
opposingcounsel: "opposing_counsel", opposingcounsels: "opposing_counsel",
opposingcounselfirm: "opposing_counsel_firm",
opposingcounselemail: "opposing_counsel_email",
opposingcounselphone: "opposing_counsel_phone",
leadattorney: "_assignedname", originatingattorney: "_originatingname",
// Attorneys
leadattorney: "_assignedname", leadattorney1: "_assignedname",
originatingattorney: "_originatingname",
// Money
claimamount: "claim_amount", settlementamount: "settlement_amount",
outstandingbalance: "claim_amount",
casebalance: "claim_amount", ledgerbalance: "claim_amount",
@@ -232,15 +244,25 @@ const IMPORTERS: ImporterConfig[] = [
flatfee: "flat_fee_amount",
billingtype: "billing_method",
soldate: "statute_of_limitations",
// Archive
archived: "_archived", isarchived: "_archived",
},
numeric: ["claim_amount", "settlement_amount", "default_hourly_rate", "flat_fee_amount"],
dateCols: ["opened_at", "closed_at", "filing_date", "next_hearing_date", "statute_of_limitations"],
transform: (r, ctx) => {
// Client resolution priority:
// 1. Client number (external id)
// 2. Client / Community Association / Association Name (by name)
// 3. Management Company (only if nothing else matched)
const cid = r._clientext ? ctx.clientByExt.get(String(r._clientext)) : null;
const cidByName = r._clientname ? ctx.clientByName.get(String(r._clientname).toLowerCase()) : null;
r.client_id = cid ?? cidByName ?? null;
delete r._clientext; delete r._clientname;
const cidByName = r._clientname
? ctx.clientByName.get(String(r._clientname).toLowerCase())
: null;
const cidByMgmt = r._mgmtcompany
? ctx.clientByName.get(String(r._mgmtcompany).toLowerCase())
: null;
r.client_id = cid ?? cidByName ?? cidByMgmt ?? null;
delete r._clientext; delete r._clientname; delete r._mgmtcompany;
delete r._assignedname; delete r._originatingname;
if (!r.client_id) return null;
const closedFlag = String(r._closedflag ?? "").toLowerCase().trim();
@@ -265,7 +287,14 @@ const IMPORTERS: ImporterConfig[] = [
const bm = String(r.billing_method).toLowerCase();
r.billing_method = bm.includes("flat") ? "flat" : bm.includes("contingency") ? "contingency" : bm.includes("hour") ? "hourly" : null;
}
if (!r.case_number) r.case_number = `CASE-${Date.now()}-${Math.floor(Math.random() * 1000)}`;
// Generate a collision-free case number when none was provided.
// Uses crypto.randomUUID so simultaneous rows in the same batch never collide.
if (!r.case_number || !String(r.case_number).trim()) {
const uid = (typeof crypto !== "undefined" && "randomUUID" in crypto)
? crypto.randomUUID().slice(0, 8).toUpperCase()
: `${Date.now().toString(36)}${Math.floor(Math.random() * 1e6).toString(36)}`.toUpperCase();
r.case_number = `CASE-${uid}`;
}
if (!r.title) r.title = r.case_number;
return r;
},