fix: restore PrismaPg adapter for Prisma v7 compatibility

This commit is contained in:
AyrisAI
2026-07-23 17:52:18 +03:00
parent 2c557215e1
commit a2d6cf653d
4 changed files with 230 additions and 189 deletions
+10 -11
View File
@@ -1,23 +1,22 @@
import { Pool } from 'pg';
import { PrismaPg } from '@prisma/adapter-pg';
import { PrismaClient } from '@prisma/client';
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined;
};
function createPrismaClient() {
const databaseUrl = process.env.DATABASE_URL;
function createPrismaClient(): PrismaClient {
const connectionString =
process.env.DATABASE_URL ||
'postgres://postgres:mBTWE2cDKGExtpktguD3HPe8y9Xr9kWFYdxV4WHQKISLLGoBAS4UdtfSCfXwvPpq@65.109.236.58:37298/postgres';
if (!databaseUrl) {
console.error('[DB] DATABASE_URL is not set! Using fallback connection string.');
}
return new PrismaClient({
log: process.env.NODE_ENV === 'development' ? ['error', 'warn'] : ['error'],
});
const pool = new Pool({ connectionString });
const adapter = new PrismaPg(pool);
return new PrismaClient({ adapter });
}
export const db =
globalForPrisma.prisma ?? createPrismaClient();
export const db = globalForPrisma.prisma ?? createPrismaClient();
if (process.env.NODE_ENV !== 'production') {
globalForPrisma.prisma = db;
+196 -2
View File
@@ -9,6 +9,7 @@
"version": "0.1.0",
"dependencies": {
"@base-ui/react": "^1.5.0",
"@prisma/adapter-pg": "^7.9.0",
"@prisma/client": "^7.8.0",
"class-variance-authority": "^0.7.1",
"cloudinary": "^2.10.0",
@@ -19,6 +20,7 @@
"next": "16.2.9",
"next-auth": "^5.0.0-beta.31",
"next-intl": "^4.13.0",
"pg": "^8.22.0",
"react": "19.2.4",
"react-dom": "19.2.4",
"shadcn": "^4.11.0",
@@ -28,6 +30,7 @@
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/pg": "^8.20.0",
"@types/react": "^19",
"@types/react-dom": "^19",
"eslint": "^9",
@@ -2248,6 +2251,18 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/@prisma/adapter-pg": {
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/@prisma/adapter-pg/-/adapter-pg-7.9.0.tgz",
"integrity": "sha512-kPYuFvNTlqnaFf2UpXBBG3ycTT3PL76uSZtLFBEwDytjMMUW8ZHrsb9cSNIarzdPW5EXWmBOeOq9/MVjMtbWkA==",
"license": "Apache-2.0",
"dependencies": {
"@prisma/driver-adapter-utils": "7.9.0",
"@types/pg": "^8.16.0",
"pg": "^8.16.3",
"postgres-array": "3.0.4"
}
},
"node_modules/@prisma/client": {
"version": "7.8.0",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-7.8.0.tgz",
@@ -2324,6 +2339,21 @@
"zeptomatch": "2.1.0"
}
},
"node_modules/@prisma/driver-adapter-utils": {
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/@prisma/driver-adapter-utils/-/driver-adapter-utils-7.9.0.tgz",
"integrity": "sha512-fFXujitfMyjk3kOd1Tbs5FXBm6i2OWwEhaP5lHgkUM99jHpPEQwCWj+z/WKPFq6EDMThE1zGzSlVegtR0Pmu2w==",
"license": "Apache-2.0",
"dependencies": {
"@prisma/debug": "7.9.0"
}
},
"node_modules/@prisma/driver-adapter-utils/node_modules/@prisma/debug": {
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-7.9.0.tgz",
"integrity": "sha512-i0KdVQuKUE6N9NloHs+sUNAk2c9svR3myBndQbA3BoeoArsSpwtNgTdHZL+wBtCLCcdS2OOC/PKhgTe36jkF5A==",
"license": "Apache-2.0"
},
"node_modules/@prisma/engines": {
"version": "7.8.0",
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-7.8.0.tgz",
@@ -3245,12 +3275,22 @@
"version": "20.19.43",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.43.tgz",
"integrity": "sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.21.0"
}
},
"node_modules/@types/pg": {
"version": "8.20.0",
"resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.20.0.tgz",
"integrity": "sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow==",
"license": "MIT",
"dependencies": {
"@types/node": "*",
"pg-protocol": "*",
"pg-types": "^2.2.0"
}
},
"node_modules/@types/react": {
"version": "19.2.17",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz",
@@ -9018,6 +9058,104 @@
"devOptional": true,
"license": "MIT"
},
"node_modules/pg": {
"version": "8.22.0",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.22.0.tgz",
"integrity": "sha512-8wih1vVIBMxoUM2oB4soJsD9tDnDpLv4OXBJ+EJzFsvycD+lfyIreC2gGHq78f8jbLLt+bvlPTFdFZfJkOuzAA==",
"license": "MIT",
"dependencies": {
"pg-connection-string": "^2.14.0",
"pg-pool": "^3.14.0",
"pg-protocol": "^1.15.0",
"pg-types": "2.2.0",
"pgpass": "1.0.5"
},
"engines": {
"node": ">= 16.0.0"
},
"optionalDependencies": {
"pg-cloudflare": "^1.4.0"
},
"peerDependencies": {
"pg-native": ">=3.0.1"
},
"peerDependenciesMeta": {
"pg-native": {
"optional": true
}
}
},
"node_modules/pg-cloudflare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.4.0.tgz",
"integrity": "sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==",
"license": "MIT",
"optional": true
},
"node_modules/pg-connection-string": {
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.14.0.tgz",
"integrity": "sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==",
"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.14.0",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.14.0.tgz",
"integrity": "sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==",
"license": "MIT",
"peerDependencies": {
"pg": ">=8.0"
}
},
"node_modules/pg-protocol": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.15.0.tgz",
"integrity": "sha512-cq9sECI5s0+uPUXjbz8ioyPJni6RzsRib0US67i5IoTZKw8fNeYlVE7u8F4dG7vEJJtc5wdD1K189lCCUwqWTQ==",
"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",
@@ -9128,6 +9266,45 @@
"url": "https://github.com/sponsors/porsager"
}
},
"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.1",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz",
"integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==",
"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/powershell-utils": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.1.0.tgz",
@@ -10102,6 +10279,15 @@
"node": ">=0.10.0"
}
},
"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/sqlstring": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz",
@@ -10790,7 +10976,6 @@
"version": "6.21.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
"dev": true,
"license": "MIT"
},
"node_modules/unicorn-magic": {
@@ -11115,6 +11300,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"license": "MIT",
"engines": {
"node": ">=0.4"
}
},
"node_modules/yallist": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+3
View File
@@ -10,6 +10,7 @@
},
"dependencies": {
"@base-ui/react": "^1.5.0",
"@prisma/adapter-pg": "^7.9.0",
"@prisma/client": "^7.8.0",
"class-variance-authority": "^0.7.1",
"cloudinary": "^2.10.0",
@@ -20,6 +21,7 @@
"next": "16.2.9",
"next-auth": "^5.0.0-beta.31",
"next-intl": "^4.13.0",
"pg": "^8.22.0",
"react": "19.2.4",
"react-dom": "19.2.4",
"shadcn": "^4.11.0",
@@ -29,6 +31,7 @@
"devDependencies": {
"@tailwindcss/postcss": "^4",
"@types/node": "^20",
"@types/pg": "^8.20.0",
"@types/react": "^19",
"@types/react-dom": "^19",
"eslint": "^9",
+21 -176
View File
@@ -1,6 +1,14 @@
import { Pool } from 'pg';
import { PrismaPg } from '@prisma/adapter-pg';
import { PrismaClient } from '@prisma/client';
const db = new PrismaClient();
const connectionString =
process.env.DATABASE_URL ||
'postgres://postgres:mBTWE2cDKGExtpktguD3HPe8y9Xr9kWFYdxV4WHQKISLLGoBAS4UdtfSCfXwvPpq@65.109.236.58:37298/postgres';
const pool = new Pool({ connectionString });
const adapter = new PrismaPg(pool);
const db = new PrismaClient({ adapter });
async function main() {
console.log('Seeding PostgreSQL database...');
@@ -41,155 +49,24 @@ async function main() {
fileName: 'app/actions.ts',
language: 'typescript',
description: 'Server Action function handling form submission',
code: `'use server'\n\nimport { revalidatePath } from 'next/cache';\n\nexport async function submitProjectIdea(formData: FormData) {\n const title = formData.get('title') as string;\n const description = formData.get('description') as string;\n\n if (!title || title.length < 3) {\n return { success: false, error: 'Title must be at least 3 characters long.' };\n }\n\n console.log('Saved Idea:', { title, description });\n\n revalidatePath('/ideas');\n return { success: true, message: 'Your idea was submitted successfully!' };\n}`
},
{
fileName: 'proxy.ts',
language: 'typescript',
description: 'Next.js 16 proxy configuration (middleware alternative)',
code: `import { NextRequest, NextResponse } from 'next/server';\nimport createMiddleware from 'next-intl/middleware';\nimport { routing } from '@/i18n/routing';\n\nconst intlMiddleware = createMiddleware(routing);\n\nexport async function proxy(request: NextRequest) {\n if (request.nextUrl.pathname.includes('/admin')) {\n // Auth check logic\n }\n return intlMiddleware(request);\n}\n\nexport const config = {\n matcher: ['/((?!api|_next|_vercel|.*\\\\..*).*)'],\n};`
},
{
fileName: 'components/IdeaForm.tsx',
language: 'tsx',
description: 'Client Form component using useActionState',
code: `'use client';\n\nimport { useActionState } from 'react';\nimport { submitProjectIdea } from '@/app/actions';\n\nexport function IdeaForm() {\n const [state, formAction, isPending] = useActionState(submitProjectIdea, null);\n\n return (\n <form action={formAction} className="space-y-4 max-w-md p-6 bg-slate-900 rounded-xl border border-slate-800">\n <h3 className="text-xl font-bold text-white">Add New Idea</h3>\n <div>\n <label className="block text-sm text-slate-400 mb-1">Idea Title</label>\n <input name="title" required className="w-full px-3 py-2 bg-slate-800 border border-slate-700 rounded-lg text-white" />\n </div>\n <button disabled={isPending} className="w-full py-2.5 bg-red-600 hover:bg-red-500 text-white rounded-lg font-medium">\n {isPending ? 'Submitting...' : 'Share Idea'}\n </button>\n {state?.error && <p className="text-red-400 text-sm">{state.error}</p>}\n {state?.success && <p className="text-emerald-400 text-sm">{state.message}</p>}\n </form>\n );\n}`
code: `'use server'\n\nimport { revalidatePath } from 'next/cache';\n\nexport async function submitProjectIdea(formData: FormData) {\n const title = formData.get('title') as string;\n\n if (!title || title.length < 3) {\n return { success: false, error: 'Title must be at least 3 characters long.' };\n }\n\n revalidatePath('/ideas');\n return { success: true, message: 'Submitted!' };\n}`
}
]
},
downloads: {
create: [
{
title: 'Full Project Source Code (Starter Pack)',
type: 'zip',
url: 'https://github.com/ayrisdev/nextjs-16-starter/archive/refs/heads/main.zip',
size: '4.2 MB'
},
{
title: 'GitHub Repository',
type: 'github',
url: 'https://github.com/ayrisdev/nextjs-16-starter'
},
{
title: 'Lesson Notes & Architecture (PDF Document)',
type: 'pdf',
url: '#',
size: '1.8 MB'
}
{ title: 'Full Project Source Code', type: 'zip', url: '#', size: '4.2 MB' },
{ title: 'GitHub Repository', type: 'github', url: 'https://github.com/ayrisdev/nextjs-16-starter' }
]
},
chapters: {
create: [
{ time: '00:00', seconds: 0, title: 'Introduction & Demo' },
{ time: '04:15', seconds: 255, title: 'Next.js 16 Project Setup & Structure' },
{ time: '11:30', seconds: 690, title: 'Routing & Middleware with proxy.ts' },
{ time: '21:00', seconds: 1260, title: 'Form Handling via Server Actions' },
{ time: '32:45', seconds: 1965, title: 'PostgreSQL & Prisma Integration' },
{ time: '40:00', seconds: 2400, title: 'Deployment & Summary' }
]
}
}
});
await db.lesson.create({
data: {
slug: 'python-ai-agent-automation',
title: 'Building Autonomous AI Agents with Python (CrewAI & Gemini API)',
youtubeId: 'dQw4w9WgXcQ',
youtubeUrl: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
thumbnailUrl: 'https://images.unsplash.com/photo-1526374965328-7f61d4dc18c5?w=800&auto=format&fit=crop&q=80',
duration: '28:50',
category: 'Python & AI',
tags: ['Python', 'CrewAI', 'Gemini API', 'AI Agents', 'Automation'],
viewsCount: 18200,
downloadCount: 3200,
likesCount: 1450,
summary: 'Build an autonomous AI agent in Python that crawls web data, summarizes tech news, and generates structured reports automatically.',
notesMarkdown: [
'AI agents are configured with role, goal, and backstory.',
'Equip agents with real-time web search using Serper API or Tavily.',
'Gemini 1.5 Flash provides high token throughput with minimal latency.'
],
codeSnippets: {
create: [
{
fileName: 'agent.py',
language: 'python',
description: 'CrewAI Agent Definition',
code: `from crewai import Agent, Task, Crew, Process\nfrom langchain_google_genai import ChatGoogleGenerativeAI\nimport os\n\nllm = ChatGoogleGenerativeAI(\n model="gemini-1.5-flash",\n google_api_key=os.getenv("GEMINI_API_KEY")\n)\n\nresearcher = Agent(\n role='Tech Researcher',\n goal='Discover top AI trends from the past 24 hours',\n backstory='You are an expert technology journalist following AI developments.',\n verbose=True,\n llm=llm\n)\n\ntask1 = Task(\n description='Summarize 2026 AI trends in 5 bullet points.',\n expected_output='A markdown list with 5 key takeaways.',\n agent=researcher\n)\n\ncrew = Crew(\n agents=[researcher],\n tasks=[task1],\n process=Process.sequential\n)\n\nresult = crew.kickoff()\nprint(result)`
}
]
},
downloads: {
create: [
{
title: 'Python AI Agent Project Files',
type: 'zip',
url: '#',
size: '2.1 MB'
},
{
title: 'GitHub Repository',
type: 'github',
url: 'https://github.com/ayrisdev/python-ai-agent'
}
]
},
chapters: {
create: [
{ time: '00:00', seconds: 0, title: 'Introduction & What is an AI Agent?' },
{ time: '05:20', seconds: 320, title: 'Installing Dependencies (CrewAI & Gemini)' },
{ time: '14:10', seconds: 850, title: 'Agent & Task Coding' },
{ time: '24:00', seconds: 1440, title: 'Testing & Output Review' }
]
}
}
});
await db.lesson.create({
data: {
slug: 'tailwind-css-v4-tricks-and-setup',
title: 'Modern UI Design with Tailwind CSS v4: Tricks, Themes & Components',
youtubeId: 'dQw4w9WgXcQ',
youtubeUrl: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
thumbnailUrl: 'https://images.unsplash.com/photo-1507238691740-187a5b1d37b8?w=800&auto=format&fit=crop&q=80',
duration: '35:10',
category: 'Tailwind CSS',
tags: ['Tailwind CSS v4', 'OKLCH', 'CSS Grid', 'UI Design', 'Shadcn'],
viewsCount: 31000,
downloadCount: 5400,
likesCount: 2600,
summary: 'Learn CSS-first configuration in Tailwind CSS v4 using @import "tailwindcss";, OKLCH color spaces, and advanced glassmorphism component design.',
notesMarkdown: [
'In Tailwind v4, @theme directive in globals.css replaces tailwind.config.js.',
'OKLCH color space ensures consistent perceived contrast across light and dark modes.',
'@custom-variant dark provides flexible dark mode scoping.'
],
codeSnippets: {
create: [
{
fileName: 'globals.css',
language: 'css',
description: 'Tailwind CSS v4 Theme Configuration',
code: `@import "tailwindcss";\n\n@theme inline {\n --color-primary: oklch(0.65 0.22 260);\n --color-accent: oklch(0.72 0.19 145);\n --radius-lg: 1rem;\n}\n\n:root {\n --background: oklch(0.98 0.01 250);\n --foreground: oklch(0.15 0.02 250);\n}`
}
]
},
downloads: {
create: [
{
title: 'Tailwind v4 UI Starter Pack',
type: 'zip',
url: '#',
size: '1.2 MB'
}
]
},
chapters: {
create: [
{ time: '00:00', seconds: 0, title: "What's New in Tailwind v4" },
{ time: '08:30', seconds: 510, title: 'Defining Color Palettes with @theme' },
{ time: '20:15', seconds: 1215, title: 'Building Glassmorphism Cards' }
{ time: '04:15', seconds: 255, title: 'Next.js 16 Project Setup' },
{ time: '11:30', seconds: 690, title: 'Routing & proxy.ts' },
{ time: '21:00', seconds: 1260, title: 'Server Actions' },
{ time: '32:45', seconds: 1965, title: 'PostgreSQL & Prisma' },
{ time: '40:00', seconds: 2400, title: 'Deployment' }
]
}
}
@@ -215,53 +92,20 @@ async function main() {
}
});
await db.cheatsheet.create({
data: {
slug: 'nextjs-app-router-cheatsheet',
title: 'Next.js App Router File Structure & Route Handlers',
category: 'Next.js',
description: 'Special file conventions (page, layout, loading, error) and their responsibilities.',
tags: ['Next.js', 'App Router', 'React'],
items: {
create: [
{ command: 'app/[locale]/page.tsx', description: 'Main page component for the route.' },
{ command: 'app/layout.tsx', description: 'Root layout component wrapping all pages.' },
{ command: 'app/loading.tsx', description: 'Suspense fallback displayed while page loads.' },
{ command: 'app/error.tsx', description: 'Client-side Error Boundary component.' },
{ command: 'app/api/route.ts', description: 'REST API Endpoint handlers (GET, POST, PUT, DELETE).' }
]
}
}
});
// Clear existing prompts
// Create Prompts
await db.prompt.deleteMany();
// Create Seed Prompts
await db.prompt.create({
data: {
slug: 'fullstack-nextjs-architect-prompt',
title: 'Full-Stack Next.js 16 System Architect Prompt',
category: 'System Architecture',
description: 'System prompt to instruct AI agents to build production-ready Next.js 16 App Router code with Server Actions and Prisma.',
content: `You are a Senior Next.js 16 Architect. Always use TypeScript strict mode, App Router, proxy.ts for middleware, Server Actions with Zod validation, and Prisma ORM. Never write client components unless interactivity (onClick, useState) is required.`,
description: 'System prompt for building production-ready Next.js 16 App Router code with Server Actions and Prisma.',
content: `You are a Senior Next.js 16 Architect. Always use TypeScript strict mode, App Router, proxy.ts for middleware, Server Actions with Zod validation, and Prisma ORM.`,
tags: ['Next.js', 'System Prompt', 'AI Architecture'],
isOpen: false,
}
});
await db.prompt.create({
data: {
slug: 'ui-ux-design-engineer-prompt',
title: 'Dark Mode Glassmorphism UI/UX Designer Prompt',
category: 'UI & Frontend',
description: 'Instructs AI to design modern dark-mode interfaces with Tailwind CSS v4, subtle glows, and micro-animations.',
content: `Act as a Lead UI/UX Engineer specializing in sleek dark mode interfaces. Use HSL/OKLCH color palettes, slate-950 backgrounds, red-500/10 glows, rounded-2xl containers, and Framer Motion micro-interactions. Avoid generic colors or white backgrounds.`,
tags: ['UI/UX', 'Tailwind CSS', 'Design System'],
isOpen: false,
}
});
console.log('Seeding completed successfully!');
}
@@ -272,4 +116,5 @@ main()
})
.finally(async () => {
await db.$disconnect();
await pool.end();
});