338 lines
12 KiB
JavaScript
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;
|