From 29595d2da4ed92e51d91d6b379aa367f9da2898b Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2026 00:06:20 +0000 Subject: [PATCH 1/4] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/settings.import.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/routes/settings.import.tsx b/src/routes/settings.import.tsx index 45cac22..6b382d9 100644 --- a/src/routes/settings.import.tsx +++ b/src/routes/settings.import.tsx @@ -56,6 +56,8 @@ interface ImportCtx { clientByName: Map; caseByNumber: Map; caseByTitle: Map; + // Composite key "client_name||case_title" (both lowercased/trimmed) → case uuid + caseByClientAndTitle: Map; userByName: Map; userByEmail: Map; // Set of case ids considered "active" (not closed, not archived) From 319c9f69675829e41da872a6166e579ef4813a74 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2026 00:06:36 +0000 Subject: [PATCH 2/4] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/settings.import.tsx | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/routes/settings.import.tsx b/src/routes/settings.import.tsx index 6b382d9..4c2e66c 100644 --- a/src/routes/settings.import.tsx +++ b/src/routes/settings.import.tsx @@ -665,7 +665,8 @@ const IMPORTERS: ImporterConfig[] = [ { key: "status_updates", label: "Status updates → Status", - description: "Case status reports.", + description: + "Case status reports. Match cases by title + client name (recommended), or by case number / external id.", table: "status_updates", conflict: "external_id", required: ["title", "body", "case_id"], @@ -675,14 +676,18 @@ const IMPORTERS: ImporterConfig[] = [ body: "body", content: "body", notes: "body", description: "body", caseid: "_caseext", matterid: "_caseext", casenumber: "_casenum", casename: "_casename", casetitle: "_casename", matter: "_casename", mattername: "_casename", + clientname: "_clientname", client: "_clientname", hoa: "_clientname", association: "_clientname", }, transform: (r, ctx) => { + const titleKey = r._casename ? String(r._casename).toLowerCase().trim() : ""; + const clientKey = r._clientname ? String(r._clientname).toLowerCase().trim() : ""; r.case_id = (r._caseext && ctx.caseByExt.get(String(r._caseext))) || + (titleKey && clientKey && ctx.caseByClientAndTitle.get(`${clientKey}||${titleKey}`)) || (r._casenum && ctx.caseByNumber.get(String(r._casenum))) || - (r._casename && ctx.caseByTitle.get(String(r._casename).toLowerCase().trim())) || + (titleKey && ctx.caseByTitle.get(titleKey)) || null; - delete r._caseext; delete r._casenum; delete r._casename; + delete r._caseext; delete r._casenum; delete r._casename; delete r._clientname; if (!r.case_id || !r.body) return null; return r; }, From 7f379e1c68105e24625f97d39c7884fa919c283b Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2026 00:06:46 +0000 Subject: [PATCH 3/4] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/settings.import.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/routes/settings.import.tsx b/src/routes/settings.import.tsx index 4c2e66c..a288c70 100644 --- a/src/routes/settings.import.tsx +++ b/src/routes/settings.import.tsx @@ -729,6 +729,7 @@ function ImportPage() { clientByName: new Map(), caseByNumber: new Map(), caseByTitle: new Map(), + caseByClientAndTitle: new Map(), userByName: new Map(), userByEmail: new Map(), activeCaseIds: new Set(), From f5b5d0d6f871fae0e050fa6cb3649360b629cabe Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2026 00:07:05 +0000 Subject: [PATCH 4/4] Changes Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com> --- src/routes/settings.import.tsx | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/routes/settings.import.tsx b/src/routes/settings.import.tsx index a288c70..627bf6d 100644 --- a/src/routes/settings.import.tsx +++ b/src/routes/settings.import.tsx @@ -806,16 +806,27 @@ function ImportPage() { ctx.caseByExt.clear(); ctx.caseByNumber.clear(); ctx.caseByTitle.clear(); + ctx.caseByClientAndTitle.clear(); ctx.activeCaseIds.clear(); - const cases = await fetchAllPaginated<{ id: string; case_number: string | null; title: string | null; external_id: string | null; status: string | null; archived_at: string | null }>( + const cases = await fetchAllPaginated<{ id: string; case_number: string | null; title: string | null; external_id: string | null; status: string | null; archived_at: string | null; client_id: string | null }>( "cases", - "id, case_number, title, external_id, status, archived_at", + "id, case_number, title, external_id, status, archived_at, client_id", ); + // Build id → client_name lookup from already-loaded clients + const clientNameById = new Map(); + for (const [name, id] of ctx.clientByName.entries()) clientNameById.set(id, name); const CLOSED_STATUSES = new Set(["closed", "closed_won", "closed_lost"]); for (const r of cases) { if (r.external_id) ctx.caseByExt.set(r.external_id, r.id); if (r.case_number) ctx.caseByNumber.set(r.case_number, r.id); - if (r.title) ctx.caseByTitle.set(r.title.toLowerCase().trim(), r.id); + if (r.title) { + const titleKey = r.title.toLowerCase().trim(); + ctx.caseByTitle.set(titleKey, r.id); + if (r.client_id) { + const cname = clientNameById.get(r.client_id); + if (cname) ctx.caseByClientAndTitle.set(`${cname}||${titleKey}`, r.id); + } + } if (!r.archived_at && !CLOSED_STATUSES.has(String(r.status ?? "").toLowerCase())) { ctx.activeCaseIds.add(r.id); } @@ -827,7 +838,7 @@ function ImportPage() { if (p.full_name) ctx.userByName.set(p.full_name.toLowerCase().trim(), p.id); if (p.email) ctx.userByEmail.set(p.email.toLowerCase().trim(), p.id); } - console.info(`[import] lookups loaded: clients=${ctx.clientByExt.size}/${ctx.clientByName.size} cases=${ctx.caseByExt.size}/${ctx.caseByNumber.size}/${ctx.caseByTitle.size} users=${ctx.userByName.size}`); + console.info(`[import] lookups loaded: clients=${ctx.clientByExt.size}/${ctx.clientByName.size} cases=${ctx.caseByExt.size}/${ctx.caseByNumber.size}/${ctx.caseByTitle.size}/${ctx.caseByClientAndTitle.size} users=${ctx.userByName.size}`); }; const handleFile = async (cfg: ImporterConfig, source: File | string) => {