fix: replace prisma.$use with $extends for Prisma 6 compatibility

prisma.$use middleware API was removed in Prisma 6. Switched to
$extends query hooks which is the supported approach.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Ruslan Bakiev
2026-02-25 09:08:20 +07:00
parent 5c29cde13d
commit f4891e6932

View File

@@ -5,51 +5,72 @@ declare global {
var __prisma: PrismaClient | undefined; var __prisma: PrismaClient | undefined;
} }
export const prisma = // ---------------------------------------------------------------------------
// Auto-sync ClientTimelineEntry for CalendarEvent and FeedCard
// ---------------------------------------------------------------------------
const TIMELINE_MODEL_MAP: Record<string, string> = {
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 basePrisma =
globalThis.__prisma ?? globalThis.__prisma ??
new PrismaClient({ new PrismaClient({
log: ["error", "warn"], log: ["error", "warn"],
}); });
// --------------------------------------------------------------------------- export const prisma = basePrisma.$extends({
// Auto-sync ClientTimelineEntry for CalendarEvent, WorkspaceDocument, FeedCard query: {
// --------------------------------------------------------------------------- calendarEvent: timelineHook("calendarEvent")!,
const TIMELINE_MODEL_MAP: Record<string, string> = { feedCard: timelineHook("feedCard")!,
CalendarEvent: "CALENDAR_EVENT", },
FeedCard: "RECOMMENDATION", }) as unknown as PrismaClient;
};
prisma.$use(async (params, next) => {
const result = await next(params);
const contentType = params.model ? TIMELINE_MODEL_MAP[params.model] : undefined;
if (!contentType) return result;
if (params.action !== "create" && params.action !== "update" && params.action !== "upsert") return result;
if (!result || typeof result !== "object") return result;
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 result;
const datetime = row.startsAt ?? row.happenedAt ?? row.createdAt ?? new Date();
prisma.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 result;
});
if (process.env.NODE_ENV !== "production") { if (process.env.NODE_ENV !== "production") {
globalThis.__prisma = prisma; globalThis.__prisma = basePrisma;
} }