diff --git a/app/api/projects/[projectId]/route.ts b/app/api/projects/[projectId]/route.ts index 4c29cc1..3b08da5 100644 --- a/app/api/projects/[projectId]/route.ts +++ b/app/api/projects/[projectId]/route.ts @@ -1,5 +1,7 @@ import { NextResponse } from 'next/server'; -import { getAdminAuth, getAdminDb } from '@/lib/firebase/admin'; +import { getServerSession } from 'next-auth'; +import { authOptions } from '@/lib/auth/authOptions'; +import { query } from '@/lib/db-postgres'; export async function GET( request: Request, @@ -7,49 +9,29 @@ export async function GET( ) { try { const { projectId } = await params; - - // Authentication (skip in development if no auth header) - const authHeader = request.headers.get('Authorization'); - const isDevelopment = process.env.NODE_ENV === 'development'; - - if (!isDevelopment || authHeader?.startsWith('Bearer ')) { - if (!authHeader?.startsWith('Bearer ')) { - return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); - } - const token = authHeader.substring(7); - const auth = getAdminAuth(); - const decoded = await auth.verifyIdToken(token); - - if (!decoded?.uid) { - return NextResponse.json({ error: 'Invalid token' }, { status: 401 }); - } + const session = await getServerSession(authOptions); + if (!session?.user?.email) { + return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } - // Fetch project from Firestore - const adminDb = getAdminDb(); - const projectDoc = await adminDb.collection('projects').doc(projectId).get(); - - if (!projectDoc.exists) { + 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 projectData = projectDoc.data(); - - return NextResponse.json({ - success: true, - project: { - id: projectDoc.id, - ...projectData, - }, - }); + return NextResponse.json({ success: true, project: { id: rows[0].id, ...rows[0].data } }); } catch (error) { - console.error('[API /projects/:id] Error fetching project:', error); + console.error('[GET /api/projects/:id] Error:', error); return NextResponse.json( - { - error: 'Failed to fetch project', - details: error instanceof Error ? error.message : String(error) - }, + { error: 'Failed to fetch project', details: error instanceof Error ? error.message : String(error) }, { status: 500 } ); } @@ -62,54 +44,43 @@ export async function PATCH( try { const { projectId } = await params; const body = await request.json(); - - // Authentication (skip in development if no auth header) - const authHeader = request.headers.get('Authorization'); - const isDevelopment = process.env.NODE_ENV === 'development'; - - if (!isDevelopment || authHeader?.startsWith('Bearer ')) { - if (!authHeader?.startsWith('Bearer ')) { - return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); - } - const token = authHeader.substring(7); - const auth = getAdminAuth(); - const decoded = await auth.verifyIdToken(token); - - if (!decoded?.uid) { - return NextResponse.json({ error: 'Invalid token' }, { status: 401 }); - } + const session = await getServerSession(authOptions); + if (!session?.user?.email) { + return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } - // Update project in Firestore - const adminDb = getAdminDb(); - const updateData: any = {}; + // Fetch current data (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]); - // Only update fields that are provided - if (body.vision !== undefined) updateData.vision = body.vision; - if (body.description !== undefined) updateData.description = body.description; - if (body.name !== undefined) updateData.name = body.name; - if (body.githubRepo !== undefined) updateData.githubRepo = body.githubRepo; + if (rows.length === 0) { + return NextResponse.json({ error: 'Project not found' }, { status: 404 }); + } - updateData.updatedAt = new Date().toISOString(); + const current = rows[0].data || {}; + const updated = { ...current }; + const allowedFields = ['vision', 'description', 'name', 'githubRepo', 'productVision', 'productName']; + for (const field of allowedFields) { + if (body[field] !== undefined) updated[field] = body[field]; + } + updated.updatedAt = new Date().toISOString(); - await adminDb.collection('projects').doc(projectId).update(updateData); - - return NextResponse.json({ - success: true, - message: 'Project updated successfully', - updated: Object.keys(updateData) - }); + await query(` + UPDATE fs_projects SET data = $1::jsonb WHERE id = $2 + `, [JSON.stringify(updated), projectId]); + return NextResponse.json({ success: true, message: 'Project updated successfully' }); } catch (error) { - console.error('[API /projects/:id] Error updating project:', error); + console.error('[PATCH /api/projects/:id] Error:', error); return NextResponse.json( - { - error: 'Failed to update project', - details: error instanceof Error ? error.message : String(error) - }, + { error: 'Failed to update project', details: error instanceof Error ? error.message : String(error) }, { status: 500 } ); } } -