import { NextResponse } from 'next/server'; import { getServerSession } from 'next-auth'; import { authOptions } from '@/lib/auth'; import { getMailboxes } from '@/lib/services/email-service'; import { getRedisClient } from '@/lib/redis'; import { getImapConnection } from '@/lib/services/email-service'; import { MailCredentials } from '@prisma/client'; import { prisma } from '@/lib/prisma'; // Keep track of last prefetch time for each user const lastPrefetchMap = new Map(); const PREFETCH_COOLDOWN_MS = 30000; // 30 seconds cooldown between prefetches // Cache TTL for folders in Redis (5 minutes) const FOLDERS_CACHE_TTL = 3600; // 1 hour // Redis key for folders cache const FOLDERS_CACHE_KEY = (userId: string, accountId: string) => `email:folders:${userId}:${accountId}`; /** * This endpoint is called when the app initializes to check if the user has email credentials * and to start prefetching email data in the background if they do */ export async function GET() { try { const session = await getServerSession(authOptions); if (!session?.user?.id) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } // Get Redis connection const redis = getRedisClient(); if (!redis) { return NextResponse.json({ error: 'Redis connection failed' }, { status: 500 }); } // Get user with their accounts const user = await prisma.user.findUnique({ where: { id: session.user.id }, include: { mailCredentials: true } }); if (!user) { return NextResponse.json({ error: 'User not found' }, { status: 404 }); } // Get all accounts for the user const accounts = (user.mailCredentials || []) as MailCredentials[]; if (accounts.length === 0) { return NextResponse.json({ error: 'No email accounts found' }, { status: 404 }); } // Fetch folders for each account const accountsWithFolders = await Promise.all( accounts.map(async (account: MailCredentials) => { const cacheKey = FOLDERS_CACHE_KEY(user.id, account.id); // Try to get folders from Redis cache first const cachedFolders = await redis.get(cacheKey); if (cachedFolders) { return { ...account, folders: JSON.parse(cachedFolders) }; } // If not in cache, fetch from IMAP const client = await getImapConnection(user.id, account.id); if (!client) { return { ...account, folders: ['INBOX', 'Sent', 'Drafts', 'Trash', 'Junk'] }; } try { const folders = await getMailboxes(client); // Cache the folders in Redis await redis.set( cacheKey, JSON.stringify(folders), 'EX', FOLDERS_CACHE_TTL ); return { ...account, folders }; } catch (error) { console.error(`Error fetching folders for account ${account.id}:`, error); return { ...account, folders: ['INBOX', 'Sent', 'Drafts', 'Trash', 'Junk'] }; } }) ); return NextResponse.json({ accounts: accountsWithFolders }); } catch (error) { console.error('Error in session route:', error); return NextResponse.json( { error: 'Internal server error' }, { status: 500 } ); } }