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>
23 lines
660 B
Rust
23 lines
660 B
Rust
//! Reshape raw stored events into the presentation shape consumed by the UI.
|
|
//!
|
|
//! Storage holds the upstream payload verbatim; transformation lives here so
|
|
//! the rendering can evolve without re-fetching upstream data.
|
|
|
|
use moments_entities::{Event, Source, TimelineItem};
|
|
|
|
pub mod blog;
|
|
mod bugzilla;
|
|
mod gitea;
|
|
mod github;
|
|
mod hg;
|
|
|
|
pub fn reshape(event: &Event) -> TimelineItem {
|
|
match event.source {
|
|
Source::Github => github::reshape(event),
|
|
Source::Gitea => gitea::reshape(event),
|
|
Source::Hg => hg::reshape(event),
|
|
Source::Bugzilla => bugzilla::reshape(event),
|
|
Source::Blog => blog::reshape(event),
|
|
}
|
|
}
|