import { NextResponse } from 'next/server'; import { getServerSession } from 'next-auth'; import { authOptions } from '@/lib/auth/authOptions'; import { query } from '@/lib/db-postgres'; import { randomUUID } from 'crypto'; import type { ProjectPhaseData, ProjectPhaseScores } from '@/lib/types/project-artifacts'; export async function POST(request: Request) { try { const session = await getServerSession(authOptions); if (!session?.user?.email) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const email = session.user.email; // Resolve Firebase user ID and workspace from fs_users const users = await query<{ id: string; data: any }>(` SELECT id, data FROM fs_users WHERE data->>'email' = $1 LIMIT 1 `, [email]); const firebaseUserId = users[0]?.id || session.user.id || randomUUID(); const userData = users[0]?.data || {}; const workspace = userData.workspace || email.split('@')[0].toLowerCase().replace(/[^a-z0-9]+/g, '-') + '-account'; const body = await request.json(); const { projectName, projectType, slug, vision, product, workspacePath, chatgptUrl, githubRepo, githubRepoId, githubRepoUrl, githubDefaultBranch, } = body; // Check slug uniqueness const existing = await query(`SELECT id FROM fs_projects WHERE slug = $1 LIMIT 1`, [slug]); if (existing.length > 0) { return NextResponse.json({ error: 'Project slug already exists' }, { status: 400 }); } const projectId = randomUUID(); const now = new Date().toISOString(); const projectData = { id: projectId, name: projectName, slug, userId: firebaseUserId, workspace, projectType, productName: product?.name || projectName, productVision: vision || '', isForClient: product?.isForClient || false, hasLogo: product?.hasLogo || false, hasDomain: product?.hasDomain || false, hasWebsite: product?.hasWebsite || false, hasGithub: !!githubRepo, hasChatGPT: !!chatgptUrl, workspacePath: workspacePath || null, workspaceName: workspacePath ? workspacePath.split('/').pop() : null, githubRepo: githubRepo || null, githubRepoId: githubRepoId || null, githubRepoUrl: githubRepoUrl || null, githubDefaultBranch: githubDefaultBranch || null, chatgptUrl: chatgptUrl || null, extensionLinked: false, status: 'active', currentPhase: 'collector', phaseStatus: 'not_started', phaseData: {} as ProjectPhaseData, phaseScores: {} as ProjectPhaseScores, createdAt: now, updatedAt: now, }; await query(` INSERT INTO fs_projects (id, data, user_id, workspace, slug) VALUES ($1, $2::jsonb, $3, $4, $5) `, [projectId, JSON.stringify(projectData), firebaseUserId, workspace, slug]); // Associate unlinked sessions for this workspace path if (workspacePath) { await query(` UPDATE fs_sessions SET data = jsonb_set( jsonb_set(data, '{projectId}', $1::jsonb), '{needsProjectAssociation}', 'false' ) WHERE user_id = $2 AND data->>'workspacePath' = $3 AND (data->>'needsProjectAssociation')::boolean = true `, [JSON.stringify(projectId), firebaseUserId, workspacePath]); } console.log('[API] Created project', projectId, slug); return NextResponse.json({ success: true, projectId, slug, workspace }); } catch (error) { console.error('[POST /api/projects/create] Error:', error); return NextResponse.json( { error: 'Failed to create project', details: error instanceof Error ? error.message : String(error) }, { status: 500 } ); } }