TreasureTrails/backend/dist/routes/routes.js

338 lines
12 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = require("express");
const index_1 = require("../index");
const auth_1 = require("../middleware/auth");
const router = (0, express_1.Router)();
router.get('/game/:gameId', async (req, res) => {
try {
const { gameId } = req.params;
const routes = await index_1.prisma.route.findMany({
where: { gameId: gameId },
include: {
routeLegs: {
orderBy: { sequenceNumber: 'asc' }
},
_count: { select: { teamRoutes: true } }
},
orderBy: { createdAt: 'asc' }
});
res.json(routes);
}
catch (error) {
console.error('List routes error:', error);
res.status(500).json({ error: 'Failed to list routes' });
}
});
router.get('/:id', async (req, res) => {
try {
const { id } = req.params;
const route = await index_1.prisma.route.findUnique({
where: { id: id },
include: {
routeLegs: {
orderBy: { sequenceNumber: 'asc' }
},
teamRoutes: {
include: {
team: {
include: {
members: { include: { user: { select: { id: true, name: true } } } }
}
}
}
}
}
});
if (!route) {
return res.status(404).json({ error: 'Route not found' });
}
res.json(route);
}
catch (error) {
console.error('Get route error:', error);
res.status(500).json({ error: 'Failed to get route' });
}
});
router.post('/', auth_1.authenticate, async (req, res) => {
try {
const { gameId, name, description, color } = req.body;
if (!gameId || !name) {
return res.status(400).json({ error: 'Game ID and name are required' });
}
const game = await index_1.prisma.game.findUnique({ where: { id: gameId } });
if (!game) {
return res.status(404).json({ error: 'Game not found' });
}
if (game.gameMasterId !== req.user.id) {
return res.status(403).json({ error: 'Not authorized' });
}
const route = await index_1.prisma.route.create({
data: {
gameId,
name,
description,
color: color || '#3498db'
},
include: {
routeLegs: true
}
});
res.json(route);
}
catch (error) {
console.error('Create route error:', error);
res.status(500).json({ error: 'Failed to create route' });
}
});
router.put('/:id', auth_1.authenticate, async (req, res) => {
try {
const { id } = req.params;
const { name, description, color } = req.body;
const route = await index_1.prisma.route.findUnique({
where: { id: id },
include: { game: true }
});
if (!route) {
return res.status(404).json({ error: 'Route not found' });
}
if (route.game.gameMasterId !== req.user.id) {
return res.status(403).json({ error: 'Not authorized' });
}
const updated = await index_1.prisma.route.update({
where: { id: id },
data: {
name: name || route.name,
description: description !== undefined ? description : route.description,
color: color || route.color
},
include: {
routeLegs: {
orderBy: { sequenceNumber: 'asc' }
}
}
});
res.json(updated);
}
catch (error) {
console.error('Update route error:', error);
res.status(500).json({ error: 'Failed to update route' });
}
});
router.delete('/:id', auth_1.authenticate, async (req, res) => {
try {
const { id } = req.params;
const route = await index_1.prisma.route.findUnique({
where: { id: id },
include: { game: true }
});
if (!route) {
return res.status(404).json({ error: 'Route not found' });
}
if (route.game.gameMasterId !== req.user.id) {
return res.status(403).json({ error: 'Not authorized' });
}
await index_1.prisma.route.delete({ where: { id: id } });
res.json({ message: 'Route deleted' });
}
catch (error) {
console.error('Delete route error:', error);
res.status(500).json({ error: 'Failed to delete route' });
}
});
router.post('/:id/legs', auth_1.authenticate, async (req, res) => {
try {
const { id } = req.params;
const { description, conditionType, conditionDetails, locationLat, locationLng, timeLimit } = req.body;
const route = await index_1.prisma.route.findUnique({
where: { id: id },
include: {
game: true,
routeLegs: true
}
});
if (!route) {
return res.status(404).json({ error: 'Route not found' });
}
if (route.game.gameMasterId !== req.user.id) {
return res.status(403).json({ error: 'Not authorized' });
}
const maxSequence = route.routeLegs.length > 0
? Math.max(...route.routeLegs.map(l => l.sequenceNumber))
: 0;
const routeLeg = await index_1.prisma.routeLeg.create({
data: {
routeId: id,
sequenceNumber: maxSequence + 1,
description: description || '',
conditionType: conditionType || 'photo',
conditionDetails,
locationLat,
locationLng,
timeLimit
}
});
res.json(routeLeg);
}
catch (error) {
console.error('Add route leg error:', error);
res.status(500).json({ error: 'Failed to add leg to route' });
}
});
router.put('/:id/legs/:legId', auth_1.authenticate, async (req, res) => {
try {
const { id, legId } = req.params;
const { description, conditionType, conditionDetails, locationLat, locationLng, timeLimit, sequenceNumber } = req.body;
const route = await index_1.prisma.route.findUnique({
where: { id: id },
include: { game: true }
});
if (!route) {
return res.status(404).json({ error: 'Route not found' });
}
if (route.game.gameMasterId !== req.user.id) {
return res.status(403).json({ error: 'Not authorized' });
}
const routeLeg = await index_1.prisma.routeLeg.update({
where: { id: legId },
data: {
description: description !== undefined ? description : undefined,
conditionType: conditionType !== undefined ? conditionType : undefined,
conditionDetails: conditionDetails !== undefined ? conditionDetails : undefined,
locationLat: locationLat !== undefined ? locationLat : undefined,
locationLng: locationLng !== undefined ? locationLng : undefined,
timeLimit: timeLimit !== undefined ? timeLimit : undefined,
sequenceNumber: sequenceNumber !== undefined ? sequenceNumber : undefined
}
});
res.json(routeLeg);
}
catch (error) {
console.error('Update route leg error:', error);
res.status(500).json({ error: 'Failed to update route leg' });
}
});
router.delete('/:id/legs/:legId', auth_1.authenticate, async (req, res) => {
try {
const { id, legId } = req.params;
const route = await index_1.prisma.route.findUnique({
where: { id: id },
include: { game: true }
});
if (!route) {
return res.status(404).json({ error: 'Route not found' });
}
if (route.game.gameMasterId !== req.user.id) {
return res.status(403).json({ error: 'Not authorized' });
}
await index_1.prisma.routeLeg.delete({ where: { id: legId } });
const remainingLegs = await index_1.prisma.routeLeg.findMany({
where: { routeId: id },
orderBy: { sequenceNumber: 'asc' }
});
for (let i = 0; i < remainingLegs.length; i++) {
if (remainingLegs[i].sequenceNumber !== i + 1) {
await index_1.prisma.routeLeg.update({
where: { id: remainingLegs[i].id },
data: { sequenceNumber: i + 1 }
});
}
}
res.json({ message: 'Leg deleted' });
}
catch (error) {
console.error('Delete route leg error:', error);
res.status(500).json({ error: 'Failed to delete route leg' });
}
});
router.post('/:id/legs/:legId/photo', auth_1.authenticate, async (req, res) => {
try {
const { id, legId } = req.params;
const { teamId, photoUrl } = req.body;
const route = await index_1.prisma.route.findUnique({
where: { id: id },
include: { game: true }
});
if (!route) {
return res.status(404).json({ error: 'Route not found' });
}
const routeLeg = await index_1.prisma.routeLeg.findFirst({
where: { id: legId, routeId: id }
});
if (!routeLeg) {
return res.status(404).json({ error: 'Route leg not found' });
}
const member = await index_1.prisma.teamMember.findFirst({
where: { teamId, userId: req.user.id }
});
const team = await index_1.prisma.team.findUnique({ where: { id: teamId } });
if (!member && team?.captainId !== req.user.id) {
return res.status(403).json({ error: 'Not authorized' });
}
const submission = await index_1.prisma.photoSubmission.create({
data: {
teamId,
routeId: id,
routeLegId: legId,
photoUrl
}
});
res.json(submission);
}
catch (error) {
console.error('Photo submission error:', error);
res.status(500).json({ error: 'Failed to submit photo' });
}
});
router.post('/:id/copy', auth_1.authenticate, async (req, res) => {
try {
const { id } = req.params;
const originalRoute = await index_1.prisma.route.findUnique({
where: { id: id },
include: {
game: true,
routeLegs: { orderBy: { sequenceNumber: 'asc' } }
}
});
if (!originalRoute) {
return res.status(404).json({ error: 'Route not found' });
}
if (originalRoute.game.gameMasterId !== req.user.id) {
return res.status(403).json({ error: 'Not authorized' });
}
const newRoute = await index_1.prisma.route.create({
data: {
gameId: originalRoute.gameId,
name: `${originalRoute.name} (Copy)`,
description: originalRoute.description,
color: originalRoute.color
}
});
for (const leg of originalRoute.routeLegs) {
await index_1.prisma.routeLeg.create({
data: {
routeId: newRoute.id,
sequenceNumber: leg.sequenceNumber,
description: leg.description,
conditionType: leg.conditionType,
conditionDetails: leg.conditionDetails,
locationLat: leg.locationLat,
locationLng: leg.locationLng,
timeLimit: leg.timeLimit
}
});
}
const fullRoute = await index_1.prisma.route.findUnique({
where: { id: newRoute.id },
include: {
routeLegs: { orderBy: { sequenceNumber: 'asc' } }
}
});
res.json(fullRoute);
}
catch (error) {
console.error('Copy route error:', error);
res.status(500).json({ error: 'Failed to copy route' });
}
});
exports.default = router;