Files
Admin_dash/lib/db.ts
Shivam Patel 4ee365cfc0 Fix RSS time filters and add draggable grid layout
Normalize pub_date to ISO 8601 on insert so SQLite datetime comparisons
work correctly. Migrate existing RFC 2822 dates. Change 1h filter to 12h.
Add react-grid-layout with persistent drag/resize and reset button.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 17:51:06 -05:00

103 lines
2.8 KiB
TypeScript

import sqlite3 from 'sqlite3';
import { open, Database } from 'sqlite';
let db: Database | null = null;
export async function getDb() {
if (db) return db;
// Enable verbose mode for debugging
sqlite3.verbose();
const dbPath = process.env.DB_PATH || './dashboard.db';
db = await open({
filename: dbPath,
driver: sqlite3.Database
});
await db.exec(`
CREATE TABLE IF NOT EXISTS uptime_logs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
service_name TEXT NOT NULL,
url TEXT NOT NULL,
status TEXT NOT NULL,
latency INTEGER,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS visitors (
id INTEGER PRIMARY KEY AUTOINCREMENT,
ip_hash TEXT,
city TEXT,
country TEXT,
lat REAL,
lon REAL,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS monitored_services (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
url TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_uptime_logs_service_timestamp
ON uptime_logs(service_name, timestamp);
CREATE TABLE IF NOT EXISTS rss_feeds (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
url TEXT NOT NULL UNIQUE,
last_fetched DATETIME,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS rss_items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
feed_id INTEGER NOT NULL,
title TEXT NOT NULL,
link TEXT NOT NULL UNIQUE,
pub_date DATETIME,
creator TEXT,
snippet TEXT,
read INTEGER DEFAULT 0,
bookmarked INTEGER DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_rss_items_feed ON rss_items(feed_id);
CREATE INDEX IF NOT EXISTS idx_rss_items_pubdate ON rss_items(pub_date DESC);
`);
// Seed default HN feed if rss_feeds is empty
const feedCount = await db.get('SELECT COUNT(*) as cnt FROM rss_feeds');
if (feedCount?.cnt === 0) {
await db.run(
'INSERT INTO rss_feeds (name, url) VALUES (?, ?)',
'Hacker News', 'https://news.ycombinator.com/rss'
);
}
// Migrate existing non-ISO pub_date values to ISO 8601
try {
const rows = await db.all(
"SELECT id, pub_date FROM rss_items WHERE pub_date IS NOT NULL AND pub_date NOT LIKE '____-__-__T%'"
);
for (const row of rows) {
const d = new Date(row.pub_date);
if (!isNaN(d.getTime())) {
await db.run('UPDATE rss_items SET pub_date = ? WHERE id = ?', d.toISOString(), row.id);
}
}
if (rows.length > 0) {
console.log(`Migrated ${rows.length} rss_items pub_date values to ISO 8601`);
}
} catch (e) {
// Table may not have data yet, ignore
}
return db;
}