My-Weekly-ToDo-List/src/app/api/someday-lists/external/route.ts
2026-03-07 17:39:26 +01:00

114 lines
4.8 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from "@/lib/auth";
import { PrismaClient } from '@prisma/client';
import { createGoogleClient, createGoogleTaskList } from '@/lib/google-tasks';
import { createMsTodoList } from '@/lib/microsoft-todo';
import { getOutlookAccessToken } from '@/lib/outlook-token';
import { createAppleReminderList } from '@/lib/apple-reminders';
import { createSynologyReminderList } from '@/lib/synology-tasks';
const prisma = new PrismaClient();
export async function POST(req: NextRequest) {
try {
const session = await getServerSession(authOptions);
if (!session?.user?.email) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const body = await req.json();
const { title, provider } = body;
if (!title) {
return NextResponse.json({ error: 'Title is required' }, { status: 400 });
}
const user = await prisma.user.findUnique({
where: { email: session.user.email }
});
if (!user) {
return NextResponse.json({ error: 'User not found' }, { status: 404 });
}
let externalId: string | undefined;
let externalProvider: string | undefined;
if (provider === 'google') {
const account = await prisma.account.findFirst({
where: { userId: user.id, provider: { in: ['google-calendar', 'google'] } },
orderBy: { provider: 'asc' }
});
if (!account || !account.access_token) {
return NextResponse.json({ error: 'Google account not connected' }, { status: 400 });
}
const client = createGoogleClient(account.access_token, account.refresh_token || undefined);
const newList = await createGoogleTaskList(client, title);
externalId = newList.id;
externalProvider = 'google';
} else if (provider === 'outlook' || provider === 'microsoft') {
const accessToken = await getOutlookAccessToken(user.id);
if (!accessToken) {
return NextResponse.json({ error: 'Outlook account not connected' }, { status: 400 });
}
const newList = await createMsTodoList(accessToken, title);
externalId = newList.id;
externalProvider = 'outlook';
} else if (provider === 'apple') {
const connection = await prisma.calendarConnection.findFirst({
where: { userId: user.id, provider: 'apple' }
});
if (!connection || !connection.accessToken) {
return NextResponse.json({ error: 'Apple account not connected' }, { status: 400 });
}
const [email, password] = connection.accessToken.split(':');
const newList = await createAppleReminderList(email, password, title);
externalId = newList.id;
externalProvider = 'apple';
} else if (provider === 'synology') {
const connection = await prisma.calendarConnection.findFirst({
where: { userId: user.id, provider: 'synology' }
});
if (!connection || !connection.accessToken || !connection.refreshToken) {
return NextResponse.json({ error: 'Synology account not connected or missing server URL' }, { status: 400 });
}
const [username, password] = connection.accessToken.split(':');
const serverUrl = connection.refreshToken;
const newList = await createSynologyReminderList(serverUrl, username, password, title);
externalId = newList.id;
externalProvider = 'synology';
}
// Create local SomedayList
console.log('Creating SomedayList with data:', {
userId: user.id,
title,
externalId: externalId ?? null,
externalProvider: externalProvider ?? null,
});
const somedayList = await prisma.somedayList.create({
data: {
userId: user.id,
title,
order: 0, // In external route we can just default to 0 or calculate it
externalId: externalId ?? null,
externalProvider: externalProvider ?? null,
lastSyncedAt: externalId ? new Date() : null
}
});
console.log('Successfully created SomedayList:', somedayList.id);
return NextResponse.json({ success: true, somedayList });
} catch (error: any) {
console.error('Error creating external someday list:', error);
return NextResponse.json(
{ error: error.message || 'Failed to create list' },
{ status: 500 }
);
}
}