import { NextRequest, NextResponse } from 'next/server'; import { db, habits, users } from '@/lib/db'; import { getTokenCookie } from '@/lib/auth/cookies'; import { eq, and } from 'drizzle-orm'; async function getUserFromToken() { const token = await getTokenCookie(); if (!token) return null; const userRows = await db.select().from(users).where(eq(users.token, token)); return userRows.length > 0 ? userRows[0] : null; } export async function PATCH( request: NextRequest, { params }: { params: Promise<{ id: string }> } ) { try { const { id } = await params; const habitId = parseInt(id); if (isNaN(habitId)) { return NextResponse.json({ error: 'Invalid habit ID' }, { status: 400 }); } const user = await getUserFromToken(); if (!user) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } // Verify habit belongs to user const habitRows = await db .select() .from(habits) .where(and(eq(habits.id, habitId), eq(habits.userId, user.id))); if (habitRows.length === 0) { return NextResponse.json({ error: 'Habit not found' }, { status: 404 }); } const body = (await request.json()) as { name?: string; type?: string; color?: string; icon?: string; targetFrequency?: { value: number; period: 'day' | 'week' | 'month' }; }; const { name, type, color, icon, targetFrequency } = body; // Validate type if provided if (type && !['positive', 'neutral', 'negative'].includes(type)) { return NextResponse.json( { error: 'Type must be one of: positive, neutral, negative' }, { status: 400 } ); } const updatedHabitRows = await db .update(habits) .set({ ...(name && { name }), ...(type && { type: type as 'positive' | 'neutral' | 'negative' }), ...(color && { color }), ...(icon && { icon }), ...(targetFrequency && { targetFrequency }), }) .where(and(eq(habits.id, habitId), eq(habits.userId, user.id))) .returning(); return NextResponse.json({ habit: updatedHabitRows[0] }); } catch (error) { console.error('Update habit error:', error); return NextResponse.json({ error: 'Internal server error' }, { status: 500 }); } } export async function DELETE( request: NextRequest, { params }: { params: Promise<{ id: string }> } ) { try { const { id } = await params; const habitId = parseInt(id); if (isNaN(habitId)) { return NextResponse.json({ error: 'Invalid habit ID' }, { status: 400 }); } const user = await getUserFromToken(); if (!user) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } // Verify habit belongs to user const habitRows = await db .select() .from(habits) .where(and(eq(habits.id, habitId), eq(habits.userId, user.id))); if (habitRows.length === 0) { return NextResponse.json({ error: 'Habit not found' }, { status: 404 }); } // Soft delete (archive) await db .update(habits) .set({ isArchived: true, archivedAt: new Date() }) .where(and(eq(habits.id, habitId), eq(habits.userId, user.id))); return NextResponse.json({ success: true }); } catch (error) { console.error('Delete habit error:', error); return NextResponse.json({ error: 'Internal server error' }, { status: 500 }); } }