mirror of
https://github.com/juherr/kill-the-news.git
synced 2026-06-21 06:13:48 +00:00
feat: reader-compat batch — JSON Feed, OPML export, conditional GET, dedup
Batch of four reader-facing improvements (TODO "Compat lecteurs + dedup"): - JSON Feed at /json/:feedId (feed lib .json1()); all formats cross-link - OPML export at /admin/opml (admin-protected; the registry lists every feed URL, so it must not be public) - Conditional GET on /rss + /atom: strong ETag + Last-Modified, 304 on If-None-Match/If-Modified-Since, validators shared via http-cache.ts - Duplicate-send dedup in ingestion: match by Message-ID, fall back to a SHA-256 of normalized subject+content; a duplicate is a no-op and bumps the new emails_deduplicated counter (status page + /api/v1/stats) 429 tests green, tsc clean, build dry-run OK. Docs (README/CLAUDE/TODO + landing cards) updated. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -68,6 +68,8 @@ export interface EmailMetadata {
|
||||
size?: number;
|
||||
attachmentIds?: string[]; // Downloadable attachments (shown to the user)
|
||||
inlineAttachmentIds?: string[]; // Inline images: hidden from lists, still cleaned up
|
||||
messageId?: string; // RFC 2822 Message-ID header (dedup primary key)
|
||||
dedupHash?: string; // SHA-256 hex of normalized subject+content (dedup fallback)
|
||||
}
|
||||
|
||||
// Feed list interface
|
||||
@@ -92,6 +94,7 @@ export interface Counters {
|
||||
// Subset of emails_rejected: non-feed mail forwarded to FALLBACK_FORWARD_ADDRESS
|
||||
// instead of dropped. Dropped count = emails_rejected − emails_forwarded.
|
||||
emails_forwarded: number;
|
||||
emails_deduplicated: number; // Duplicate deliveries silently skipped (not stored)
|
||||
unsubscribes_sent: number;
|
||||
last_email_at?: string; // ISO 8601
|
||||
last_feed_created_at?: string; // ISO 8601
|
||||
|
||||
Reference in New Issue
Block a user