mirror of
https://github.com/profullstack/logicsrc.git
synced 2026-09-10 19:26:00 +00:00
feat(web): blog-post ingestion webhook + /blog, dynamic RSS & sitemap
Add an autoblog webhook receiver and a Supabase-backed blog to logicsrc-web (the app had no Supabase usage before). - Migration: blog_posts table (RLS: public reads published, service-role writes). Applied to the linked project. - POST /api/webhooks/blog: verifies the Standard Webhooks signature against BLOG_WEBHOOK_SECRET via @profullstack/autoblog verifyAndParse (no admin user — shared secret only) and upserts the post by slug. - /blog index + /blog/[slug] render published posts from the table. - /blog/rss.xml and /sitemap.xml are now dynamic, generated from the table; removed the static public/sitemap.xml and public/blog/rss.xml. - BLOG_WEBHOOK_SECRET added to .env.example. Verified end-to-end: a signed sample post delivered 200 and appeared in the index, post page, RSS, and sitemap; build + typecheck pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
ade606c157
commit
cf99e93c53
13 changed files with 549 additions and 82 deletions
34
apps/logicsrc-web/src/lib/supabase.ts
Normal file
34
apps/logicsrc-web/src/lib/supabase.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import { createClient, type SupabaseClient } from "@supabase/supabase-js";
|
||||
|
||||
const url = process.env.SUPABASE_URL;
|
||||
const anonKey = process.env.SUPABASE_ANON_KEY ?? process.env.SUPABASE_PUBLISHABLE_KEY;
|
||||
const serviceKey = process.env.SUPABASE_SECRET_KEY;
|
||||
|
||||
// Public read client (anon key) — used by /blog, /blog/[slug], the RSS feed,
|
||||
// and the sitemap. RLS limits it to published posts.
|
||||
export function publicClient(): SupabaseClient {
|
||||
if (!url || !anonKey) {
|
||||
throw new Error("SUPABASE_URL and SUPABASE_ANON_KEY (or SUPABASE_PUBLISHABLE_KEY) are required");
|
||||
}
|
||||
return createClient(url, anonKey, { auth: { persistSession: false } });
|
||||
}
|
||||
|
||||
// Privileged client (service-role key) — used by the blog webhook to upsert
|
||||
// posts. Bypasses RLS, so keep it server-only.
|
||||
export function serviceClient(): SupabaseClient {
|
||||
if (!url || !serviceKey) {
|
||||
throw new Error("SUPABASE_URL and SUPABASE_SECRET_KEY are required");
|
||||
}
|
||||
return createClient(url, serviceKey, { auth: { persistSession: false } });
|
||||
}
|
||||
|
||||
export type BlogPost = {
|
||||
slug: string;
|
||||
title: string;
|
||||
excerpt: string | null;
|
||||
html: string;
|
||||
tags: string[];
|
||||
featured_image: { url?: string } | null;
|
||||
published_at: string;
|
||||
updated_at: string;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue