import { FastifyPluginAsync } from 'fastify'; import { z } from 'zod'; import { db } from '../config/database.js'; import { contentSections } from '../db/schema.js'; import { eq } from 'drizzle-orm'; // Fastify JSON schema for content section body const contentBodyJsonSchema = { type: 'object', required: ['contentJson'], properties: { contentJson: {}, // allow any JSON }, } as const; const contentRoute: FastifyPluginAsync = async (fastify) => { // Get content section fastify.get('/content/:section', { preHandler: [fastify.authenticate], }, async (request, reply) => { const { section } = request.params as { section: string }; const [content] = await db .select() .from(contentSections) .where(eq(contentSections.sectionName, section)) .limit(1); if (!content) { return reply.code(404).send({ error: 'Content section not found' }); } return { section: content.sectionName, content: content.contentJson, updatedAt: content.updatedAt, }; }); // Update content section fastify.put('/content/:section', { schema: { body: contentBodyJsonSchema, }, preHandler: [fastify.authenticate], }, async (request, reply) => { const { section } = request.params as { section: string }; const { contentJson } = request.body as any; // Check if section exists const [existing] = await db .select() .from(contentSections) .where(eq(contentSections.sectionName, section)) .limit(1); let result; if (existing) { // Update existing [result] = await db .update(contentSections) .set({ contentJson, updatedAt: new Date(), }) .where(eq(contentSections.sectionName, section)) .returning(); } else { // Create new [result] = await db .insert(contentSections) .values({ sectionName: section, contentJson, }) .returning(); } return { section: result.sectionName, content: result.contentJson, updatedAt: result.updatedAt, }; }); // List all content sections fastify.get('/content', { preHandler: [fastify.authenticate], }, async (request, reply) => { const sections = await db.select().from(contentSections); return { sections: (sections as any[]).map((s: any) => ({ section: s.sectionName, content: s.contentJson, updatedAt: s.updatedAt, })), }; }); }; export default contentRoute;