feat: implement SQLite persistent storage for analysis results

- Implemented database initialization and connection management in `database.ts` using Bun's SQLite.
- Created `runs` and `results` tables to track historical analysis metadata and detailed product performance.
- Updated `writer.ts` to persist analysis results to the database within a transaction, replacing the previous CSV output logic.
- Updated README and `.gitignore` to reflect the new persistent storage capability.
This commit is contained in:
Victor Noguera
2026-04-12 23:41:40 -04:00
parent 0162e54007
commit 8ffbd48c46
5 changed files with 223 additions and 25 deletions

80
src/database.ts Normal file
View File

@@ -0,0 +1,80 @@
import { Database } from "bun:sqlite";
let db: Database | null = null;
export function getDb(dbPath: string): Database {
if (!db) {
db = new Database(dbPath);
db.run("PRAGMA journal_mode = WAL;"); // Enable WAL mode for better performance
}
return db;
}
export function closeDb(): void {
if (db) {
db.close();
db = null;
}
}
export function initDb(dbPath: string): void {
const database = getDb(dbPath);
database.run(`
CREATE TABLE IF NOT EXISTS runs (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp TEXT NOT NULL,
input_file TEXT NOT NULL,
output_file TEXT,
total_products INTEGER,
fba_count INTEGER,
fbm_count INTEGER,
skip_count INTEGER
);
`);
database.run(`
CREATE TABLE IF NOT EXISTS results (
id INTEGER PRIMARY KEY AUTOINCREMENT,
run_id INTEGER NOT NULL,
asin TEXT NOT NULL,
product_name TEXT,
brand TEXT,
category TEXT,
unit_cost REAL,
current_price REAL,
avg_price_90d REAL,
avg_price_90d_sheet REAL,
selling_price_sheet REAL,
sales_rank INTEGER,
rank_avg_90d INTEGER,
sellers INTEGER,
monthly_sold INTEGER,
rank_drops_30d INTEGER,
rank_drops_90d INTEGER,
fba_net_sheet REAL,
gross_profit_dollar REAL,
gross_profit_pct REAL,
net_profit_sheet REAL,
roi_sheet REAL,
moq INTEGER,
moq_cost REAL,
qty_available INTEGER,
supplier TEXT,
source_url TEXT,
asin_link TEXT,
promo_coupon_code TEXT,
notes TEXT,
lead_date TEXT,
fba_fee REAL,
fbm_fee REAL,
referral_percent REAL,
can_sell TEXT,
sellability_status TEXT,
sellability_reason TEXT,
verdict TEXT NOT NULL,
confidence INTEGER,
reasoning TEXT,
fetched_at TEXT NOT NULL,
FOREIGN KEY (run_id) REFERENCES runs(id)
);
`);
}