import { json, error } from '@sveltejs/kit'; import type { RequestHandler } from './$types'; import { db } from '$lib/server/db'; import { friendship, user } from '$lib/server/db/schema'; import { eq } from 'drizzle-orm'; import { notificationService } from '$lib/server/notifications'; import { pushService } from '$lib/server/push'; export const PUT: RequestHandler = async ({ params, request, locals }) => { if (!locals.user) { throw error(401, 'Unauthorized'); } const { friendshipId } = params; const data = await request.json(); const { action } = data; // 'accept', 'decline', 'block' if (!friendshipId) { throw error(400, 'Friendship ID is required'); } if (!action || !['accept', 'decline', 'block'].includes(action)) { throw error(400, 'Valid action is required (accept, decline, block)'); } try { // Find the friendship const existingFriendship = await db .select() .from(friendship) .where(eq(friendship.id, friendshipId)) .limit(1); if (existingFriendship.length === 0) { throw error(404, 'Friendship not found'); } const friendshipRecord = existingFriendship[0]; // Check if user is authorized to modify this friendship // User can only accept/decline requests sent TO them, or cancel requests they sent const isReceiver = friendshipRecord.friendId === locals.user.id; const isSender = friendshipRecord.userId === locals.user.id; if (!isReceiver && !isSender) { throw error(403, 'Not authorized to modify this friendship'); } // Only receivers can accept or decline pending requests if ((action === 'accept' || action === 'decline') && !isReceiver) { throw error(403, 'Only the recipient can accept or decline friend requests'); } // Only accept pending requests if (action === 'accept' && friendshipRecord.status !== 'pending') { throw error(400, 'Can only accept pending friend requests'); } let newStatus: string; if (action === 'accept') { newStatus = 'accepted'; } else if (action === 'decline') { newStatus = 'declined'; } else if (action === 'block') { newStatus = 'blocked'; } else { throw error(400, 'Invalid action'); } // Update the friendship status const updatedFriendship = await db .update(friendship) .set({ status: newStatus }) .where(eq(friendship.id, friendshipId)) .returning(); // Send notification if friend request was accepted if (action === 'accept') { const senderId = friendshipRecord.userId; const shouldNotify = await notificationService.shouldNotify(senderId, 'friend_accepted'); if (shouldNotify) { // Get accepter's username const accepterUser = await db .select({ username: user.username }) .from(user) .where(eq(user.id, locals.user.id)) .limit(1); const accepterUsername = accepterUser[0]?.username || 'Someone'; await notificationService.createNotification({ userId: senderId, type: 'friend_accepted', title: 'Friend request accepted', message: `${accepterUsername} accepted your friend request`, data: { friendshipId: friendshipRecord.id, accepterId: locals.user.id, accepterUsername } }); // Send push notification await pushService.sendPushNotification(senderId, { title: 'Friend request accepted', message: `${accepterUsername} accepted your friend request`, url: '/friends', tag: 'friend_accepted', data: { friendshipId: friendshipRecord.id, accepterId: locals.user.id } }); } } return json({ success: true, friendship: updatedFriendship[0] }); } catch (err) { console.error('Error updating friendship:', err); if (err instanceof Error && 'status' in err) { throw err; } throw error(500, 'Failed to update friendship'); } }; export const DELETE: RequestHandler = async ({ params, locals }) => { if (!locals.user) { throw error(401, 'Unauthorized'); } const { friendshipId } = params; if (!friendshipId) { throw error(400, 'Friendship ID is required'); } try { // Find the friendship const existingFriendship = await db .select() .from(friendship) .where(eq(friendship.id, friendshipId)) .limit(1); if (existingFriendship.length === 0) { throw error(404, 'Friendship not found'); } const friendshipRecord = existingFriendship[0]; // Check if user is part of this friendship if ( friendshipRecord.userId !== locals.user.id && friendshipRecord.friendId !== locals.user.id ) { throw error(403, 'Not authorized to delete this friendship'); } // Delete the friendship await db.delete(friendship).where(eq(friendship.id, friendshipId)); return json({ success: true }); } catch (err) { console.error('Error deleting friendship:', err); if (err instanceof Error && 'status' in err) { throw err; } throw error(500, 'Failed to delete friendship'); } };