Changes
Co-authored-by: renee-png <262607627+renee-png@users.noreply.github.com>
This commit is contained in:
co-authored by
renee-png
parent
66194febdf
commit
aff994bd05
@@ -0,0 +1,147 @@
|
||||
// Server-side helper that loads all the lookup data needed for matching and
|
||||
// runs `matchEmailToCases` against an array of incoming_emails rows. Updates
|
||||
// each row in place with the resulting status, case_id, suggestions, etc.
|
||||
|
||||
import { supabaseAdmin } from "@/integrations/supabase/client.server";
|
||||
import {
|
||||
matchEmailToCases,
|
||||
type CaseLookup,
|
||||
type ContactCaseLink,
|
||||
type ClientCaseLink,
|
||||
type HomeownerCaseLink,
|
||||
type EmailLike,
|
||||
type PriorEmail,
|
||||
} from "@/lib/email-matching";
|
||||
|
||||
interface IncomingEmailRow extends EmailLike {
|
||||
id: string;
|
||||
}
|
||||
|
||||
async function loadLookups() {
|
||||
const [casesRes, contactsRes, clientsRes, homeownersRes, priorRes] =
|
||||
await Promise.all([
|
||||
supabaseAdmin
|
||||
.from("cases")
|
||||
.select(
|
||||
"id, case_number, court_case_number, case_caption, title, client_id, opposing_counsel_email, status, updated_at",
|
||||
)
|
||||
.is("archived_at", null),
|
||||
supabaseAdmin
|
||||
.from("case_contacts")
|
||||
.select("case_id, contact_id, contact:contacts(email)"),
|
||||
supabaseAdmin
|
||||
.from("clients")
|
||||
.select("id, primary_contact_email")
|
||||
.is("archived_at", null),
|
||||
supabaseAdmin
|
||||
.from("homeowners")
|
||||
.select("id, email, client_id")
|
||||
.is("archived_at", null),
|
||||
supabaseAdmin
|
||||
.from("incoming_emails")
|
||||
.select("message_id, case_id")
|
||||
.not("case_id", "is", null)
|
||||
.not("message_id", "is", null)
|
||||
.limit(5000),
|
||||
]);
|
||||
|
||||
const cases: CaseLookup[] = (casesRes.data ?? []) as any;
|
||||
|
||||
const contactLinks: ContactCaseLink[] = ((contactsRes.data ?? []) as any[])
|
||||
.map((row: any) => ({
|
||||
case_id: row.case_id,
|
||||
contact_id: row.contact_id,
|
||||
email: row.contact?.email ?? null,
|
||||
}))
|
||||
.filter((r) => r.email);
|
||||
|
||||
// Build case_ids per client/homeowner
|
||||
const casesByClient = new Map<string, string[]>();
|
||||
const clientByCases = new Map<string, string | null>();
|
||||
for (const c of cases) {
|
||||
clientByCases.set(c.id, c.client_id);
|
||||
if (c.client_id) {
|
||||
const arr = casesByClient.get(c.client_id) ?? [];
|
||||
arr.push(c.id);
|
||||
casesByClient.set(c.client_id, arr);
|
||||
}
|
||||
}
|
||||
|
||||
const clientLinks: ClientCaseLink[] = ((clientsRes.data ?? []) as any[])
|
||||
.filter((r) => r.primary_contact_email)
|
||||
.map((r) => ({
|
||||
client_id: r.id,
|
||||
primary_contact_email: r.primary_contact_email,
|
||||
case_ids: casesByClient.get(r.id) ?? [],
|
||||
}))
|
||||
.filter((r) => r.case_ids.length > 0);
|
||||
|
||||
const homeownerLinks: HomeownerCaseLink[] = ((homeownersRes.data ?? []) as any[])
|
||||
.filter((r) => r.email && r.client_id)
|
||||
.map((r) => ({
|
||||
homeowner_id: r.id,
|
||||
email: r.email,
|
||||
case_ids: casesByClient.get(r.client_id) ?? [],
|
||||
}))
|
||||
.filter((r) => r.case_ids.length > 0);
|
||||
|
||||
const priorEmails: PriorEmail[] = (priorRes.data ?? []) as any;
|
||||
|
||||
return { cases, contactLinks, clientLinks, homeownerLinks, priorEmails };
|
||||
}
|
||||
|
||||
export async function matchAndUpdateEmails(emailIds: string[]): Promise<{
|
||||
matched: number;
|
||||
suggested: number;
|
||||
unmatched: number;
|
||||
}> {
|
||||
if (emailIds.length === 0) return { matched: 0, suggested: 0, unmatched: 0 };
|
||||
|
||||
const { data: rowsRaw, error } = await supabaseAdmin
|
||||
.from("incoming_emails")
|
||||
.select(
|
||||
"id, message_id, in_reply_to, email_references, from_address, to_addresses, cc_addresses, subject, body_text",
|
||||
)
|
||||
.in("id", emailIds);
|
||||
|
||||
if (error) throw new Error(`Failed to load emails for matching: ${error.message}`);
|
||||
|
||||
const rows = (rowsRaw ?? []) as IncomingEmailRow[];
|
||||
if (rows.length === 0) return { matched: 0, suggested: 0, unmatched: 0 };
|
||||
|
||||
const lookups = await loadLookups();
|
||||
|
||||
let matched = 0,
|
||||
suggested = 0,
|
||||
unmatched = 0;
|
||||
|
||||
for (const row of rows) {
|
||||
const result = matchEmailToCases(
|
||||
row,
|
||||
lookups.cases,
|
||||
lookups.contactLinks,
|
||||
lookups.clientLinks,
|
||||
lookups.homeownerLinks,
|
||||
lookups.priorEmails,
|
||||
);
|
||||
|
||||
const update: Record<string, unknown> = {
|
||||
match_status: result.status,
|
||||
match_suggestions: result.suggestions,
|
||||
match_reason: result.reason,
|
||||
};
|
||||
if (result.status === "matched" && result.case_id) {
|
||||
update.case_id = result.case_id;
|
||||
update.matched_at = new Date().toISOString();
|
||||
matched++;
|
||||
} else if (result.status === "suggested") {
|
||||
suggested++;
|
||||
} else {
|
||||
unmatched++;
|
||||
}
|
||||
|
||||
await supabaseAdmin.from("incoming_emails").update(update).eq("id", row.id);
|
||||
}
|
||||
|
||||
return { matched, suggested, unmatched };
|
||||
}
|
||||
Reference in New Issue
Block a user