Add public endpoints and refactor deployments
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
- Implemented public `/gallery/public` and `/events/public` endpoints for fetching published data without authentication. - Updated persistent volume configuration for Fly.io across backend and static file serving. - Adjusted frontend to dynamically fetch events and gallery images from backend API. - Refined Woodpecker pipeline for clearer separation of backend and frontend deployments.
This commit is contained in:
@ -1,3 +1,9 @@
|
||||
when:
|
||||
branch:
|
||||
- main
|
||||
event:
|
||||
- push
|
||||
|
||||
steps:
|
||||
deploy_frontend:
|
||||
image: node:20
|
||||
@ -9,7 +15,7 @@ steps:
|
||||
- export PATH="$HOME/.fly/bin:$PATH"
|
||||
- flyctl deploy --config fly.toml --app gallus-pub --remote-only
|
||||
|
||||
build_and_deploy_backend:
|
||||
deploy_backend:
|
||||
image: node:20
|
||||
environment:
|
||||
FLY_API_TOKEN:
|
||||
@ -19,9 +25,3 @@ steps:
|
||||
- curl -L https://fly.io/install.sh | sh
|
||||
- export PATH="$HOME/.fly/bin:$PATH"
|
||||
- flyctl deploy --config fly.toml --app gallus-cms-backend --remote-only
|
||||
|
||||
when:
|
||||
branch:
|
||||
- main
|
||||
event:
|
||||
- push
|
||||
|
||||
@ -60,10 +60,12 @@ fastify.register(multipart, {
|
||||
},
|
||||
});
|
||||
|
||||
// Serve static files (uploaded images, etc.)
|
||||
// Serve static files (uploaded images, etc.) from persistent volume
|
||||
const dataDir = env.GIT_WORKSPACE_DIR || path.join(process.cwd(), 'data');
|
||||
fastify.register(fastifyStatic, {
|
||||
root: path.join(process.cwd(), 'public'),
|
||||
root: dataDir,
|
||||
prefix: '/static/',
|
||||
decorateReply: false
|
||||
});
|
||||
|
||||
// Decorate fastify with authenticate method
|
||||
|
||||
@ -36,7 +36,15 @@ const reorderBodyJsonSchema = {
|
||||
} as const;
|
||||
|
||||
const eventsRoute: FastifyPluginAsync = async (fastify) => {
|
||||
// List all events (by displayOrder)
|
||||
// PUBLIC: List published events (no auth required)
|
||||
fastify.get('/events/public', async () => {
|
||||
const all = await db.select().from(events)
|
||||
.where(eq(events.isPublished, true))
|
||||
.orderBy(events.displayOrder);
|
||||
return { events: all };
|
||||
});
|
||||
|
||||
// List all events (by displayOrder) - admin only
|
||||
fastify.get('/events', { preHandler: [fastify.authenticate] }, async () => {
|
||||
const all = await db.select().from(events).orderBy(events.displayOrder);
|
||||
return { events: all };
|
||||
|
||||
@ -21,7 +21,15 @@ const galleryBodyJsonSchema = {
|
||||
|
||||
const galleryRoute: FastifyPluginAsync = async (fastify) => {
|
||||
|
||||
// List all gallery images
|
||||
// PUBLIC: List published gallery images (no auth required)
|
||||
fastify.get('/gallery/public', async () => {
|
||||
const images = await db.select().from(galleryImages)
|
||||
.where(eq(galleryImages.isPublished, true))
|
||||
.orderBy(galleryImages.displayOrder);
|
||||
return { images };
|
||||
});
|
||||
|
||||
// List all gallery images - admin only
|
||||
fastify.get('/gallery', {
|
||||
preHandler: [fastify.authenticate],
|
||||
}, async (request, reply) => {
|
||||
@ -77,9 +85,9 @@ const galleryRoute: FastifyPluginAsync = async (fastify) => {
|
||||
return reply.code(400).send({ error: 'Only image uploads are allowed' });
|
||||
}
|
||||
|
||||
// Prepare directories
|
||||
const publicRoot = path.join(process.cwd(), 'public');
|
||||
const uploadDir = path.join(publicRoot, 'images', 'gallery');
|
||||
// Prepare directories - use persistent volume for Fly.io
|
||||
const dataDir = process.env.GIT_WORKSPACE_DIR || path.join(process.cwd(), 'data');
|
||||
const uploadDir = path.join(dataDir, 'images', 'gallery');
|
||||
if (!fs.existsSync(uploadDir)) fs.mkdirSync(uploadDir, { recursive: true });
|
||||
|
||||
// Read uploaded stream into buffer
|
||||
|
||||
@ -8,20 +8,39 @@ import ImageCarousel from "../components/ImageCarousel.astro";
|
||||
import Contact from "../components/Contact.astro";
|
||||
import About from "../components/About.astro";
|
||||
|
||||
const events = [
|
||||
{
|
||||
image: "/static/images/gallery/miyma9zc-8he1di.webp",
|
||||
title: "Test",
|
||||
date: "2025-12-10",
|
||||
description: `
|
||||
Das ist ein test event
|
||||
`,
|
||||
}
|
||||
];
|
||||
const API_BASE = 'https://cms.gallus-pub.ch';
|
||||
|
||||
const images = [
|
||||
{ src: "/static/images/gallery/miyma9zc-8he1di.webp", alt: "Schwarzes bild" }
|
||||
];
|
||||
// Fetch events from backend API
|
||||
let events = [];
|
||||
try {
|
||||
const eventsResponse = await fetch(`${API_BASE}/api/events/public`);
|
||||
if (eventsResponse.ok) {
|
||||
const eventsData = await eventsResponse.json();
|
||||
events = (eventsData.events || []).map((ev: any) => ({
|
||||
image: `${API_BASE}${ev.imageUrl}`,
|
||||
title: ev.title,
|
||||
date: ev.date,
|
||||
description: ev.description
|
||||
}));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch events:', error);
|
||||
}
|
||||
|
||||
// Fetch gallery images from backend API
|
||||
let images = [];
|
||||
try {
|
||||
const galleryResponse = await fetch(`${API_BASE}/api/gallery/public`);
|
||||
if (galleryResponse.ok) {
|
||||
const galleryData = await galleryResponse.json();
|
||||
images = (galleryData.images || []).map((img: any) => ({
|
||||
src: `${API_BASE}${img.imageUrl}`,
|
||||
alt: img.altText
|
||||
}));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch gallery:', error);
|
||||
}
|
||||
---
|
||||
|
||||
<Layout>
|
||||
|
||||
Reference in New Issue
Block a user