feat: wire convex data foundations

This commit is contained in:
2026-06-04 10:30:05 +02:00
parent df7a955736
commit 011e35cb17
62 changed files with 6335 additions and 14 deletions

69
convex/campaigns.ts Normal file
View File

@@ -0,0 +1,69 @@
import { v } from "convex/values";
import { normalizeListLimit } from "./domain";
import { mutation, query } from "./_generated/server";
const limitArg = v.optional(v.number());
export const create = mutation({
args: {
name: v.string(),
categoryMode: v.union(v.literal("preset"), v.literal("custom")),
category: v.string(),
customSearchTerm: v.optional(v.string()),
postalCode: v.string(),
region: v.optional(v.string()),
latitude: v.optional(v.number()),
longitude: v.optional(v.number()),
radiusKm: v.number(),
maxNewLeadsPerRun: v.number(),
maxAuditsPerRun: v.number(),
recurrence: v.union(
v.literal("manual"),
v.literal("daily"),
v.literal("weekly"),
v.literal("monthly"),
),
status: v.optional(v.union(v.literal("active"), v.literal("paused"))),
nextRunAt: v.optional(v.number()),
},
handler: async (ctx, args) => {
const now = Date.now();
return await ctx.db.insert("campaigns", {
...args,
status: args.status ?? "paused",
createdAt: now,
updatedAt: now,
});
},
});
export const get = query({
args: { id: v.id("campaigns") },
handler: async (ctx, args) => {
return await ctx.db.get(args.id);
},
});
export const list = query({
args: {
status: v.optional(v.union(v.literal("active"), v.literal("paused"))),
limit: limitArg,
},
handler: async (ctx, args) => {
const limit = normalizeListLimit(args.limit);
if (args.status) {
const status = args.status;
return await ctx.db
.query("campaigns")
.withIndex("by_status", (q) => q.eq("status", status))
.order("desc")
.take(limit);
}
return await ctx.db.query("campaigns").order("desc").take(limit);
},
});