feat(blog): prune posts removed or renamed upstream

the blog repo is the source of truth for the full set of posts, but
upserts alone never delete: removing a file or changing a slug or
filename left the old row serving forever. each poll now reconciles —
after upserting the current tree, events under source='blog' whose id
is not in the parsed set are deleted via a new EventWriter::prune_events
port. nothing is lost: git still has every post, and restoring or
fixing a file re-ingests it on the next tip change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 22:56:54 +03:00
parent cd3dc2d82d
commit 37c44906bb
4 changed files with 33 additions and 1 deletions

View File

@@ -31,4 +31,8 @@ pub trait EventReader: Send + Sync {
pub trait EventWriter: Send + Sync {
async fn upsert_events(&self, events: &[Event]) -> Result<usize, StoreError>;
async fn upsert_repo_languages(&self, languages: &[RepoLanguage]) -> Result<usize, StoreError>;
/// Delete events of `source` whose id is not in `keep_ids`. For sources
/// whose upstream is authoritative for the full set (e.g. the blog repo),
/// this reconciles deletes and renames that upserts alone never would.
async fn prune_events(&self, source: moments_entities::Source, keep_ids: &[String]) -> Result<usize, StoreError>;
}