#!/usr/bin/env python3 """ Org DB — Multi-compte / Organisations Pro Sprint: HRT-82 Migration idempotente : crée les tables organizations et org_members dans turf_saas.db si elles n'existent pas. Run une seule fois : ./venv/bin/python org_db.py """ import sqlite3 import os import logging DB_PATH = os.environ.get("TURF_SAAS_DB", "/home/h3r7/turf_saas/turf_saas.db") logger = logging.getLogger("turf_saas.org_db") def get_db(): conn = sqlite3.connect(DB_PATH) conn.row_factory = sqlite3.Row conn.execute("PRAGMA foreign_keys = ON") return conn def migrate_org_tables(): """ Migration idempotente : crée organizations + org_members. - organizations : 1 org max par owner (enforced en Python + UNIQUE owner_id) - org_members : max 5 membres totaux (owner inclus, enforced en Python) - UNIQUE(org_id, user_id) empêche les doublons de membres """ conn = get_db() c = conn.cursor() c.executescript(""" CREATE TABLE IF NOT EXISTS organizations ( id TEXT PRIMARY KEY, owner_id TEXT NOT NULL UNIQUE, name TEXT NOT NULL, max_members INTEGER NOT NULL DEFAULT 5, created_at DATETIME NOT NULL DEFAULT (datetime('now')) ); CREATE TABLE IF NOT EXISTS org_members ( id INTEGER PRIMARY KEY AUTOINCREMENT, org_id TEXT NOT NULL REFERENCES organizations(id) ON DELETE CASCADE, user_id TEXT NOT NULL, role TEXT NOT NULL DEFAULT 'member' CHECK(role IN ('owner', 'member')), invited_at DATETIME NOT NULL DEFAULT (datetime('now')), joined_at DATETIME, UNIQUE(org_id, user_id) ); CREATE INDEX IF NOT EXISTS idx_org_owner ON organizations(owner_id); CREATE INDEX IF NOT EXISTS idx_orgmem_org ON org_members(org_id); CREATE INDEX IF NOT EXISTS idx_orgmem_user ON org_members(user_id); """) conn.commit() conn.close() logger.info("[org_db] Tables organizations + org_members créées/vérifiées.") print("[org_db] Migration OK: organizations, org_members.") if __name__ == "__main__": logging.basicConfig(level=logging.INFO) migrate_org_tables()