cms: headless CMS vor Hugo (Supabase + Node-API + React-Admin)

All-in-One docker-compose-Stack (Muster von RAPPORT-SERVER gespiegelt):
db/auth/rest/kong + cms-Service (Node-API + Hugo-Binary 0.161.1 + Admin-SPA).

- DB-backed: posts-Tabelle kanonisch, MD ist generiertes Artefakt
- echte Hugo-Vorschau via draft:true + --buildDrafts → /_preview
- Publish: DB → content/library/<section>/<slug>.md → hugo build → live
- Bild-Upload nach static/images/, Supabase-Auth schützt /api/*
- Proxmox-LXC-Script: legt Container an, generiert Secrets, startet Stack

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-05-31 00:21:04 +02:00
parent 7a5be9250a
commit 60e5ef6844
31 changed files with 3616 additions and 0 deletions
+27
View File
@@ -0,0 +1,27 @@
import { Hono } from 'hono';
import { supabase } from '../supabase.js';
import { writePostFile } from '../content.js';
import { hugoBuild } from '../hugo.js';
// Echte Hugo-Vorschau: Post als draft:true in content/ schreiben und mit
// --buildDrafts nach preview/ bauen. Der Live-Build (public/) lässt den
// Draft weiterhin aus.
const preview = new Hono();
preview.post('/:id', async (c) => {
const id = c.req.param('id');
const { data: post, error } = await supabase
.from('posts').select('*').eq('id', id).single();
if (error || !post) return c.json({ error: 'Post nicht gefunden' }, 404);
try {
await writePostFile(post, { draft: true });
const build = await hugoBuild({ dest: 'preview', drafts: true });
const url = `/_preview/library/${post.section}/${post.slug}/`;
return c.json({ ok: true, url, hugo: build.stdout });
} catch (e) {
return c.json({ error: String(e.message || e) }, 500);
}
});
export default preview;