""" Migration: Add 3-tier role system to the portal DB. Replaces the old binary is_admin boolean with a role column ('admin' | 'advanced' | 'standard') on portal_users, and updates existing app_access.app_role values from the old 'user' string to the new 'standard' string. Run once against your existing portal.db: cd portal python migrate_roles.py """ import os import sqlite3 DB_PATH = os.environ.get( 'DATABASE_URL', os.path.join(os.path.dirname(__file__), 'data', 'portal.db'), ).replace('sqlite:///', '') if not os.path.exists(DB_PATH): # Try the instance folder as a fallback DB_PATH = os.path.join(os.path.dirname(__file__), 'instance', 'portal.db') print(f'Migrating: {DB_PATH}') con = sqlite3.connect(DB_PATH) cur = con.cursor() # ── 1. portal_users: add role column if missing ──────────────────────────────── cols = {row[1] for row in cur.execute("PRAGMA table_info(portal_users)")} if 'role' not in cols: print(' Adding portal_users.role column …') cur.execute("ALTER TABLE portal_users ADD COLUMN role TEXT NOT NULL DEFAULT 'standard'") # Populate from the old is_admin boolean if 'is_admin' in cols: cur.execute(""" UPDATE portal_users SET role = CASE WHEN is_admin = 1 THEN 'admin' ELSE 'standard' END """) print(' Populated role from is_admin.') con.commit() else: print(' portal_users.role already exists — skipping add.') # ── 2. app_access: rename old 'user' role value to 'standard' ───────────────── updated = cur.execute( "UPDATE app_access SET app_role = 'standard' WHERE app_role = 'user'" ).rowcount if updated: print(f' Updated {updated} app_access rows: user → standard') con.commit() print('Migration complete.') con.close()