fupshop-detector / database.py
mibrahimalpha's picture
FupShop v2.0 - clean deploy without model files
005c0b0
Raw
History Blame Contribute Delete
4.46 kB
import sqlite3
import json
import os
from datetime import datetime
DB_PATH = os.path.join(os.path.dirname(__file__), '..', 'data', 'fupshop.db')
def init_db():
"""Create all tables. Run once at startup."""
os.makedirs(os.path.dirname(DB_PATH), exist_ok=True)
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
# Every scan a user makes
c.execute('''
CREATE TABLE IF NOT EXISTS scans (
id INTEGER PRIMARY KEY AUTOINCREMENT,
url TEXT NOT NULL,
domain TEXT NOT NULL,
risk_score REAL,
prediction TEXT, -- SAFE, CAUTION, AVOID
features_json TEXT, -- All 13 features as JSON
raw_data_json TEXT, -- Full API responses
shap_explanation TEXT, -- Top 3 SHAP reasons
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
# Labeled data for retraining
c.execute('''
CREATE TABLE IF NOT EXISTS labels (
id INTEGER PRIMARY KEY AUTOINCREMENT,
url TEXT NOT NULL,
domain TEXT NOT NULL,
is_scam INTEGER NOT NULL, -- 0 or 1
source TEXT, -- 'manual', 'user_report', 'forbrugerombudsmanden'
features_json TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
# User scam reports
c.execute('''
CREATE TABLE IF NOT EXISTS user_reports (
id INTEGER PRIMARY KEY AUTOINCREMENT,
url TEXT NOT NULL,
domain TEXT NOT NULL,
lost_money INTEGER, -- 0 or 1
amount_lost REAL,
description TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
# Model versions for rollback
c.execute('''
CREATE TABLE IF NOT EXISTS model_versions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
version TEXT NOT NULL,
wandb_run_id TEXT,
f1_score REAL,
accuracy REAL,
model_path TEXT,
deployed_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
conn.commit()
conn.close()
print(f"Database initialized at: {DB_PATH}")
def save_scan(url, domain, risk_score, prediction, features, raw_data, shap_exp):
"""Save a prediction result."""
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
c.execute('''
INSERT INTO scans (url, domain, risk_score, prediction, features_json, raw_data_json, shap_explanation)
VALUES (?, ?, ?, ?, ?, ?, ?)
''', (url, domain, risk_score, prediction, json.dumps(features), json.dumps(raw_data), json.dumps(shap_exp)))
conn.commit()
scan_id = c.lastrowid
conn.close()
return scan_id
def save_label(url, domain, is_scam, source, features):
"""Save a labeled example for retraining."""
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
c.execute('''
INSERT INTO labels (url, domain, is_scam, source, features_json)
VALUES (?, ?, ?, ?, ?)
''', (url, domain, is_scam, source, json.dumps(features)))
conn.commit()
conn.close()
def save_user_report(url, domain, lost_money, amount_lost, description):
"""Save user scam report."""
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
c.execute('''
INSERT INTO user_reports (url, domain, lost_money, amount_lost, description)
VALUES (?, ?, ?, ?, ?)
''', (url, domain, lost_money, amount_lost, description))
conn.commit()
conn.close()
def get_training_data():
"""Get all labeled data for model retraining."""
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
c.execute('SELECT url, domain, is_scam, features_json FROM labels')
rows = c.fetchall()
conn.close()
return rows
def get_scan_history(limit=50):
"""Get recent scans for dashboard."""
conn = sqlite3.connect(DB_PATH)
c = conn.cursor()
c.execute('''
SELECT url, domain, risk_score, prediction, created_at
FROM scans ORDER BY created_at DESC LIMIT ?
''', (limit,))
rows = c.fetchall()
conn.close()
return rows
# Initialize on import
init_db()
if __name__ == "__main__":
# Test
print("Testing database...")
save_scan("https://test.dk", "test.dk", 15.5, "SAFE", {"feat1": 1}, {"raw": "data"}, ["domain old"])
print("Scan saved!")
history = get_scan_history()
print(f"Recent scans: {history}")