- Add storage module with SQLite persistence via better-sqlite3 - Add deduplication module for feed item dedup - Add infrastructure directory for deployment config - Add .env.example for environment variables - Update dependencies: kysely, better-sqlite3, pg
55 lines
1.8 KiB
TypeScript
55 lines
1.8 KiB
TypeScript
/**
|
|
* Database schema migrations.
|
|
* Creates tables idempotently.
|
|
*/
|
|
|
|
import type { Kysely } from 'kysely';
|
|
import type { Database } from './database.js';
|
|
|
|
export async function migrate(db: Kysely<Database>): Promise<void> {
|
|
// Create feed_items table
|
|
await db.schema
|
|
.createTable('feed_items')
|
|
.ifNotExists()
|
|
.addColumn('id', 'varchar(64)', (col) => col.primaryKey())
|
|
.addColumn('source', 'varchar(2048)', (col) => col.notNull())
|
|
.addColumn('title', 'varchar(512)', (col) => col.notNull())
|
|
.addColumn('url', 'varchar(2048)', (col) => col.notNull())
|
|
.addColumn('published_at', 'varchar(32)', (col) => col.notNull())
|
|
.addColumn('content', 'text')
|
|
.addColumn('summary', 'text')
|
|
.addColumn('created_at', 'varchar(32)', (col) => col.notNull().defaultTo('CURRENT_TIMESTAMP'))
|
|
.execute();
|
|
|
|
// Create indexes for feed_items
|
|
await db.schema
|
|
.createIndex('idx_feed_items_source')
|
|
.ifNotExists()
|
|
.on('feed_items')
|
|
.column('source')
|
|
.execute();
|
|
|
|
await db.schema
|
|
.createIndex('idx_feed_items_published')
|
|
.ifNotExists()
|
|
.on('feed_items')
|
|
.column('published_at')
|
|
.execute();
|
|
|
|
// Create seen_ids table
|
|
await db.schema
|
|
.createTable('seen_ids')
|
|
.ifNotExists()
|
|
.addColumn('id', 'varchar(64)', (col) => col.primaryKey())
|
|
.addColumn('seen_at', 'varchar(32)', (col) => col.notNull().defaultTo('CURRENT_TIMESTAMP'))
|
|
.execute();
|
|
}
|
|
|
|
export async function reset(db: Kysely<Database>): Promise<void> {
|
|
// Drop tables (for testing)
|
|
await db.schema.dropTable('seen_ids').ifExists().execute();
|
|
await db.schema.dropIndex('idx_feed_items_published').ifExists().execute();
|
|
await db.schema.dropIndex('idx_feed_items_source').ifExists().execute();
|
|
await db.schema.dropTable('feed_items').ifExists().execute();
|
|
}
|