feat(backend): initial setup for cms backend service
This commit is contained in:
123
backend/src/routes/events.ts
Normal file
123
backend/src/routes/events.ts
Normal file
@ -0,0 +1,123 @@
|
||||
import { FastifyPluginAsync } from 'fastify';
|
||||
import { z } from 'zod';
|
||||
import { db } from '../config/database.js';
|
||||
import { events } from '../db/schema.js';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
const eventSchema = z.object({
|
||||
title: z.string().min(1).max(200),
|
||||
date: z.string().min(1).max(100),
|
||||
description: z.string().min(1),
|
||||
imageUrl: z.string().url(),
|
||||
displayOrder: z.number().int().min(0),
|
||||
isPublished: z.boolean().optional().default(true),
|
||||
});
|
||||
|
||||
const eventsRoute: FastifyPluginAsync = async (fastify) => {
|
||||
|
||||
// List all events
|
||||
fastify.get('/events', {
|
||||
preHandler: [fastify.authenticate],
|
||||
}, async (request, reply) => {
|
||||
const allEvents = await db.select().from(events).orderBy(events.displayOrder);
|
||||
return { events: allEvents };
|
||||
});
|
||||
|
||||
// Get single event
|
||||
fastify.get('/events/:id', {
|
||||
preHandler: [fastify.authenticate],
|
||||
}, async (request, reply) => {
|
||||
const { id } = request.params as { id: string };
|
||||
const event = await db.select().from(events).where(eq(events.id, id)).limit(1);
|
||||
|
||||
if (event.length === 0) {
|
||||
return reply.code(404).send({ error: 'Event not found' });
|
||||
}
|
||||
|
||||
return { event: event[0] };
|
||||
});
|
||||
|
||||
// Create event
|
||||
fastify.post('/events', {
|
||||
schema: {
|
||||
body: eventSchema,
|
||||
},
|
||||
preHandler: [fastify.authenticate],
|
||||
}, async (request, reply) => {
|
||||
const data = request.body as z.infer<typeof eventSchema>;
|
||||
|
||||
const [newEvent] = await db.insert(events).values(data).returning();
|
||||
|
||||
return reply.code(201).send({ event: newEvent });
|
||||
});
|
||||
|
||||
// Update event
|
||||
fastify.put('/events/:id', {
|
||||
schema: {
|
||||
body: eventSchema,
|
||||
},
|
||||
preHandler: [fastify.authenticate],
|
||||
}, async (request, reply) => {
|
||||
const { id } = request.params as { id: string };
|
||||
const data = request.body as z.infer<typeof eventSchema>;
|
||||
|
||||
const [updated] = await db
|
||||
.update(events)
|
||||
.set({ ...data, updatedAt: new Date() })
|
||||
.where(eq(events.id, id))
|
||||
.returning();
|
||||
|
||||
if (!updated) {
|
||||
return reply.code(404).send({ error: 'Event not found' });
|
||||
}
|
||||
|
||||
return { event: updated };
|
||||
});
|
||||
|
||||
// Delete event
|
||||
fastify.delete('/events/:id', {
|
||||
preHandler: [fastify.authenticate],
|
||||
}, async (request, reply) => {
|
||||
const { id } = request.params as { id: string };
|
||||
|
||||
const [deleted] = await db
|
||||
.delete(events)
|
||||
.where(eq(events.id, id))
|
||||
.returning();
|
||||
|
||||
if (!deleted) {
|
||||
return reply.code(404).send({ error: 'Event not found' });
|
||||
}
|
||||
|
||||
return { message: 'Event deleted successfully' };
|
||||
});
|
||||
|
||||
// Reorder events
|
||||
fastify.put('/events/reorder', {
|
||||
schema: {
|
||||
body: z.object({
|
||||
orders: z.array(z.object({
|
||||
id: z.string().uuid(),
|
||||
displayOrder: z.number().int().min(0),
|
||||
})),
|
||||
}),
|
||||
},
|
||||
preHandler: [fastify.authenticate],
|
||||
}, async (request, reply) => {
|
||||
const { orders } = request.body as { orders: Array<{ id: string; displayOrder: number }> };
|
||||
|
||||
// Update all in transaction
|
||||
await db.transaction(async (tx) => {
|
||||
for (const { id, displayOrder } of orders) {
|
||||
await tx
|
||||
.update(events)
|
||||
.set({ displayOrder })
|
||||
.where(eq(events.id, id));
|
||||
}
|
||||
});
|
||||
|
||||
return { message: 'Events reordered successfully' };
|
||||
});
|
||||
};
|
||||
|
||||
export default eventsRoute;
|
||||
Reference in New Issue
Block a user