#!/usr/bin/env python3 """ Database migration: Client Portal (M1). Adds the authoritative client link to projects: - projects.client_id (TEXT, nullable) -> clients.id The `clients` and `client_access_tokens` tables are created automatically by SQLAlchemy `create_all` at app startup (they're brand-new tables), so this migration only handles the column that create_all won't add to an existing `projects` table. Run once per database: docker exec terra-view-terra-view-1 python3 backend/migrate_add_client_portal.py """ import sqlite3 from pathlib import Path def migrate(): possible_paths = [ Path("data/seismo_fleet.db"), Path("data/sfm.db"), Path("data/seismo.db"), ] db_path = next((p for p in possible_paths if p.exists()), None) if db_path is None: print(f"Database not found in any of: {[str(p) for p in possible_paths]}") print("A fresh DB created via models.py will include projects.client_id automatically.") return print(f"Using database: {db_path}") conn = sqlite3.connect(db_path) cursor = conn.cursor() cursor.execute("PRAGMA table_info(projects)") existing = {row[1] for row in cursor.fetchall()} if "client_id" not in existing: try: cursor.execute("ALTER TABLE projects ADD COLUMN client_id TEXT") print("āœ“ Added column: projects.client_id (TEXT)") except sqlite3.OperationalError as e: print(f"āœ— Failed to add projects.client_id: {e}") else: print("ā—‹ Column already exists: projects.client_id") conn.commit() conn.close() print("\nāœ“ Client-portal migration complete.") print(" Note: `clients` + `client_access_tokens` tables auto-create on app startup.") if __name__ == "__main__": migrate()