114 lines
3.5 KiB
TypeScript
114 lines
3.5 KiB
TypeScript
// @ts-nocheck
|
|
import { mutation, query } from "./_generated/server"
|
|
import { v } from "convex/values"
|
|
|
|
function trimOptional(value?: string | null) {
|
|
const normalized = String(value || "").trim()
|
|
return normalized || undefined
|
|
}
|
|
|
|
function buildDisplayName(args: {
|
|
displayName?: string
|
|
firstName?: string
|
|
lastName?: string
|
|
}) {
|
|
if (trimOptional(args.displayName)) {
|
|
return trimOptional(args.displayName)
|
|
}
|
|
|
|
const firstName = trimOptional(args.firstName)
|
|
const lastName = trimOptional(args.lastName)
|
|
const fallback = [firstName, lastName].filter(Boolean).join(" ").trim()
|
|
return fallback || undefined
|
|
}
|
|
|
|
export const getByNormalizedPhone = query({
|
|
args: {
|
|
normalizedPhone: v.string(),
|
|
},
|
|
handler: async (ctx, args) => {
|
|
return await ctx.db
|
|
.query("contactProfiles")
|
|
.withIndex("by_normalizedPhone", (q) =>
|
|
q.eq("normalizedPhone", args.normalizedPhone)
|
|
)
|
|
.unique()
|
|
},
|
|
})
|
|
|
|
export const upsertByPhone = mutation({
|
|
args: {
|
|
normalizedPhone: v.string(),
|
|
displayName: v.optional(v.string()),
|
|
firstName: v.optional(v.string()),
|
|
lastName: v.optional(v.string()),
|
|
email: v.optional(v.string()),
|
|
company: v.optional(v.string()),
|
|
lastIntent: v.optional(v.string()),
|
|
lastLeadOutcome: v.optional(
|
|
v.union(
|
|
v.literal("none"),
|
|
v.literal("contact"),
|
|
v.literal("requestMachine")
|
|
)
|
|
),
|
|
lastSummaryText: v.optional(v.string()),
|
|
lastCallAt: v.optional(v.number()),
|
|
lastReminderAt: v.optional(v.number()),
|
|
reminderNotes: v.optional(v.string()),
|
|
source: v.optional(v.string()),
|
|
},
|
|
handler: async (ctx, args) => {
|
|
const existing = await ctx.db
|
|
.query("contactProfiles")
|
|
.withIndex("by_normalizedPhone", (q) =>
|
|
q.eq("normalizedPhone", args.normalizedPhone)
|
|
)
|
|
.unique()
|
|
|
|
const now = Date.now()
|
|
const patch = {
|
|
normalizedPhone: args.normalizedPhone,
|
|
displayName: buildDisplayName(args),
|
|
firstName: trimOptional(args.firstName),
|
|
lastName: trimOptional(args.lastName),
|
|
email: trimOptional(args.email),
|
|
company: trimOptional(args.company),
|
|
lastIntent: trimOptional(args.lastIntent),
|
|
lastLeadOutcome: args.lastLeadOutcome,
|
|
lastSummaryText: trimOptional(args.lastSummaryText),
|
|
lastCallAt: args.lastCallAt,
|
|
lastReminderAt: args.lastReminderAt,
|
|
reminderNotes: trimOptional(args.reminderNotes),
|
|
source: trimOptional(args.source),
|
|
updatedAt: now,
|
|
}
|
|
|
|
if (existing) {
|
|
await ctx.db.patch(existing._id, {
|
|
displayName: patch.displayName || existing.displayName,
|
|
firstName: patch.firstName || existing.firstName,
|
|
lastName: patch.lastName || existing.lastName,
|
|
email: patch.email || existing.email,
|
|
company: patch.company || existing.company,
|
|
lastIntent: patch.lastIntent || existing.lastIntent,
|
|
lastLeadOutcome: patch.lastLeadOutcome || existing.lastLeadOutcome,
|
|
lastSummaryText: patch.lastSummaryText || existing.lastSummaryText,
|
|
lastCallAt: patch.lastCallAt || existing.lastCallAt,
|
|
lastReminderAt: patch.lastReminderAt || existing.lastReminderAt,
|
|
reminderNotes: patch.reminderNotes || existing.reminderNotes,
|
|
source: patch.source || existing.source,
|
|
updatedAt: now,
|
|
})
|
|
|
|
return await ctx.db.get(existing._id)
|
|
}
|
|
|
|
const id = await ctx.db.insert("contactProfiles", {
|
|
...patch,
|
|
createdAt: now,
|
|
})
|
|
|
|
return await ctx.db.get(id)
|
|
},
|
|
})
|