#!/usr/bin/env python3 """ Auth DB — users and subscriptions schema for turf_saas.db Sprint 2-3: Auth JWT + Multi-tenant (HRT-28) HRT-79: migration Telegram columns """ import sqlite3 import os # NOTE: DB_PATH kept for backward compat, but get_db() reads env at call time # so test isolation works correctly when TURF_SAAS_DB is set per-module. DB_PATH = os.environ.get("TURF_SAAS_DB", "/home/h3r7/turf_saas/turf_saas.db") def get_db(): # Read env dynamically so test overrides of TURF_SAAS_DB are respected db_path = os.environ.get("TURF_SAAS_DB", DB_PATH) conn = sqlite3.connect(db_path) conn.row_factory = sqlite3.Row return conn def init_auth_tables(): """Create users and subscriptions tables if they don't exist.""" conn = get_db() c = conn.cursor() c.executescript(""" CREATE TABLE IF NOT EXISTS users ( id INTEGER PRIMARY KEY AUTOINCREMENT, email TEXT NOT NULL UNIQUE, password_hash TEXT NOT NULL, plan TEXT NOT NULL DEFAULT 'free' CHECK(plan IN ('free','premium','pro')), created_at DATETIME NOT NULL DEFAULT (datetime('now')), is_active INTEGER NOT NULL DEFAULT 1, daily_usage INTEGER NOT NULL DEFAULT 0, last_usage_date TEXT DEFAULT NULL ); CREATE TABLE IF NOT EXISTS subscriptions ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL REFERENCES users(id), plan TEXT NOT NULL CHECK(plan IN ('free','premium','pro')), start_date DATETIME NOT NULL DEFAULT (datetime('now')), end_date DATETIME, stripe_customer_id TEXT, FOREIGN KEY (user_id) REFERENCES users(id) ); CREATE TABLE IF NOT EXISTS refresh_tokens ( id INTEGER PRIMARY KEY AUTOINCREMENT, user_id INTEGER NOT NULL REFERENCES users(id), token_hash TEXT NOT NULL UNIQUE, created_at DATETIME NOT NULL DEFAULT (datetime('now')), expires_at DATETIME NOT NULL, revoked INTEGER NOT NULL DEFAULT 0 ); CREATE INDEX IF NOT EXISTS idx_users_email ON users(email); CREATE INDEX IF NOT EXISTS idx_subscriptions_user ON subscriptions(user_id); CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user ON refresh_tokens(user_id); CREATE INDEX IF NOT EXISTS idx_refresh_tokens_hash ON refresh_tokens(token_hash); """) conn.commit() conn.close() print("[auth_db] Tables users, subscriptions, refresh_tokens created/verified.") # Apply Telegram columns migration (idempotent) migrate_telegram_columns() def migrate_telegram_columns(): """ Migration idempotente : ajoute les colonnes Telegram à la table users. Utilise ALTER TABLE ... ADD COLUMN avec try/except OperationalError pour être safe si les colonnes existent déjà (SQLite ne supporte pas IF NOT EXISTS). HRT-79 """ conn = get_db() c = conn.cursor() columns = [ ("telegram_chat_id", "TEXT DEFAULT NULL"), ("alert_value_bets", "INTEGER DEFAULT 1"), ("alert_top1", "INTEGER DEFAULT 1"), ("alert_quinte_only", "INTEGER DEFAULT 0"), ] for col, definition in columns: try: c.execute(f"ALTER TABLE users ADD COLUMN {col} {definition}") print(f"[auth_db] Colonne '{col}' ajoutée.") except sqlite3.OperationalError: # Column already exists — safe to ignore pass conn.commit() conn.close() print("[auth_db] Migration Telegram columns OK.") if __name__ == "__main__": init_auth_tables()