- database.py: CryptContext = ['bcrypt', 'sha256_crypt'] with sha256_crypt deprecated
- database.py: add verify_and_update_password() returning (ok, new_hash)
- main.py: login uses verify_and_update; on successful verify transparently
commits new bcrypt hash when old hash is sha256_crypt
- requirements.txt: passlib[bcrypt]==1.7.4 + bcrypt==4.0.1 (compat with passlib 1.7.4)
Migration: zero-touch. Admin's first login after this deploy will
auto-upgrade the stored hash from $5$... to $2b$...
Avoids the passlib sha256_crypt cross-version verify bug that bit us
this morning. bcrypt is OpenSSL-native and stable across passlib
versions.