feat(backend): initial setup for cms backend service
This commit is contained in:
122
backend/src/routes/publish.ts
Normal file
122
backend/src/routes/publish.ts
Normal file
@ -0,0 +1,122 @@
|
||||
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<typeof publishSchema>;
|
||||
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;
|
||||
Reference in New Issue
Block a user