Skip to content

Commit 8d84c4d

Browse files
committed
チャットデータもdrizzleで扱える
1 parent 26a3d36 commit 8d84c4d

File tree

8 files changed

+518
-141
lines changed

8 files changed

+518
-141
lines changed

app/lib/auth.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import { anonymous } from "better-auth/plugins";
55
import { migrateChatUser } from "./chatHistory";
66
import { getDrizzle } from "./drizzle";
77

8-
export async function getAuthServer(drizzle: ReturnType<typeof getDrizzle>) {
8+
export async function getAuthServer(
9+
drizzle: Awaited<ReturnType<typeof getDrizzle>>
10+
) {
911
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1012
let cloudflareEnv: any;
1113
try {

app/lib/chatHistory.ts

Lines changed: 40 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { headers } from "next/headers";
22
import { getAuthServer } from "./auth";
3+
import { getDrizzle } from "./drizzle";
4+
import { chat, message } from "@/schema/chat";
5+
import { and, asc, eq } from "drizzle-orm";
36

47
export interface CreateChatMessage {
58
role: "user" | "ai" | "error";
@@ -11,66 +14,66 @@ export async function addChat(
1114
sectionId: string,
1215
messages: CreateChatMessage[]
1316
) {
14-
const prisma = await getPrismaClient();
15-
const auth = await getAuthServer(prisma);
17+
const drizzle = await getDrizzle();
18+
const auth = await getAuthServer(drizzle);
1619
const session = await auth.api.getSession({ headers: await headers() });
1720
if (!session) {
1821
throw new Error("Not authenticated");
1922
}
2023

21-
return await prisma.chat.create({
22-
data: {
24+
const [newChat] = await drizzle
25+
.insert(chat)
26+
.values({
2327
userId: session.user.id,
2428
docsId,
2529
sectionId,
26-
messages: {
27-
createMany: {
28-
data: messages,
29-
},
30-
},
31-
},
32-
include: {
33-
messages: true,
34-
},
35-
});
30+
})
31+
.returning();
32+
33+
const chatMessages = await drizzle
34+
.insert(message)
35+
.values(
36+
messages.map((msg) => ({
37+
chatId: newChat.chatId,
38+
role: msg.role,
39+
content: msg.content,
40+
}))
41+
)
42+
.returning();
43+
44+
return {
45+
...newChat,
46+
messages: chatMessages,
47+
};
3648
}
3749

3850
export type ChatWithMessages = Awaited<ReturnType<typeof addChat>>;
3951

4052
export async function getChat(docsId: string) {
41-
const prisma = await getPrismaClient();
42-
const auth = await getAuthServer(prisma);
53+
const drizzle = await getDrizzle();
54+
const auth = await getAuthServer(drizzle);
4355
const session = await auth.api.getSession({ headers: await headers() });
4456
if (!session) {
4557
return [];
4658
}
4759

48-
return await prisma.chat.findMany({
49-
where: {
50-
userId: session.user.id,
51-
docsId,
52-
},
53-
include: {
60+
const chats = await drizzle.query.chat.findMany({
61+
where: and(eq(chat.userId, session.user.id), eq(chat.docsId, docsId)),
62+
with: {
5463
messages: {
55-
orderBy: {
56-
createdAt: "asc",
57-
},
64+
orderBy: [asc(message.createdAt)],
5865
},
5966
},
60-
orderBy: {
61-
createdAt: "asc",
62-
},
67+
orderBy: [asc(chat.createdAt)],
6368
});
69+
70+
return chats;
6471
}
6572

6673
export async function migrateChatUser(oldUserId: string, newUserId: string) {
67-
const prisma = await getPrismaClient();
68-
await prisma.chat.updateMany({
69-
where: {
70-
userId: oldUserId,
71-
},
72-
data: {
73-
userId: newUserId,
74-
},
75-
});
74+
const drizzle = await getDrizzle();
75+
await drizzle
76+
.update(chat)
77+
.set({ userId: newUserId })
78+
.where(eq(chat.userId, oldUserId));
7679
}

app/lib/drizzle.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { getCloudflareContext } from "@opennextjs/cloudflare";
22
import { drizzle } from "drizzle-orm/node-postgres";
33
import { Pool } from "pg";
44
import * as authSchema from "../schema/auth";
5+
import * as chatSchema from "../schema/chat";
56

67
export async function getDrizzle() {
78
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -24,6 +25,7 @@ export async function getDrizzle() {
2425
client: pool,
2526
schema: {
2627
...authSchema,
28+
...chatSchema,
2729
},
2830
});
2931
}

app/schema/chat.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { relations } from "drizzle-orm";
2+
import { pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
3+
4+
export const chat = pgTable("chat", {
5+
chatId: uuid("chatId").primaryKey().defaultRandom(),
6+
userId: text("userId").notNull(),
7+
docsId: text("docsId").notNull(),
8+
sectionId: text("sectionId").notNull(),
9+
createdAt: timestamp("createdAt").notNull().defaultNow(),
10+
});
11+
12+
export const message = pgTable("message", {
13+
id: uuid("id").primaryKey().defaultRandom(),
14+
chatId: uuid("chatId").notNull(),
15+
role: text("role").notNull(),
16+
content: text("content").notNull(),
17+
createdAt: timestamp("createdAt").notNull().defaultNow(),
18+
});
19+
20+
export const chatRelations = relations(chat, ({ many }) => ({
21+
messages: many(message),
22+
}));
23+
24+
export const messageRelations = relations(message, ({ one }) => ({
25+
chat: one(chat, {
26+
fields: [message.chatId],
27+
references: [chat.chatId],
28+
}),
29+
}));

drizzle/0001_stale_reaper.sql

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
CREATE TABLE "chat" (
2+
"chatId" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
3+
"userId" text NOT NULL,
4+
"docsId" text NOT NULL,
5+
"sectionId" text NOT NULL,
6+
"createdAt" timestamp DEFAULT now() NOT NULL
7+
);
8+
--> statement-breakpoint
9+
CREATE TABLE "message" (
10+
"id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
11+
"chatId" uuid NOT NULL,
12+
"role" text NOT NULL,
13+
"content" text NOT NULL,
14+
"createdAt" timestamp DEFAULT now() NOT NULL
15+
);

0 commit comments

Comments
 (0)