feat(blog): add markdown blog sourced from a gitea repo

posts are markdown files with yaml frontmatter (title, slug, date;
optional draft/public) in the grenade/blog repo. the worker's new
BlogSource polls the repo — one branch-tip request when nothing
changed — and upserts posts into events with source='blog' and
occurred_at from the frontmatter date, so imported posts keep their
original publish dates and backfill the contribution graph.

- new /v1/blog and /v1/blog/{slug} endpoints over the existing
  EventReader port; drafts stay hidden via the public gate
- new /blog and /blog/:slug routes, nav link, activity-feed entry
  with post icon and filter toggle; relative image srcs resolve to
  gitea raw urls
- shared Markdown component extracted from ProjectPage
- vite proxy target overridable via API_PROXY_TARGET for local dev

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 22:44:56 +03:00
parent 2821548e6e
commit 88ce993df3
23 changed files with 846 additions and 61 deletions

View File

@@ -19,6 +19,7 @@ thiserror = "2"
# core / data
sqlx = { version = "0.8", default-features = false, features = ["postgres", "runtime-tokio-rustls", "macros", "migrate", "chrono", "json"] }
async-trait = "0.1"
serde_yaml_ng = "0.10"
# binaries
tokio = { version = "1", features = ["rt-multi-thread", "macros", "signal", "time"] }