Previously, init_collection_db() opened a separate sqlite3.connect() call,
ran migrations, then closed that connection — entirely outside the
thread-local pool that route handlers use via _get_db_conn().
This meant:
- The migration connection and the request-serving connection were
independent objects with no ordering guarantee under concurrent startup.
- The warm-up connection was thrown away immediately, so every handler
thread still had to open its own connection on first use.
Fix:
- init_collection_db() now calls _get_db_conn() directly, so schema
creation and migrations run on the same thread-local connection that
will serve subsequent requests.
- Added _close_db_conn() helper for explicit teardown on thread exit
(e.g. FastAPI lifespan shutdown or worker thread cleanup).
- Removed the redundant standalone conn.close() that discarded the
init connection without ever making it available to route handlers.