- Prisma 6 → 7: new prisma-client generator, prisma.config.ts, PrismaPg adapter, updated all imports - LangChain 0.x → 1.x: @langchain/core, langgraph, openai - Tailwind 4.1 → 4.2.1, daisyUI 5.5.19, Vue 3.5.29, ai 6.0.99, zod 4.3.6 - Fix MessageDirection bug in crm-updates.ts (OUTBOUND → OUT) - Add server/generated to .gitignore Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
import { PrismaClient, type ClientTimelineContentType } from "../generated/prisma/client";
|
|
import { PrismaPg } from "@prisma/adapter-pg";
|
|
|
|
declare global {
|
|
// eslint-disable-next-line no-var
|
|
var __prisma: PrismaClient | undefined;
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------
|
|
// Auto-sync ClientTimelineEntry for CalendarEvent and FeedCard
|
|
// ---------------------------------------------------------------------------
|
|
const TIMELINE_MODEL_MAP: Record<string, ClientTimelineContentType> = {
|
|
calendarEvent: "CALENDAR_EVENT",
|
|
feedCard: "RECOMMENDATION",
|
|
};
|
|
|
|
function timelineHook(model: string) {
|
|
const contentType = TIMELINE_MODEL_MAP[model];
|
|
if (!contentType) return undefined;
|
|
|
|
const afterMutate = (result: any) => {
|
|
if (!result || typeof result !== "object") return;
|
|
const row = result as Record<string, any>;
|
|
const teamId = row.teamId as string | undefined;
|
|
const contactId = row.contactId as string | undefined;
|
|
const id = row.id as string | undefined;
|
|
if (!teamId || !contactId || !id) return;
|
|
|
|
const datetime = row.startsAt ?? row.happenedAt ?? row.createdAt ?? new Date();
|
|
|
|
basePrisma.clientTimelineEntry
|
|
.upsert({
|
|
where: {
|
|
teamId_contentType_contentId: { teamId, contentType, contentId: id },
|
|
},
|
|
create: { teamId, contactId, contentType, contentId: id, datetime },
|
|
update: { contactId, datetime },
|
|
select: { id: true },
|
|
})
|
|
.catch(() => {});
|
|
};
|
|
|
|
return {
|
|
async create({ args, query }: any) {
|
|
const result = await query(args);
|
|
afterMutate(result);
|
|
return result;
|
|
},
|
|
async update({ args, query }: any) {
|
|
const result = await query(args);
|
|
afterMutate(result);
|
|
return result;
|
|
},
|
|
async upsert({ args, query }: any) {
|
|
const result = await query(args);
|
|
afterMutate(result);
|
|
return result;
|
|
},
|
|
};
|
|
}
|
|
|
|
const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL! });
|
|
|
|
const basePrisma =
|
|
globalThis.__prisma ??
|
|
new PrismaClient({
|
|
adapter,
|
|
log: ["error", "warn"],
|
|
});
|
|
|
|
export const prisma = basePrisma.$extends({
|
|
query: {
|
|
calendarEvent: timelineHook("calendarEvent")!,
|
|
feedCard: timelineHook("feedCard")!,
|
|
},
|
|
}) as unknown as PrismaClient;
|
|
|
|
if (process.env.NODE_ENV !== "production") {
|
|
globalThis.__prisma = basePrisma;
|
|
}
|