- Add users.password_hash to _migrate_add_missing_columns pending list
- Skip tables that don't exist yet (prevents crash on fresh DB)
- Handle nullable columns (no DEFAULT clause) in ALTER TABLE
- Fix SQLite column type (use sql_type instead of hardcoded TEXT)
- Update migrate_roles.py to create schema columns/tables before seeding roles
- Add unit tests for migration: adds column, nullable, idempotent, no-op
- Add Role model and user_roles association table (many-to-many)
- Add password_hash column to User model (nullable, for future bcrypt)
- Keep is_admin boolean for backward compatibility
- Add is_admin_effective property: true if legacy is_admin OR 'admin' role
- Update auth dependency (get_current_admin_user) to use is_admin_effective
- Update bootstrap login to auto-create 'admin' role and assign on login
- Update Google OAuth login to use is_admin_effective for token creation
- Add migrate_roles.py: idempotent migration script to backfill roles
- Add unit tests for Role, User, association table, and is_admin_effective