import { FastifyPluginAsync } from 'fastify'; import { z } from 'zod'; import { GitService } from '../services/git.service.js'; import { FileGeneratorService } from '../services/file-generator.service.js'; import { db } from '../config/database.js'; import { events, galleryImages, contentSections, publishHistory } from '../db/schema.js'; import { eq } from 'drizzle-orm'; const publishSchema = z.object({ commitMessage: z.string().min(1).max(200), }); const publishRoute: FastifyPluginAsync = async (fastify) => { fastify.post('/publish', { schema: { body: publishSchema, }, preHandler: [fastify.authenticate], }, async (request, reply) => { try { const { commitMessage } = request.body as z.infer; const userId = request.user.id; fastify.log.info('Starting publish process...'); // Initialize git service const gitService = new GitService(); await gitService.initialize(); fastify.log.info('Git repository initialized'); // Fetch all content from database const eventsData = await db .select() .from(events) .where(eq(events.isPublished, true)) .orderBy(events.displayOrder); const galleryData = await db .select() .from(galleryImages) .where(eq(galleryImages.isPublished, true)) .orderBy(galleryImages.displayOrder); const sectionsData = await db.select().from(contentSections); const sectionsMap = new Map( sectionsData.map(s => [s.sectionName, s.contentJson as any]) ); fastify.log.info(`Fetched ${eventsData.length} events, ${galleryData.length} images, ${sectionsData.length} sections`); // Generate and write files const fileGenerator = new FileGeneratorService(); await fileGenerator.writeFiles( gitService.getWorkspacePath(''), eventsData.map(e => ({ title: e.title, date: e.date, description: e.description, imageUrl: e.imageUrl, })), galleryData.map(g => ({ imageUrl: g.imageUrl, altText: g.altText, })), sectionsMap ); fastify.log.info('Files generated successfully'); // Commit and push const commitHash = await gitService.commitAndPush(commitMessage); fastify.log.info(`Changes committed: ${commitHash}`); // Record in history await db.insert(publishHistory).values({ userId, commitHash, commitMessage, }); return { success: true, commitHash, message: 'Changes published successfully', }; } catch (error) { fastify.log.error('Publish error:', error); // Attempt to reset git state on error try { const gitService = new GitService(); await gitService.reset(); } catch (resetError) { fastify.log.error('Failed to reset git state:', resetError); } return reply.code(500).send({ success: false, error: 'Failed to publish changes', details: error instanceof Error ? error.message : 'Unknown error', }); } }); // Get publish history fastify.get('/publish/history', { preHandler: [fastify.authenticate], }, async (request, reply) => { const history = await db .select() .from(publishHistory) .orderBy(publishHistory.publishedAt) .limit(20); return { history }; }); }; export default publishRoute;