import { sessionOptions } from '@/lib/session'; import { withIronSessionApiRoute } from 'iron-session/next'; import type { NextApiRequest, NextApiResponse } from 'next' import client from "@/lib/mongodb"; const db = client.db(process.env.MONGODB_DB); export default withIronSessionApiRoute(handler, sessionOptions); async function handler(req: NextApiRequest, res: NextApiResponse) { const { op } = req.query if (req.method === 'GET') { switch (op) { default: res.status(400).json({ error: 'Invalid operation!' }) } } else if (req.method === 'POST') { switch (op) { case 'crossRefEmails': res.status(200).json(await crossRefEmails(req.body.emails)); break; case 'dontExist': res.status(200).json(await dontExist(req.body.emails)) break; case 'entityCheck': res.status(200).json(await entityCheck(req.body)); break; case 'crossRefClassrooms': res.status(200).json(await crossRefClassrooms(req.body.sets)); break; default: res.status(400).json({ error: 'Invalid operation!' }) } } else { res.status(400).end(`Method ${req.method} Not Allowed`) } } async function crossRefEmails(emails: string[]) { return await db.collection("users").aggregate([ { $match: { email: { $in: emails } } }, { $project: { _id: 0, email: 1 } } ]).toArray(); } async function dontExist(emails: string[]): Promise { const existingUsers = await db.collection('users') .find( { email: { $in: emails } }, { projection: { _id: 0, email: 1 } } ) .toArray(); const existingEmails = new Set(existingUsers.map(u => u.email)); return emails.filter(email => !existingEmails.has(email)); } async function entityCheck(body: Record): Promise { const { entities, emails } = body; const pipeline = [ // Match users with the provided emails { $match: { email: { $in: emails } } }, // Match users who don't have any of the entities { $match: { $or: [ // Either they have no entities array { entities: { $exists: false } }, // Or their entities array is empty { entities: { $size: 0 } }, // Or none of their entities match the provided IDs { entities: { $not: { $elemMatch: { id: { $in: entities.map((e: any) => e.id) } } } } } ] } }, // Project only the email field { $project: { _id: 0, email: 1 } } ]; const results = await db.collection('users').aggregate(pipeline).toArray(); return results.map((result: any) => result.email); } async function crossRefClassrooms(sets: { email: string, classroom: string }[]) { const pipeline = [ // Match users with the provided emails { $match: { email: { $in: sets.map(set => set.email) } } }, // Lookup groups that contain the user's ID in participants { $lookup: { from: 'groups', let: { userId: '$id', userEmail: '$email' }, pipeline: [ { $match: { $expr: { $and: [ { $in: ['$$userId', '$participants'] }, { // Match the classroom that corresponds to this user's email $let: { vars: { matchingSet: { $arrayElemAt: [ { $filter: { input: sets, cond: { $eq: ['$$this.email', '$$userEmail'] } } }, 0 ] } }, in: { $eq: ['$name', '$$matchingSet.classroom'] } } } ] } } } ], as: 'matchingGroups' } }, // Only keep users who have matching groups { $match: { matchingGroups: { $ne: [] } } }, // Project only the email { $project: { _id: 0, email: 1 } } ]; const results = await db.collection('users').aggregate(pipeline).toArray(); return results.map((result: any) => result.email); }