import { AdminMessage, ConnectedAircraft, getPublicUser, MissionLog, Prisma, prisma, } from "@repo/db"; import { Router } from "express"; import { io } from "../index"; const router: Router = Router(); // Get all connectedAircrafts router.post("/", async (req, res) => { try { const filter = req.body?.filter || {}; const connectedAircrafts = await prisma.connectedAircraft.findMany({ where: filter, }); res.json(connectedAircrafts); } catch (error) { console.error(error); res.status(500).json({ error: "Failed to fetch connectedAircrafts" }); } }); // Get a single connectedAircraft by ID router.get("/:id", async (req, res) => { const { id } = req.params; try { const connectedAircraft = await prisma.connectedAircraft.findUnique({ where: { id: Number(id) }, }); if (connectedAircraft) { res.json(connectedAircraft); } else { res.status(404).json({ error: "ConnectedAircraft not found" }); } } catch (error) { console.error(error); res.status(500).json({ error: "Failed to fetch connectedAircraft" }); } }); // Update a connectedAircraft by ID router.patch("/:id", async (req, res) => { const { id } = req.params; const aircraftUpdate = req.body as Prisma.ConnectedAircraftUpdateInput; try { const oldConnectedAircraft = await prisma.connectedAircraft.findUnique({ where: { id: Number(id) }, include: { Station: true, User: true, }, }); const updatedConnectedAircraft = await prisma.connectedAircraft.update({ where: { id: Number(id) }, data: { ...aircraftUpdate, }, }); const mission = await prisma.mission.findFirst({ where: { state: "running", missionStationIds: { has: updatedConnectedAircraft.stationId, }, }, }); if ( mission && aircraftUpdate.fmsStatus && oldConnectedAircraft && updatedConnectedAircraft && oldConnectedAircraft.fmsStatus !== updatedConnectedAircraft.fmsStatus ) { const newMissionLog = mission.missionLog as any as MissionLog[]; newMissionLog.push({ type: "station-log", auto: true, data: { oldFMSstatus: oldConnectedAircraft.fmsStatus, newFMSstatus: updatedConnectedAircraft.fmsStatus, station: oldConnectedAircraft.Station, stationId: updatedConnectedAircraft.stationId, user: getPublicUser(oldConnectedAircraft.User), }, timeStamp: new Date().toISOString(), }); await prisma.mission.update({ where: { id: mission.id }, data: { missionLog: newMissionLog as any, }, }); } res.json(updatedConnectedAircraft); // When change is only the estimated logout time, we don't need to emit an event if (Object.keys(aircraftUpdate).length === 1 && aircraftUpdate.esimatedLogoutTime) return; io.to("dispatchers").emit("update-connectedAircraft", updatedConnectedAircraft); io.to(`user:${updatedConnectedAircraft.userId}`).emit( "aircraft-update", updatedConnectedAircraft, ); } catch (error) { console.error(error); res.status(500).json({ error: "Failed to update connectedAircraft" }); } }); // Kick a connectedAircraft by ID router.delete("/:id", async (req, res) => { const { id } = req.params; const bann = req.body?.bann as boolean; const requiredPermission = bann ? "ADMIN_USER" : "ADMIN_KICK"; if (!req.user) { res.status(401).json({ error: "Unauthorized" }); return; } if (!req.user.permissions.includes(requiredPermission)) { res.status(403).json({ error: "Forbidden" }); return; } try { const aircraft = await prisma.connectedAircraft.update({ where: { id: Number(id) }, data: { logoutTime: new Date() }, include: bann ? { User: true } : undefined, }); if (!aircraft) { res.status(404).json({ error: "ConnectedAircraft not found" }); return; } const status = bann ? "ban" : "kick"; io.to(`user:${aircraft.userId}`).emit("notification", { type: "admin-message", message: "Verbindung durch einen Administrator getrennt", status, data: { admin: getPublicUser(req.user) }, } as AdminMessage); io.in(`user:${aircraft.userId}`).disconnectSockets(true); if (bann) { await prisma.user.update({ where: { id: aircraft.userId }, data: { permissions: { set: req.user.permissions.filter((p) => p !== "PILOT"), }, }, }); } res.status(204).send(); } catch (error) { console.error(error); res.status(500).json({ error: "Failed to disconnect pilot" }); } }); export default router;