import { NextResponse } from 'next/server'; import { getServerSession } from 'next-auth'; import { authOptions } from '@/lib/auth/authOptions'; import { query } from '@/lib/db-postgres'; import { provisionTheiaWorkspace } from '@/lib/cloud-run-workspace'; export async function POST( _request: Request, { params }: { params: Promise<{ projectId: string }> }, ) { try { const { projectId } = await params; const session = await getServerSession(authOptions); if (!session?.user?.email) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } // Verify ownership const rows = await query<{ id: string; data: any }>(` SELECT p.id, p.data FROM fs_projects p JOIN fs_users u ON u.id = p.user_id WHERE p.id = $1 AND u.data->>'email' = $2 LIMIT 1 `, [projectId, session.user.email]); if (rows.length === 0) { return NextResponse.json({ error: 'Project not found' }, { status: 404 }); } const project = rows[0].data; if (project.theiaWorkspaceUrl) { return NextResponse.json({ success: true, workspaceUrl: project.theiaWorkspaceUrl, message: 'Workspace already provisioned', }); } const slug = project.slug; if (!slug) { return NextResponse.json({ error: 'Project has no slug — cannot provision workspace' }, { status: 400 }); } // Provision Cloud Run workspace const workspace = await provisionTheiaWorkspace(slug, projectId, project.giteaRepo ?? null); // Save URL back to project record await query(` UPDATE fs_projects SET data = data || jsonb_build_object( 'theiaWorkspaceUrl', $1::text, 'theiaAppUuid', $2::text ) WHERE id = $3 `, [workspace.serviceUrl, workspace.serviceName, projectId]); return NextResponse.json({ success: true, workspaceUrl: workspace.serviceUrl, }); } catch (error) { console.error('[POST /api/projects/:id/workspace] Error:', error); return NextResponse.json( { error: 'Failed to provision workspace', details: error instanceof Error ? error.message : String(error) }, { status: 500 }, ); } }