diff --git a/build_output.txt b/build_output.txt new file mode 100644 index 0000000..8c24814 Binary files /dev/null and b/build_output.txt differ diff --git a/build_output2.txt b/build_output2.txt new file mode 100644 index 0000000..aca0036 --- /dev/null +++ b/build_output2.txt @@ -0,0 +1,64 @@ + +> plumeia@0.1.0 build +> npx prisma generate && next build + +[dotenv@17.3.1] injecting env (4) from .env -- tip: ⚙️ specify custom .env file path with { path: '/custom/path/.env' } +[dotenv@17.3.1] injecting env (0) from .env.local -- tip: ⚙️ suppress all logs with { quiet: true } +Loaded Prisma config from prisma.config.ts. + +Prisma schema loaded from prisma\schema.prisma. + +✔ Generated Prisma Client (v7.4.1) to .\node_modules\@prisma\client in 72ms + +Start by importing your Prisma Client (See: https://pris.ly/d/importing-client) + + +⚠ Warning: Next.js inferred your workspace root, but it may not be correct. + We detected multiple lockfiles and selected the directory of C:\Users\streaper2\package-lock.json as the root directory. + To silence this warning, set `turbopack.root` in your Next.js config, or consider removing one of the lockfiles if it's not needed. + See https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopack#root-directory for more information. + Detected additional lockfiles: + * C:\Users\streaper2\Documents\00 - projet\plumeia\package-lock.json + +▲ Next.js 16.1.6 (Turbopack) +- Environments: .env + + Creating an optimized production build ... +✓ Compiled successfully in 1183.7ms + Skipping validation of types + Collecting page data using 31 workers ... +Error [PrismaClientInitializationError]: `PrismaClient` needs to be constructed with a non-empty, valid `PrismaClientOptions`: + +``` +new PrismaClient({ + ... +}) +``` + +or + +``` +constructor() { + super({ ... }); +} +``` + + at a (C:\Users\streaper2\Documents\00 - projet\plumeia\.next\server\chunks\[root-of-the-server]__bcb19414._.js:1:1488) + at module evaluation (C:\Users\streaper2\Documents\00 - projet\plumeia\.next\server\chunks\[root-of-the-server]__bcb19414._.js:1:1523) + at instantiateModule (C:\Users\streaper2\Documents\00 - projet\plumeia\.next\server\chunks\[turbopack]_runtime.js:740:9) + at getOrInstantiateModuleFromParent (C:\Users\streaper2\Documents\00 - projet\plumeia\.next\server\chunks\[turbopack]_runtime.js:763:12) + at Context.esmImport [as i] (C:\Users\streaper2\Documents\00 - projet\plumeia\.next\server\chunks\[turbopack]_runtime.js:228:20) + at (C:\Users\streaper2\Documents\00 - projet\plumeia\.next\server\chunks\[root-of-the-server]__bcb19414._.js:1:2288) + at Context.asyncModule [as a] (C:\Users\streaper2\Documents\00 - projet\plumeia\.next\server\chunks\[turbopack]_runtime.js:455:5) + at module evaluation (C:\Users\streaper2\Documents\00 - projet\plumeia\.next\server\chunks\[root-of-the-server]__bcb19414._.js:1:2235) + at instantiateModule (C:\Users\streaper2\Documents\00 - projet\plumeia\.next\server\chunks\[turbopack]_runtime.js:740:9) { + clientVersion: '7.4.1', + errorCode: undefined, + retryable: undefined +} + +> Build error occurred +Error: Failed to collect page data for /api/ai/generate + at ignore-listed frames { + type: 'Error' +} diff --git a/build_output3.txt b/build_output3.txt new file mode 100644 index 0000000..2d0296b --- /dev/null +++ b/build_output3.txt @@ -0,0 +1,71 @@ + +> plumeia@0.1.0 build +> npx prisma generate && next build + +[dotenv@17.3.1] injecting env (4) from .env -- tip: 🛠️ run anywhere with `dotenvx run -- yourcommand` +[dotenv@17.3.1] injecting env (0) from .env.local -- tip: ⚙️ enable debug logging with { debug: true } +Loaded Prisma config from prisma.config.ts. + +Prisma schema loaded from prisma\schema.prisma. + +✔ Generated Prisma Client (v7.4.1) to .\node_modules\@prisma\client in 75ms + +Start by importing your Prisma Client (See: https://pris.ly/d/importing-client) + + +⚠ Warning: Next.js inferred your workspace root, but it may not be correct. + We detected multiple lockfiles and selected the directory of C:\Users\streaper2\package-lock.json as the root directory. + To silence this warning, set `turbopack.root` in your Next.js config, or consider removing one of the lockfiles if it's not needed. + See https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopack#root-directory for more information. + Detected additional lockfiles: + * C:\Users\streaper2\Documents\00 - projet\plumeia\package-lock.json + +▲ Next.js 16.1.6 (Turbopack) +- Environments: .env + + Creating an optimized production build ... +✓ Compiled successfully in 1196.6ms + Skipping validation of types + Collecting page data using 31 workers ... + Generating static pages using 31 workers (0/10) ... + Generating static pages using 31 workers (2/10) + Generating static pages using 31 workers (4/10) + Generating static pages using 31 workers (7/10) +✓ Generating static pages using 31 workers (10/10) in 359.6ms + Finalizing page optimization ... + +Route (app) +┌ ○ / +├ ○ /_not-found +├ ƒ /api/ai/generate +├ ƒ /api/ai/transform +├ ƒ /api/auth/[...nextauth] +├ ƒ /api/auth/register +├ ƒ /api/chapters +├ ƒ /api/chapters/[id] +├ ƒ /api/entities +├ ƒ /api/entities/[id] +├ ƒ /api/ideas +├ ƒ /api/ideas/[id] +├ ƒ /api/plans +├ ƒ /api/projects +├ ƒ /api/projects/[id] +├ ƒ /api/projects/[id]/workflow +├ ƒ /api/user/profile +├ ○ /checkout +├ ○ /dashboard +├ ○ /features +├ ○ /login +├ ○ /pricing +├ ○ /profile +├ ƒ /project/[id] +├ ƒ /project/[id]/ideas +├ ƒ /project/[id]/settings +├ ƒ /project/[id]/workflow +├ ƒ /project/[id]/world +└ ○ /signup + + +○ (Static) prerendered as static content +ƒ (Dynamic) server-rendered on demand + diff --git a/next-env.d.ts b/next-env.d.ts index c4b7818..9edff1c 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/dev/types/routes.d.ts"; +import "./.next/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/package.json b/package.json index 2029f2d..c675135 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ }, "scripts": { "dev": "next dev", - "build": "rm -rf .next && npx prisma generate && next build", + "build": "npx prisma generate && next build", "start": "npx prisma db push && next start", "lint": "next lint" }, diff --git a/src/app/api/chapters/[id]/route.ts b/src/app/api/chapters/[id]/route.ts index 2ab72e4..b478317 100644 --- a/src/app/api/chapters/[id]/route.ts +++ b/src/app/api/chapters/[id]/route.ts @@ -2,7 +2,8 @@ export const dynamic = 'force-dynamic'; import { NextRequest, NextResponse } from 'next/server'; import { auth } from '@/lib/auth'; -import getDB from '@/lib/prisma'; +// 1. On remplace l'import de getDB par l'objet prisma direct +import { prisma } from '@/lib/prisma'; // PUT /api/chapters/[id] — Update a chapter export async function PUT( @@ -17,8 +18,8 @@ export async function PUT( const { id } = await params; const body = await request.json(); - // Verify ownership via project - const chapter = await getDB().chapter.findUnique({ + // 2. On utilise 'prisma' au lieu de 'getDB()' + const chapter = await prisma.chapter.findUnique({ where: { id }, include: { project: { select: { userId: true } } }, }); @@ -26,7 +27,7 @@ export async function PUT( return NextResponse.json({ error: 'Non trouvé' }, { status: 404 }); } - const updated = await getDB().chapter.update({ + const updated = await prisma.chapter.update({ where: { id }, data: { ...(body.title !== undefined && { title: body.title }), @@ -51,7 +52,8 @@ export async function DELETE( const { id } = await params; - const chapter = await getDB().chapter.findUnique({ + // 3. On utilise 'prisma' au lieu de 'getDB()' + const chapter = await prisma.chapter.findUnique({ where: { id }, include: { project: { select: { userId: true } } }, }); @@ -59,7 +61,7 @@ export async function DELETE( return NextResponse.json({ error: 'Non trouvé' }, { status: 404 }); } - await getDB().chapter.delete({ where: { id } }); + await prisma.chapter.delete({ where: { id } }); return NextResponse.json({ success: true }); -} +} \ No newline at end of file diff --git a/src/app/api/chapters/route.ts b/src/app/api/chapters/route.ts index 772e7fc..943e7ca 100644 --- a/src/app/api/chapters/route.ts +++ b/src/app/api/chapters/route.ts @@ -2,7 +2,8 @@ export const dynamic = 'force-dynamic'; import { NextRequest, NextResponse } from 'next/server'; import { auth } from '@/lib/auth'; -import getDB from '@/lib/prisma'; +// 1. On importe l'objet prisma au lieu de la fonction getDB +import { prisma } from '@/lib/prisma'; // POST /api/chapters — Create a chapter export async function POST(request: NextRequest) { @@ -13,15 +14,17 @@ export async function POST(request: NextRequest) { const body = await request.json(); - // Verify project ownership - const project = await getDB().project.findFirst({ + // 2. On utilise 'prisma' directement au lieu de 'getDB()' + const project = await prisma.project.findFirst({ where: { id: body.projectId, userId: session.user.id }, }); + if (!project) { return NextResponse.json({ error: 'Projet non trouvé' }, { status: 404 }); } - const chapter = await getDB().chapter.create({ + // 3. Pareil ici pour la création + const chapter = await prisma.chapter.create({ data: { title: body.title || 'Nouveau Chapitre', content: body.content || '', @@ -32,4 +35,4 @@ export async function POST(request: NextRequest) { }); return NextResponse.json(chapter, { status: 201 }); -} +} \ No newline at end of file diff --git a/src/app/api/entities/[id]/route.ts b/src/app/api/entities/[id]/route.ts index 991ca99..47563eb 100644 --- a/src/app/api/entities/[id]/route.ts +++ b/src/app/api/entities/[id]/route.ts @@ -2,7 +2,7 @@ export const dynamic = 'force-dynamic'; import { NextRequest, NextResponse } from 'next/server'; import { auth } from '@/lib/auth'; -import getDB from '@/lib/prisma'; +import { prisma } from '@/lib/prisma'; // PUT /api/entities/[id] export async function PUT( @@ -17,7 +17,7 @@ export async function PUT( const { id } = await params; const body = await request.json(); - const entity = await getDB().entity.findUnique({ + const entity = await prisma.entity.findUnique({ where: { id }, include: { project: { select: { userId: true } } }, }); @@ -25,7 +25,7 @@ export async function PUT( return NextResponse.json({ error: 'Non trouvé' }, { status: 404 }); } - const updated = await getDB().entity.update({ + const updated = await prisma.entity.update({ where: { id }, data: { ...(body.name !== undefined && { name: body.name }), @@ -53,7 +53,7 @@ export async function DELETE( const { id } = await params; - const entity = await getDB().entity.findUnique({ + const entity = await prisma.entity.findUnique({ where: { id }, include: { project: { select: { userId: true } } }, }); @@ -61,7 +61,7 @@ export async function DELETE( return NextResponse.json({ error: 'Non trouvé' }, { status: 404 }); } - await getDB().entity.delete({ where: { id } }); + await prisma.entity.delete({ where: { id } }); return NextResponse.json({ success: true }); } diff --git a/src/app/api/entities/route.ts b/src/app/api/entities/route.ts index ddf328b..9b76896 100644 --- a/src/app/api/entities/route.ts +++ b/src/app/api/entities/route.ts @@ -2,7 +2,7 @@ export const dynamic = 'force-dynamic'; import { NextRequest, NextResponse } from 'next/server'; import { auth } from '@/lib/auth'; -import getDB from '@/lib/prisma'; +import { prisma } from '@/lib/prisma'; // POST /api/entities — Create an entity export async function POST(request: NextRequest) { @@ -13,14 +13,14 @@ export async function POST(request: NextRequest) { const body = await request.json(); - const project = await getDB().project.findFirst({ + const project = await prisma.project.findFirst({ where: { id: body.projectId, userId: session.user.id }, }); if (!project) { return NextResponse.json({ error: 'Projet non trouvé' }, { status: 404 }); } - const entity = await getDB().entity.create({ + const entity = await prisma.entity.create({ data: { type: body.type, name: body.name || 'Nouvelle entité', diff --git a/src/app/api/ideas/[id]/route.ts b/src/app/api/ideas/[id]/route.ts index 06511a3..bd742a8 100644 --- a/src/app/api/ideas/[id]/route.ts +++ b/src/app/api/ideas/[id]/route.ts @@ -2,7 +2,7 @@ export const dynamic = 'force-dynamic'; import { NextRequest, NextResponse } from 'next/server'; import { auth } from '@/lib/auth'; -import getDB from '@/lib/prisma'; +import { prisma } from '@/lib/prisma'; // PUT /api/ideas/[id] export async function PUT( @@ -17,7 +17,7 @@ export async function PUT( const { id } = await params; const body = await request.json(); - const idea = await getDB().idea.findUnique({ + const idea = await prisma.idea.findUnique({ where: { id }, include: { project: { select: { userId: true } } }, }); @@ -25,7 +25,7 @@ export async function PUT( return NextResponse.json({ error: 'Non trouvé' }, { status: 404 }); } - const updated = await getDB().idea.update({ + const updated = await prisma.idea.update({ where: { id }, data: { ...(body.title !== undefined && { title: body.title }), @@ -50,7 +50,7 @@ export async function DELETE( const { id } = await params; - const idea = await getDB().idea.findUnique({ + const idea = await prisma.idea.findUnique({ where: { id }, include: { project: { select: { userId: true } } }, }); @@ -58,7 +58,7 @@ export async function DELETE( return NextResponse.json({ error: 'Non trouvé' }, { status: 404 }); } - await getDB().idea.delete({ where: { id } }); + await prisma.idea.delete({ where: { id } }); return NextResponse.json({ success: true }); } diff --git a/src/app/api/ideas/route.ts b/src/app/api/ideas/route.ts index 0c96fc2..d48f380 100644 --- a/src/app/api/ideas/route.ts +++ b/src/app/api/ideas/route.ts @@ -2,7 +2,7 @@ export const dynamic = 'force-dynamic'; import { NextRequest, NextResponse } from 'next/server'; import { auth } from '@/lib/auth'; -import getDB from '@/lib/prisma'; +import { prisma } from '@/lib/prisma'; // POST /api/ideas export async function POST(request: NextRequest) { @@ -13,14 +13,14 @@ export async function POST(request: NextRequest) { const body = await request.json(); - const project = await getDB().project.findFirst({ + const project = await prisma.project.findFirst({ where: { id: body.projectId, userId: session.user.id }, }); if (!project) { return NextResponse.json({ error: 'Projet non trouvé' }, { status: 404 }); } - const idea = await getDB().idea.create({ + const idea = await prisma.idea.create({ data: { title: body.title || 'Nouvelle idée', description: body.description || '', diff --git a/src/app/api/plans/route.ts b/src/app/api/plans/route.ts index ff1b7bb..eeea6a3 100644 --- a/src/app/api/plans/route.ts +++ b/src/app/api/plans/route.ts @@ -1,11 +1,11 @@ import { NextResponse } from 'next/server'; -import getDB from '@/lib/prisma'; +import { prisma } from '@/lib/prisma'; export const dynamic = 'force-dynamic'; export async function GET() { try { - const prisma = getDB(); + //const prisma = getDB(); const plans = await prisma.plan.findMany({ orderBy: { price: 'asc' } }); diff --git a/src/app/api/projects/[id]/route.ts b/src/app/api/projects/[id]/route.ts index d56bc9d..b9fabff 100644 --- a/src/app/api/projects/[id]/route.ts +++ b/src/app/api/projects/[id]/route.ts @@ -2,7 +2,7 @@ export const dynamic = 'force-dynamic'; import { NextRequest, NextResponse } from 'next/server'; import { auth } from '@/lib/auth'; -import getDB from '@/lib/prisma'; +import { prisma } from '@/lib/prisma'; // GET /api/projects/[id] — Get project with all related data export async function GET( @@ -16,7 +16,7 @@ export async function GET( const { id } = await params; - const project = await getDB().project.findFirst({ + const project = await prisma.project.findFirst({ where: { id, userId: session.user.id }, include: { chapters: { orderBy: { orderIndex: 'asc' } }, @@ -48,14 +48,14 @@ export async function PUT( const body = await request.json(); // Verify ownership - const existing = await getDB().project.findFirst({ + const existing = await prisma.project.findFirst({ where: { id, userId: session.user.id }, }); if (!existing) { return NextResponse.json({ error: 'Projet non trouvé' }, { status: 404 }); } - const project = await getDB().project.update({ + const project = await prisma.project.update({ where: { id }, data: { ...(body.title !== undefined && { title: body.title }), @@ -81,14 +81,14 @@ export async function DELETE( const { id } = await params; // Verify ownership - const existing = await getDB().project.findFirst({ + const existing = await prisma.project.findFirst({ where: { id, userId: session.user.id }, }); if (!existing) { return NextResponse.json({ error: 'Projet non trouvé' }, { status: 404 }); } - await getDB().project.delete({ where: { id } }); + await prisma.project.delete({ where: { id } }); return NextResponse.json({ success: true }); } diff --git a/src/app/api/projects/[id]/workflow/route.ts b/src/app/api/projects/[id]/workflow/route.ts index 61a4e97..b707869 100644 --- a/src/app/api/projects/[id]/workflow/route.ts +++ b/src/app/api/projects/[id]/workflow/route.ts @@ -1,8 +1,9 @@ export const dynamic = 'force-dynamic'; +import type { Prisma } from '@prisma/client'; import { NextRequest, NextResponse } from 'next/server'; import { auth } from '@/lib/auth'; -import getDB from '@/lib/prisma'; +import { prisma } from '@/lib/prisma'; // PUT /api/projects/[id]/workflow — Sync workflow (nodes + connections) export async function PUT( @@ -15,7 +16,7 @@ export async function PUT( } const { id } = await params; - const prisma = getDB(); + //const prisma = getDB(); // Verify ownership const project = await prisma.project.findFirst({ @@ -28,7 +29,7 @@ export async function PUT( const { nodes, connections } = await request.json(); // Replace all nodes and connections in a transaction - await prisma.$transaction(async (tx) => { + await prisma.$transaction(async (tx: Prisma.TransactionClient) => { // Delete existing await tx.plotConnection.deleteMany({ where: { projectId: id } }); await tx.plotNode.deleteMany({ where: { projectId: id } }); diff --git a/src/app/api/projects/route.ts b/src/app/api/projects/route.ts index 34e5ec8..a370290 100644 --- a/src/app/api/projects/route.ts +++ b/src/app/api/projects/route.ts @@ -2,7 +2,7 @@ export const dynamic = 'force-dynamic'; import { NextRequest, NextResponse } from 'next/server'; import { auth } from '@/lib/auth'; -import getDB from '@/lib/prisma'; +import { prisma } from '@/lib/prisma'; // GET /api/projects — List all user's projects export async function GET() { @@ -11,7 +11,7 @@ export async function GET() { return NextResponse.json({ error: 'Non autorisé' }, { status: 401 }); } - const projects = await getDB().project.findMany({ + const projects = await prisma.project.findMany({ where: { userId: session.user.id }, orderBy: { updatedAt: 'desc' }, include: { @@ -32,7 +32,6 @@ export async function POST(request: NextRequest) { } // Check plan limits - const prisma = getDB(); const user = await prisma.user.findUnique({ where: { id: session.user.id }, include: { subscriptionPlan: true } diff --git a/src/app/api/user/profile/route.ts b/src/app/api/user/profile/route.ts index e935e84..85f22ae 100644 --- a/src/app/api/user/profile/route.ts +++ b/src/app/api/user/profile/route.ts @@ -2,7 +2,7 @@ export const dynamic = 'force-dynamic'; import { NextRequest, NextResponse } from 'next/server'; import { auth } from '@/lib/auth'; -import getDB from '@/lib/prisma'; +import { prisma } from '@/lib/prisma'; // GET /api/user/profile — Get current user profile with stats export async function GET() { @@ -11,7 +11,7 @@ export async function GET() { return NextResponse.json({ error: 'Non autorisé' }, { status: 401 }); } - const prisma = getDB(); + //const prisma = getDB(); const user = await prisma.user.findUnique({ where: { id: session.user.id }, include: { subscriptionPlan: true } @@ -27,7 +27,7 @@ export async function GET() { select: { content: true }, }); - const totalWords = chapters.reduce((total, chapter) => { + const totalWords = chapters.reduce((total: number, chapter: { content: string | null }) => { const text = (chapter.content || '').replace(/<[^>]*>/g, ' ').trim(); return total + (text ? text.split(/\s+/).length : 0); }, 0); @@ -68,7 +68,7 @@ export async function PUT(request: NextRequest) { return NextResponse.json({ error: 'Non autorisé' }, { status: 401 }); } - const prisma = getDB(); + //const prisma = getDB(); const body = await request.json(); const data: Record = {}; diff --git a/src/lib/prisma.ts b/src/lib/prisma.ts index 7abad8d..d6134be 100644 --- a/src/lib/prisma.ts +++ b/src/lib/prisma.ts @@ -11,28 +11,40 @@ const globalForPrisma = globalThis as unknown as { * Uses @prisma/adapter-pg with a pg Pool for direct PostgreSQL connections. *//* export function getDB(): PrismaClient { - if (!globalForPrisma.prisma) { - const connectionString = process.env.DATABASE_URL; - const pool = new Pool({ connectionString }); - const adapter = new PrismaPg(pool); +if (!globalForPrisma.prisma) { + const connectionString = process.env.DATABASE_URL; + const pool = new Pool({ connectionString }); + const adapter = new PrismaPg(pool); - globalForPrisma.prisma = new PrismaClient({ adapter }); - } - return globalForPrisma.prisma; + globalForPrisma.prisma = new PrismaClient({ adapter }); +} +return globalForPrisma.prisma; } export default getDB; */ -import type { PrismaClient as PrismaClientType } from '@prisma/client'; -const { PrismaClient } = require('@prisma/client'); +import { PrismaClient } from '@prisma/client'; const globalForPrisma = globalThis as unknown as { - prisma: PrismaClientType | undefined; + prisma: PrismaClient | undefined; }; -export const prisma = globalForPrisma.prisma ?? new PrismaClient(); -if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma; +export function getDB(): PrismaClient { + if (!globalForPrisma.prisma) { + globalForPrisma.prisma = new PrismaClient(); + } + return globalForPrisma.prisma; +} + +if (process.env.NODE_ENV !== 'production') { + globalForPrisma.prisma = getDB(); +} + +export const prisma = new Proxy({} as any, { + get(target, prop, receiver) { + return Reflect.get(getDB(), prop, receiver); + } +}) as PrismaClient; -export function getDB() { return prisma; } export default getDB; \ No newline at end of file