UserCampusScope relation and audit action; scopeEvent/scopeList/unscopedOnly/ campusIndependent/scopeBroadcast markers; tests/campusScopeRoutes.test.js (still failing: events, payments, registrations, scan locks, tickets left). Can't delete a campus that has scoped staff. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
189 lines
4.8 KiB
JavaScript
189 lines
4.8 KiB
JavaScript
const prisma = require('../config/db');
|
|
const { v4: uuidv4 } = require('uuid');
|
|
|
|
//
|
|
// @desc Get sections (optionally by event)
|
|
// @route GET /api/sections?eventId=xxx
|
|
// @access Private/Staff
|
|
//
|
|
const getSections = async (req, res) => {
|
|
try {
|
|
const { eventId } = req.query;
|
|
|
|
const { withScope, listWhere } = require('../utils/campusScope');
|
|
const where = withScope(eventId && eventId !== 'all' ? { eventId } : {}, await listWhere(req, 'event'));
|
|
|
|
const sections = await prisma.section.findMany({
|
|
where,
|
|
include: {
|
|
allowedOptions: {
|
|
include: {
|
|
eventOption: true
|
|
}
|
|
},
|
|
event: {
|
|
select: { id: true, title: true }
|
|
}
|
|
},
|
|
orderBy: { name: 'asc' }
|
|
});
|
|
|
|
res.json(sections);
|
|
} catch (error) {
|
|
res.status(400).json({ message: error.message });
|
|
}
|
|
};
|
|
|
|
//
|
|
// @desc Create section
|
|
// @route POST /api/sections
|
|
// @access Private/Admin/Supervisor
|
|
//
|
|
const createSection = async (req, res) => {
|
|
try {
|
|
const { eventId, name, allowedOptionIds } = req.body;
|
|
|
|
if (!eventId || !name) {
|
|
res.status(400);
|
|
throw new Error('Event and section name are required');
|
|
}
|
|
|
|
const event = await prisma.event.findUnique({
|
|
where: { id: eventId }
|
|
});
|
|
|
|
if (!event) {
|
|
res.status(404);
|
|
throw new Error('Event not found');
|
|
}
|
|
|
|
const section = await prisma.section.create({
|
|
data: {
|
|
id: uuidv4(),
|
|
eventId,
|
|
name,
|
|
updatedAt: new Date()
|
|
}
|
|
});
|
|
|
|
// Attach allowed options if provided
|
|
if (Array.isArray(allowedOptionIds) && allowedOptionIds.length > 0) {
|
|
await prisma.sectionOption.createMany({
|
|
data: allowedOptionIds.map(optionId => ({
|
|
id: uuidv4(),
|
|
sectionId: section.id,
|
|
eventOptionId: optionId
|
|
})),
|
|
skipDuplicates: true
|
|
});
|
|
}
|
|
|
|
const fullSection = await prisma.section.findUnique({
|
|
where: { id: section.id },
|
|
include: {
|
|
allowedOptions: {
|
|
include: { eventOption: true }
|
|
}
|
|
}
|
|
});
|
|
|
|
res.status(201).json(fullSection);
|
|
|
|
} catch (error) {
|
|
res.status(400).json({ message: error.message });
|
|
}
|
|
};
|
|
|
|
//
|
|
// @desc Update section
|
|
// @route PUT /api/sections/:id
|
|
// @access Private/Admin/Supervisor
|
|
//
|
|
const updateSection = async (req, res) => {
|
|
try {
|
|
const { name, allowedOptionIds } = req.body;
|
|
|
|
const section = await prisma.section.findUnique({
|
|
where: { id: req.params.id }
|
|
});
|
|
|
|
if (!section) {
|
|
res.status(404);
|
|
throw new Error('Section not found');
|
|
}
|
|
|
|
const updatedSection = await prisma.section.update({
|
|
where: { id: req.params.id },
|
|
data: {
|
|
name: name || section.name,
|
|
updatedAt: new Date()
|
|
}
|
|
});
|
|
|
|
// If allowed options supplied → reset them
|
|
if (Array.isArray(allowedOptionIds)) {
|
|
|
|
await prisma.sectionOption.deleteMany({
|
|
where: { sectionId: section.id }
|
|
});
|
|
|
|
if (allowedOptionIds.length > 0) {
|
|
await prisma.sectionOption.createMany({
|
|
data: allowedOptionIds.map(optionId => ({
|
|
id: uuidv4(),
|
|
sectionId: section.id,
|
|
eventOptionId: optionId
|
|
}))
|
|
});
|
|
}
|
|
}
|
|
|
|
const fullSection = await prisma.section.findUnique({
|
|
where: { id: section.id },
|
|
include: {
|
|
allowedOptions: {
|
|
include: { eventOption: true }
|
|
}
|
|
}
|
|
});
|
|
|
|
res.json(fullSection);
|
|
|
|
} catch (error) {
|
|
res.status(400).json({ message: error.message });
|
|
}
|
|
};
|
|
|
|
//
|
|
// @desc Delete section
|
|
// @route DELETE /api/sections/:id
|
|
// @access Private/Admin
|
|
//
|
|
const deleteSection = async (req, res) => {
|
|
try {
|
|
const section = await prisma.section.findUnique({
|
|
where: { id: req.params.id }
|
|
});
|
|
|
|
if (!section) {
|
|
res.status(404);
|
|
throw new Error('Section not found');
|
|
}
|
|
|
|
await prisma.section.delete({
|
|
where: { id: section.id }
|
|
});
|
|
|
|
res.json({ message: 'Section deleted' });
|
|
|
|
} catch (error) {
|
|
res.status(400).json({ message: error.message });
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
getSections,
|
|
createSection,
|
|
updateSection,
|
|
deleteSection
|
|
}; |