Files
webdev-pipeline/convex/leads.ts

108 lines
2.7 KiB
TypeScript

import { v } from "convex/values";
import { normalizeListLimit } from "./domain";
import { mutation, query } from "./_generated/server";
export const create = mutation({
args: {
campaignId: v.optional(v.id("campaigns")),
companyName: v.string(),
niche: v.optional(v.string()),
address: v.optional(v.string()),
city: v.optional(v.string()),
postalCode: v.optional(v.string()),
googlePlaceId: v.optional(v.string()),
googleMapsUrl: v.optional(v.string()),
websiteDomain: v.optional(v.string()),
phone: v.optional(v.string()),
email: v.optional(v.string()),
emailSource: v.optional(v.string()),
contactPerson: v.optional(v.string()),
priority: v.optional(
v.union(
v.literal("high"),
v.literal("medium"),
v.literal("low"),
v.literal("defer"),
),
),
contactStatus: v.optional(
v.union(
v.literal("new"),
v.literal("missing_contact"),
v.literal("audit_ready"),
v.literal("outreach_ready"),
v.literal("contacted"),
v.literal("replied"),
v.literal("do_not_contact"),
),
),
notes: v.optional(v.string()),
},
handler: async (ctx, args) => {
const now = Date.now();
return await ctx.db.insert("leads", {
...args,
priority: args.priority ?? "medium",
contactStatus: args.contactStatus ?? "new",
duplicateStatus: "unchecked",
blacklistStatus: "clear",
createdAt: now,
updatedAt: now,
});
},
});
export const get = query({
args: { id: v.id("leads") },
handler: async (ctx, args) => {
return await ctx.db.get(args.id);
},
});
export const list = query({
args: {
campaignId: v.optional(v.id("campaigns")),
contactStatus: v.optional(
v.union(
v.literal("new"),
v.literal("missing_contact"),
v.literal("audit_ready"),
v.literal("outreach_ready"),
v.literal("contacted"),
v.literal("replied"),
v.literal("do_not_contact"),
),
),
limit: v.optional(v.number()),
},
handler: async (ctx, args) => {
const limit = normalizeListLimit(args.limit);
if (args.campaignId) {
const campaignId = args.campaignId;
return await ctx.db
.query("leads")
.withIndex("by_campaignId", (q) => q.eq("campaignId", campaignId))
.order("desc")
.take(limit);
}
if (args.contactStatus) {
const contactStatus = args.contactStatus;
return await ctx.db
.query("leads")
.withIndex("by_contactStatus", (q) =>
q.eq("contactStatus", contactStatus),
)
.order("desc")
.take(limit);
}
return await ctx.db.query("leads").order("desc").take(limit);
},
});