* fix: normalize usage tokens + migration streaming/batching
- Migration: replace .fetchall() with yield_per streaming, replace per-message INSERT+SAVEPOINT with batched inserts (5k/batch) with fallback to row-by-row on error, add progress logging
- Write path: call normalize_usage() in upsert_message() before saving to ensure input_tokens/output_tokens always present
- Read path: analytics queries now COALESCE across input_tokens/prompt_tokens and output_tokens/completion_tokens so historical data with OpenAI-format keys is visible
* fix: restore defensive timestamp conversion in migration
Re-add try/except around int(float(timestamp)) that was accidentally dropped. Without this, a non-numeric timestamp string would cause a TypeError on the subsequent comparison, breaking the entire upgrade.
* revert: remove changes to chat_messages.py