feat: complete v0.3 reading and discovery experience

This commit is contained in:
2026-07-19 03:16:18 +08:00
parent 5b5129fad5
commit 9ab09159e3
23 changed files with 1829 additions and 26 deletions
+19
View File
@@ -54,8 +54,26 @@ CREATE TABLE IF NOT EXISTS source_members (
role TEXT NOT NULL DEFAULT 'member', created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(source_id, user_id)
);
CREATE TABLE IF NOT EXISTS bookmarks (
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
post_id INTEGER NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
kind TEXT NOT NULL DEFAULT 'saved', created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(user_id, post_id)
);
CREATE TABLE IF NOT EXISTS reading_history (
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
post_id INTEGER NOT NULL REFERENCES posts(id) ON DELETE CASCADE,
last_read_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(user_id, post_id)
);
CREATE TABLE IF NOT EXISTS notifications (
id INTEGER PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
actor_id INTEGER REFERENCES users(id) ON DELETE SET NULL, post_id INTEGER REFERENCES posts(id) ON DELETE CASCADE,
type TEXT NOT NULL, message TEXT NOT NULL, read_at TEXT, created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS posts_public_idx ON posts(visibility, hidden, created_at DESC);
CREATE INDEX IF NOT EXISTS sync_jobs_idx ON sync_jobs(status, run_after);
CREATE INDEX IF NOT EXISTS notifications_user_idx ON notifications(user_id, read_at, created_at DESC);
CREATE UNIQUE INDEX IF NOT EXISTS source_remote_identity_unique ON sources(base_url, remote_user) WHERE remote_user IS NOT NULL;
CREATE TABLE IF NOT EXISTS schema_migrations (
version INTEGER PRIMARY KEY, applied_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
@@ -77,6 +95,7 @@ applyColumnMigration(4, "sources", "disabled_at", "ALTER TABLE sources ADD COLUM
applyColumnMigration(5, "sync_jobs", "trigger", "ALTER TABLE sync_jobs ADD COLUMN trigger TEXT NOT NULL DEFAULT 'manual'");
applyColumnMigration(6, "sync_jobs", "started_at", "ALTER TABLE sync_jobs ADD COLUMN started_at TEXT");
applyColumnMigration(7, "sync_jobs", "finished_at", "ALTER TABLE sync_jobs ADD COLUMN finished_at TEXT");
db.prepare("INSERT OR IGNORE INTO schema_migrations(version) VALUES(8)").run();
const admin = process.env.ADMIN_USERNAME;
const adminPassword = process.env.ADMIN_PASSWORD;