From 0f6e278dd20248ba2e29a6e712a4b0313e96199e Mon Sep 17 00:00:00 2001 From: na-trium-144 <100704180+na-trium-144@users.noreply.github.com> Date: Sun, 26 Oct 2025 17:48:24 +0900 Subject: [PATCH 1/3] =?UTF-8?q?postgres=E3=81=8B=E3=82=89d1=E3=81=AB?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + README.md | 27 ++-- app/[docs_id]/chatHistory.tsx | 2 +- app/lib/auth.ts | 2 +- app/lib/chatHistory.ts | 2 + app/lib/prisma.ts | 13 +- migrations/0001_init_table.sql | 78 ++++++++++++ package-lock.json | 221 ++++----------------------------- package.json | 3 +- prisma.config.ts | 3 +- prisma/schema.prisma | 9 +- wrangler.jsonc | 14 ++- 12 files changed, 138 insertions(+), 237 deletions(-) create mode 100644 migrations/0001_init_table.sql diff --git a/.gitignore b/.gitignore index 485c203..845ba04 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /.open-next /cloudflare-env.d.ts +/.wrangler # dependencies /node_modules diff --git a/README.md b/README.md index d58b8a2..027393f 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ https://my-code.utcode.net ## インストール ```bash npm ci +npx wrangler d1 migrations apply wrapdb --local ``` ルートディレクトリに .env.local という名前のファイルを作成し、以下の内容を記述 @@ -13,21 +14,10 @@ API_KEY=GeminiAPIキー BETTER_AUTH_URL=http://localhost:3000 ``` -prismaの開発環境を起動 -(.env にDATABASE_URLが自動的に追加される) -```bash -npx prisma dev -``` -別ターミナルで -```bash -npx prisma db push -``` - ### 本番環境の場合 上記の環境変数以外に、 * BETTER_AUTH_SECRET に任意の文字列 -* DATABASE_URL に本番用のPostgreSQLデータベースURL * GOOGLE_CLIENT_IDとGOOGLE_CLIENT_SECRETにGoogle OAuthのクライアントIDとシークレット https://www.better-auth.com/docs/authentication/google * GITHUB_CLIENT_IDとGITHUB_CLIENT_SECRETにGitHub OAuthのクライアントIDとシークレット https://www.better-auth.com/docs/authentication/github @@ -49,6 +39,21 @@ npm run lint ``` でコードをチェックします。出てくるwarningやerrorはできるだけ直しましょう。 +### prismaのスキーマを変更した場合 + +データベースにD1を使っており、 ut.code(); Learn でやっていた `npx prisma db push` とは手順が異なるので注意! + +```bash +npx wrangler d1 migrations create my-code-db [migrationの名前] +npx prisma migrate diff --from-local-d1 --to-scheme-datamodel ./prisma/schema.prisma --script --output ./migrations/000x_[migrationの名前].sql +npx wrangler d1 migrations apply my-code-db --local +``` + +変更をmainにマージした場合は、本番環境も更新する: +```bash +npx wrangler d1 migrations apply my-code-db --remote +``` + ## markdown仕様 ```` diff --git a/app/[docs_id]/chatHistory.tsx b/app/[docs_id]/chatHistory.tsx index fc92e5d..d185922 100644 --- a/app/[docs_id]/chatHistory.tsx +++ b/app/[docs_id]/chatHistory.tsx @@ -1,6 +1,6 @@ "use client"; -import { ChatWithMessages } from "@/lib/chatHistory"; +import { type ChatWithMessages } from "@/lib/chatHistory"; import { createContext, ReactNode, diff --git a/app/lib/auth.ts b/app/lib/auth.ts index 1b91e16..f4f98b4 100644 --- a/app/lib/auth.ts +++ b/app/lib/auth.ts @@ -15,7 +15,7 @@ try { } export const auth = betterAuth({ database: prismaAdapter(prisma, { - provider: "postgresql", + provider: "sqlite", }), plugins: [ anonymous({ diff --git a/app/lib/chatHistory.ts b/app/lib/chatHistory.ts index a8faf0b..fc67b37 100644 --- a/app/lib/chatHistory.ts +++ b/app/lib/chatHistory.ts @@ -1,3 +1,5 @@ +"use server"; + import { headers } from "next/headers"; import { auth } from "./auth"; import prisma from "./prisma"; diff --git a/app/lib/prisma.ts b/app/lib/prisma.ts index 4fb258d..dae5912 100644 --- a/app/lib/prisma.ts +++ b/app/lib/prisma.ts @@ -1,6 +1,5 @@ +import { PrismaD1 } from "@prisma/adapter-d1"; import { PrismaClient } from "../generated/prisma/client"; -import { PrismaPg } from "@prisma/adapter-pg"; -import { PrismaNeon } from "@prisma/adapter-neon"; import { getCloudflareContext } from "@opennextjs/cloudflare"; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -11,14 +10,6 @@ try { // @better-auth/cli generate を実行する際には initOpenNextCloudflareForDev がセットアップされていない環境になっている cloudflareEnv = {}; } -const DATABASE_URL = - process.env.DATABASE_URL ?? cloudflareEnv.DATABASE_URL ?? ""; -let adapter; -if (DATABASE_URL.includes("neon")) { - adapter = new PrismaNeon({ connectionString: DATABASE_URL }); -} else { - adapter = new PrismaPg({ connectionString: DATABASE_URL }); -} -const prisma = new PrismaClient({ adapter }); +const prisma = new PrismaClient({ adapter: new PrismaD1(cloudflareEnv.my_code_db) }); export default prisma; diff --git a/migrations/0001_init_table.sql b/migrations/0001_init_table.sql new file mode 100644 index 0000000..667af8a --- /dev/null +++ b/migrations/0001_init_table.sql @@ -0,0 +1,78 @@ +-- CreateTable +CREATE TABLE "user" ( + "id" TEXT NOT NULL PRIMARY KEY, + "name" TEXT NOT NULL, + "email" TEXT NOT NULL, + "emailVerified" BOOLEAN NOT NULL DEFAULT false, + "image" TEXT, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "isAnonymous" BOOLEAN +); + +-- CreateTable +CREATE TABLE "session" ( + "id" TEXT NOT NULL PRIMARY KEY, + "expiresAt" DATETIME NOT NULL, + "token" TEXT NOT NULL, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL, + "ipAddress" TEXT, + "userAgent" TEXT, + "userId" TEXT NOT NULL, + CONSTRAINT "session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE CASCADE +); + +-- CreateTable +CREATE TABLE "account" ( + "id" TEXT NOT NULL PRIMARY KEY, + "accountId" TEXT NOT NULL, + "providerId" TEXT NOT NULL, + "userId" TEXT NOT NULL, + "accessToken" TEXT, + "refreshToken" TEXT, + "idToken" TEXT, + "accessTokenExpiresAt" DATETIME, + "refreshTokenExpiresAt" DATETIME, + "scope" TEXT, + "password" TEXT, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL, + CONSTRAINT "account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE CASCADE +); + +-- CreateTable +CREATE TABLE "verification" ( + "id" TEXT NOT NULL PRIMARY KEY, + "identifier" TEXT NOT NULL, + "value" TEXT NOT NULL, + "expiresAt" DATETIME NOT NULL, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +-- CreateTable +CREATE TABLE "Chat" ( + "chatId" TEXT NOT NULL PRIMARY KEY, + "userId" TEXT NOT NULL, + "docsId" TEXT NOT NULL, + "sectionId" TEXT NOT NULL, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT "Chat_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE CASCADE +); + +-- CreateTable +CREATE TABLE "Message" ( + "id" TEXT NOT NULL PRIMARY KEY, + "chatId" TEXT NOT NULL, + "role" TEXT NOT NULL, + "content" TEXT NOT NULL, + "createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, + CONSTRAINT "Message_chatId_fkey" FOREIGN KEY ("chatId") REFERENCES "Chat" ("chatId") ON DELETE CASCADE ON UPDATE CASCADE +); + +-- CreateIndex +CREATE UNIQUE INDEX "user_email_key" ON "user"("email"); + +-- CreateIndex +CREATE UNIQUE INDEX "session_token_key" ON "session"("token"); diff --git a/package-lock.json b/package-lock.json index 1df0fd0..d4421f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,8 +12,7 @@ "@fontsource-variable/noto-sans-jp": "^5.2.6", "@google/genai": "^1.21.0", "@opennextjs/cloudflare": "^1.7.1", - "@prisma/adapter-neon": "^6.18.0", - "@prisma/adapter-pg": "^6.18.0", + "@prisma/adapter-d1": "^6.18.0", "@prisma/client": "^6.18.0", "@xterm/addon-fit": "^0.11.0-beta.115", "@xterm/xterm": "^5.6.0-beta.115", @@ -7752,6 +7751,12 @@ "node": ">=16" } }, + "node_modules/@cloudflare/workers-types": { + "version": "4.20251014.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20251014.0.tgz", + "integrity": "sha512-tEW98J/kOa0TdylIUOrLKRdwkUw0rvvYVlo+Ce0mqRH3c8kSoxLzUH9gfCvwLe0M89z1RkzFovSKAW2Nwtyn3w==", + "license": "MIT OR Apache-2.0" + }, "node_modules/@cspotcode/source-map-support": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", @@ -9119,28 +9124,6 @@ "@tybys/wasm-util": "^0.10.0" } }, - "node_modules/@neondatabase/serverless": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@neondatabase/serverless/-/serverless-1.0.2.tgz", - "integrity": "sha512-I5sbpSIAHiB+b6UttofhrN/UJXII+4tZPAq1qugzwCwLIL8EZLV7F/JyHUrEIiGgQpEXzpnjlJ+zwcEhheGvCw==", - "license": "MIT", - "dependencies": { - "@types/node": "^22.15.30", - "@types/pg": "^8.8.0" - }, - "engines": { - "node": ">=19.0.0" - } - }, - "node_modules/@neondatabase/serverless/node_modules/@types/node": { - "version": "22.18.12", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.12.tgz", - "integrity": "sha512-BICHQ67iqxQGFSzfCFTT7MRQ5XcBjG5aeKh5Ok38UBbPe5fxTyE+aHFxwVrGyr8GNlqFMLKD1D3P2K/1ks8tog==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } - }, "node_modules/@next/env": { "version": "15.4.7", "resolved": "https://registry.npmjs.org/@next/env/-/env-15.4.7.tgz", @@ -9748,26 +9731,15 @@ "integrity": "sha512-m7bpKCD4QMlFCjA/nKTs23fuvoVFoA83brRKmObCUNmi/9tVu8Ve3w4YQAnJu4q3Tjf5fr685HYIC/IA2zHRSg==", "license": "MIT" }, - "node_modules/@prisma/adapter-neon": { + "node_modules/@prisma/adapter-d1": { "version": "6.18.0", - "resolved": "https://registry.npmjs.org/@prisma/adapter-neon/-/adapter-neon-6.18.0.tgz", - "integrity": "sha512-U97AnsRVEj7nHBujGM2GFD8QZUafdSdC98FItu4TRywzazWb5JaHi/tyfxTW5PthDfXZEyjzE8FaD/9HMi6h8g==", + "resolved": "https://registry.npmjs.org/@prisma/adapter-d1/-/adapter-d1-6.18.0.tgz", + "integrity": "sha512-dJrePhyyvfZ5Pr8NCgwEJx2w7SLw6o8QkjeM080f9S+1TmL3wGpZcOUZOLNXvMUnuxnV8Q2cjNh2Vnu8oOQPug==", "license": "Apache-2.0", "dependencies": { - "@neondatabase/serverless": ">0.6.0 <2", + "@cloudflare/workers-types": "^4.20250408.0", "@prisma/driver-adapter-utils": "6.18.0", - "postgres-array": "3.0.4" - } - }, - "node_modules/@prisma/adapter-pg": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/@prisma/adapter-pg/-/adapter-pg-6.18.0.tgz", - "integrity": "sha512-eBtBOL1z2Sh0Rc2hwa4dmwoNeFs5T69tsA62AkhBvnzNfTcr/YfLeJae/wjNmvRttYDPmdiuhqZCRPNY1+8fOA==", - "license": "Apache-2.0", - "dependencies": { - "@prisma/driver-adapter-utils": "6.18.0", - "pg": "^8.11.3", - "postgres-array": "3.0.4" + "ky": "1.7.5" } }, "node_modules/@prisma/client": { @@ -11764,17 +11736,6 @@ "form-data": "^4.0.4" } }, - "node_modules/@types/pg": { - "version": "8.15.5", - "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.5.tgz", - "integrity": "sha512-LF7lF6zWEKxuT3/OR8wAZGzkg4ENGXFNyiV/JeOt9z5B+0ZVwbql9McqX5c/WStFq1GaGso7H1AzP/qSzmlCKQ==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "pg-protocol": "*", - "pg-types": "^2.2.0" - } - }, "node_modules/@types/prismjs": { "version": "1.26.5", "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.5.tgz", @@ -16479,6 +16440,18 @@ "node": ">=6" } }, + "node_modules/ky": { + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/ky/-/ky-1.7.5.tgz", + "integrity": "sha512-HzhziW6sc5m0pwi5M196+7cEBtbt0lCYi67wNsiwMUmz833wloE0gbzJPWKs1gliFKQb34huItDQX97LyOdPdA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sindresorhus/ky?sponsor=1" + } + }, "node_modules/kysely": { "version": "0.28.8", "resolved": "https://registry.npmjs.org/kysely/-/kysely-0.28.8.tgz", @@ -18926,104 +18899,6 @@ "devOptional": true, "license": "MIT" }, - "node_modules/pg": { - "version": "8.16.3", - "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.3.tgz", - "integrity": "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==", - "license": "MIT", - "dependencies": { - "pg-connection-string": "^2.9.1", - "pg-pool": "^3.10.1", - "pg-protocol": "^1.10.3", - "pg-types": "2.2.0", - "pgpass": "1.0.5" - }, - "engines": { - "node": ">= 16.0.0" - }, - "optionalDependencies": { - "pg-cloudflare": "^1.2.7" - }, - "peerDependencies": { - "pg-native": ">=3.0.1" - }, - "peerDependenciesMeta": { - "pg-native": { - "optional": true - } - } - }, - "node_modules/pg-cloudflare": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz", - "integrity": "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==", - "license": "MIT", - "optional": true - }, - "node_modules/pg-connection-string": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz", - "integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==", - "license": "MIT" - }, - "node_modules/pg-int8": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", - "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", - "license": "ISC", - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/pg-pool": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.1.tgz", - "integrity": "sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==", - "license": "MIT", - "peerDependencies": { - "pg": ">=8.0" - } - }, - "node_modules/pg-protocol": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.3.tgz", - "integrity": "sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==", - "license": "MIT" - }, - "node_modules/pg-types": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", - "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", - "license": "MIT", - "dependencies": { - "pg-int8": "1.0.1", - "postgres-array": "~2.0.0", - "postgres-bytea": "~1.0.0", - "postgres-date": "~1.0.4", - "postgres-interval": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pg-types/node_modules/postgres-array": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", - "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/pgpass": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", - "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", - "license": "MIT", - "dependencies": { - "split2": "^4.1.0" - } - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -19094,45 +18969,6 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/postgres-array": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.4.tgz", - "integrity": "sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==", - "license": "MIT", - "engines": { - "node": ">=12" - } - }, - "node_modules/postgres-bytea": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", - "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-date": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", - "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postgres-interval": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", - "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", - "license": "MIT", - "dependencies": { - "xtend": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -20200,15 +20036,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "license": "ISC", - "engines": { - "node": ">= 10.x" - } - }, "node_modules/stable-hash": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", diff --git a/package.json b/package.json index 0a0e497..afffbe9 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,7 @@ "@fontsource-variable/noto-sans-jp": "^5.2.6", "@google/genai": "^1.21.0", "@opennextjs/cloudflare": "^1.7.1", - "@prisma/adapter-neon": "^6.18.0", - "@prisma/adapter-pg": "^6.18.0", + "@prisma/adapter-d1": "^6.18.0", "@prisma/client": "^6.18.0", "@xterm/addon-fit": "^0.11.0-beta.115", "@xterm/xterm": "^5.6.0-beta.115", diff --git a/prisma.config.ts b/prisma.config.ts index 5a33cb7..19c97e5 100644 --- a/prisma.config.ts +++ b/prisma.config.ts @@ -1,4 +1,3 @@ -import "dotenv/config"; import { defineConfig } from "prisma/config"; export default defineConfig({ @@ -8,6 +7,6 @@ export default defineConfig({ }, engine: "classic", datasource: { - url: process.env.DATABASE_URL || "", + url: "", }, }); diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 52082c4..59db2cc 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -1,17 +1,13 @@ // This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema -// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions? -// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init - generator client { provider = "prisma-client" output = "../app/generated/prisma" - engineType = "client" } datasource db { - provider = "postgresql" + provider = "sqlite" url = env("DATABASE_URL") } @@ -23,11 +19,10 @@ model User { image String? createdAt DateTime @default(now()) updatedAt DateTime @default(now()) @updatedAt + isAnonymous Boolean? sessions Session[] accounts Account[] - isAnonymous Boolean? - Chat Chat[] @@unique([email]) diff --git a/wrangler.jsonc b/wrangler.jsonc index 2b5b387..9a85504 100644 --- a/wrangler.jsonc +++ b/wrangler.jsonc @@ -2,13 +2,10 @@ "main": ".open-next/worker.js", "name": "my-code", "compatibility_date": "2025-03-25", - "compatibility_flags": [ - "nodejs_compat", - "global_fetch_strictly_public", - ], + "compatibility_flags": ["nodejs_compat", "global_fetch_strictly_public"], "assets": { "directory": ".open-next/assets", - "binding": "ASSETS" + "binding": "ASSETS", }, "services": [ { @@ -24,4 +21,11 @@ // "bucket_name": "", // }, ], + "d1_databases": [ + { + "binding": "my_code_db", + "database_name": "my-code-db", + "database_id": "d7dfea8a-4b0b-44c1-b29c-4ae03c980eac", + }, + ], } From 88085897bb63f846ea8175a3ea63e32869d3270d Mon Sep 17 00:00:00 2001 From: na-trium-144 <100704180+na-trium-144@users.noreply.github.com> Date: Sun, 26 Oct 2025 18:26:16 +0900 Subject: [PATCH 2/3] Revert "Merge pull request #70 from ut-code/disable-turbopack" This reverts commit d8ce0f4ee3fd78a3845ef9cbccfd9b2bae8e1631, reversing changes made to b60d94553b69e7d7a987f20ea07e0f57ce3214a0. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index afffbe9..e608e7e 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "private": true, "scripts": { - "dev": "prisma generate && npm run cf-typegen && next dev", + "dev": "prisma generate && npm run cf-typegen && next dev --turbopack", "build": "prisma generate && npm run cf-typegen && next build", "start": "next start", "lint": "prisma generate && npm run cf-typegen && next lint", From 126b223848448b41b411c7ce7eedabdba08477be Mon Sep 17 00:00:00 2001 From: na-trium-144 <100704180+na-trium-144@users.noreply.github.com> Date: Sun, 26 Oct 2025 18:26:29 +0900 Subject: [PATCH 3/3] =?UTF-8?q?worker=E3=81=A7=E5=8B=95=E3=81=8F=E3=82=88?= =?UTF-8?q?=E3=81=86=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 -- app/api/auth/[...all]/route.ts | 8 +++-- app/lib/auth.ts | 66 ++++++++++++++++++---------------- app/lib/chatHistory.ts | 9 +++-- app/lib/prisma.ts | 25 ++++++------- next.config.ts | 1 + package.json | 2 +- prisma/schema.prisma | 6 ++-- 8 files changed, 68 insertions(+), 51 deletions(-) diff --git a/.gitignore b/.gitignore index 845ba04..5ee5d1b 100644 --- a/.gitignore +++ b/.gitignore @@ -43,5 +43,3 @@ yarn-error.log* # typescript *.tsbuildinfo next-env.d.ts - -/app/generated/prisma diff --git a/app/api/auth/[...all]/route.ts b/app/api/auth/[...all]/route.ts index fcb1ef0..7f0db11 100644 --- a/app/api/auth/[...all]/route.ts +++ b/app/api/auth/[...all]/route.ts @@ -1,4 +1,8 @@ -import { auth } from "@/lib/auth"; // path to your auth file +import { getAuthServer } from "@/lib/auth"; +import { getPrismaClient } from "@/lib/prisma"; import { toNextJsHandler } from "better-auth/next-js"; -export const { POST, GET } = toNextJsHandler(auth); +export const { POST, GET } = toNextJsHandler({ + handler: async (req) => + (await getAuthServer(await getPrismaClient())).handler(req), +}); diff --git a/app/lib/auth.ts b/app/lib/auth.ts index f4f98b4..48cef12 100644 --- a/app/lib/auth.ts +++ b/app/lib/auth.ts @@ -2,37 +2,43 @@ import { betterAuth } from "better-auth"; import { prismaAdapter } from "better-auth/adapters/prisma"; import { getCloudflareContext } from "@opennextjs/cloudflare"; import { anonymous } from "better-auth/plugins"; -import prisma from "./prisma"; import { migrateChatUser } from "./chatHistory"; +import { PrismaClient } from "@prisma/client"; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -let cloudflareEnv: any; -try { - cloudflareEnv = getCloudflareContext().env; -} catch { - // @better-auth/cli generate を実行する際には initOpenNextCloudflareForDev がセットアップされていない環境になっている - cloudflareEnv = {}; -} -export const auth = betterAuth({ - database: prismaAdapter(prisma, { - provider: "sqlite", - }), - plugins: [ - anonymous({ - onLinkAccount: ({ anonymousUser, newUser }) => - migrateChatUser(anonymousUser.user.id, newUser.user.id), +export async function getAuthServer(prisma: PrismaClient) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let cloudflareEnv: any; + try { + cloudflareEnv = getCloudflareContext().env; + } catch { + // @better-auth/cli generate を実行する際には initOpenNextCloudflareForDev がセットアップされていない環境になっている + cloudflareEnv = {}; + } + return betterAuth({ + database: prismaAdapter(prisma, { + provider: "sqlite", }), - ], - socialProviders: { - github: { - clientId: process.env.GITHUB_CLIENT_ID ?? cloudflareEnv.GITHUB_CLIENT_ID, - clientSecret: - process.env.GITHUB_CLIENT_SECRET ?? cloudflareEnv.GITHUB_CLIENT_SECRET, - }, - google: { - clientId: process.env.GOOGLE_CLIENT_ID ?? cloudflareEnv.GOOGLE_CLIENT_ID, - clientSecret: - process.env.GOOGLE_CLIENT_SECRET ?? cloudflareEnv.GOOGLE_CLIENT_SECRET, + plugins: [ + anonymous({ + onLinkAccount: ({ anonymousUser, newUser }) => + migrateChatUser(anonymousUser.user.id, newUser.user.id), + }), + ], + socialProviders: { + github: { + clientId: + process.env.GITHUB_CLIENT_ID ?? cloudflareEnv.GITHUB_CLIENT_ID, + clientSecret: + process.env.GITHUB_CLIENT_SECRET ?? + cloudflareEnv.GITHUB_CLIENT_SECRET, + }, + google: { + clientId: + process.env.GOOGLE_CLIENT_ID ?? cloudflareEnv.GOOGLE_CLIENT_ID, + clientSecret: + process.env.GOOGLE_CLIENT_SECRET ?? + cloudflareEnv.GOOGLE_CLIENT_SECRET, + }, }, - }, -}); + }); +} diff --git a/app/lib/chatHistory.ts b/app/lib/chatHistory.ts index fc67b37..c7bd850 100644 --- a/app/lib/chatHistory.ts +++ b/app/lib/chatHistory.ts @@ -1,8 +1,8 @@ "use server"; import { headers } from "next/headers"; -import { auth } from "./auth"; -import prisma from "./prisma"; +import { getAuthServer } from "./auth"; +import { getPrismaClient } from "./prisma"; export interface CreateChatMessage { role: "user" | "ai" | "error"; @@ -14,6 +14,8 @@ export async function addChat( sectionId: string, messages: CreateChatMessage[] ) { + const prisma = await getPrismaClient(); + const auth = await getAuthServer(prisma); const session = await auth.api.getSession({ headers: await headers() }); if (!session) { throw new Error("Not authenticated"); @@ -39,6 +41,8 @@ export async function addChat( export type ChatWithMessages = Awaited>; export async function getChat(docsId: string) { + const prisma = await getPrismaClient(); + const auth = await getAuthServer(prisma); const session = await auth.api.getSession({ headers: await headers() }); if (!session) { return []; @@ -63,6 +67,7 @@ export async function getChat(docsId: string) { } export async function migrateChatUser(oldUserId: string, newUserId: string) { + const prisma = await getPrismaClient(); await prisma.chat.updateMany({ where: { userId: oldUserId, diff --git a/app/lib/prisma.ts b/app/lib/prisma.ts index dae5912..6ae1703 100644 --- a/app/lib/prisma.ts +++ b/app/lib/prisma.ts @@ -1,15 +1,16 @@ -import { PrismaD1 } from "@prisma/adapter-d1"; -import { PrismaClient } from "../generated/prisma/client"; import { getCloudflareContext } from "@opennextjs/cloudflare"; +import { PrismaClient } from "@prisma/client"; +import { PrismaD1 } from "@prisma/adapter-d1"; -// eslint-disable-next-line @typescript-eslint/no-explicit-any -let cloudflareEnv: any; -try { - cloudflareEnv = getCloudflareContext().env; -} catch { - // @better-auth/cli generate を実行する際には initOpenNextCloudflareForDev がセットアップされていない環境になっている - cloudflareEnv = {}; -} +export async function getPrismaClient() { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let cloudflareEnv: any; + try { + cloudflareEnv = (await getCloudflareContext({ async: true })).env; + } catch { + // @better-auth/cli generate を実行する際には initOpenNextCloudflareForDev がセットアップされていない環境になっている + cloudflareEnv = {}; + } -const prisma = new PrismaClient({ adapter: new PrismaD1(cloudflareEnv.my_code_db) }); -export default prisma; + return new PrismaClient({ adapter: new PrismaD1(cloudflareEnv.my_code_db) }); +} diff --git a/next.config.ts b/next.config.ts index 8757724..069c8e8 100644 --- a/next.config.ts +++ b/next.config.ts @@ -15,6 +15,7 @@ const nextConfig: NextConfig = { env: { PYODIDE_VERSION: pyodideVersion, }, + serverExternalPackages: ["@prisma/client", ".prisma/client"], }; export default nextConfig; diff --git a/package.json b/package.json index e608e7e..dde4290 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "lint": "prisma generate && npm run cf-typegen && next lint", "tsc": "prisma generate && npm run cf-typegen && tsc", "format": "prettier --write app/", - "cf-preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview", + "cf-preview": "opennextjs-cloudflare build && opennextjs-cloudflare preview --port 3000", "cf-deploy": "opennextjs-cloudflare build && opennextjs-cloudflare deploy", "cf-typegen": "wrangler types --env-interface CloudflareEnv cloudflare-env.d.ts" }, diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 59db2cc..1b6c035 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -2,8 +2,10 @@ // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { - provider = "prisma-client" - output = "../app/generated/prisma" + provider = "prisma-client-js" + // outputを指定すると動作しない: https://opennext.js.org/cloudflare/howtos/db#schemaprisma + // output = "../app/generated/prisma" + // engineType = "client" } datasource db {