Skip to content

Commit b46a962

Browse files
committed
feat(feeds): add email feed system with AI-powered content curation
Users can create feed email addresses (feed-<hash>@thestack.cl), subscribe them to external newsletters, and an AI agent (Gemini 2.5 Flash) processes incoming emails to publish relevant tech content. Posts are published under the user's name with a "via feed" badge. - DB: feeds, feed_logs tables + source/feedId/status columns on posts - API: CRUD feeds, pending posts approval/rejection, admin feed management - Email: Cloudflare Email Routing handler with postal-mime parsing - Agent: LangChain agent with fetch_url/publish_post/skip tools - Frontend: feeds management in settings, pending posts page, admin feeds tab - Rate limits: 3 feeds per user, 1 email per 3 days per feed
1 parent 77b49c0 commit b46a962

17 files changed

Lines changed: 5214 additions & 1471 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
CREATE TABLE feeds (
2+
id TEXT PRIMARY KEY,
3+
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
4+
name TEXT NOT NULL,
5+
email_hash TEXT NOT NULL UNIQUE,
6+
auto_publish INTEGER NOT NULL DEFAULT 0,
7+
is_active INTEGER NOT NULL DEFAULT 1,
8+
last_processed_at INTEGER,
9+
created_at INTEGER NOT NULL,
10+
updated_at INTEGER NOT NULL
11+
);
12+
13+
CREATE INDEX idx_feeds_user ON feeds(user_id);
14+
CREATE UNIQUE INDEX idx_feeds_email_hash ON feeds(email_hash);
15+
16+
CREATE TABLE feed_logs (
17+
id TEXT PRIMARY KEY,
18+
feed_id TEXT NOT NULL REFERENCES feeds(id) ON DELETE CASCADE,
19+
email_subject TEXT,
20+
email_from TEXT,
21+
links_found INTEGER DEFAULT 0,
22+
links_published INTEGER DEFAULT 0,
23+
links_skipped INTEGER DEFAULT 0,
24+
status TEXT NOT NULL DEFAULT 'processing',
25+
error TEXT,
26+
created_at INTEGER NOT NULL
27+
);
28+
29+
CREATE INDEX idx_feed_logs_feed ON feed_logs(feed_id);
30+
CREATE INDEX idx_feed_logs_created_at ON feed_logs(created_at);
31+
32+
ALTER TABLE posts ADD COLUMN source TEXT;
33+
ALTER TABLE posts ADD COLUMN feed_id TEXT REFERENCES feeds(id) ON DELETE SET NULL;
34+
ALTER TABLE posts ADD COLUMN status TEXT NOT NULL DEFAULT 'published';

0 commit comments

Comments
 (0)