ulysses/core
Tatlatat 8ad436d25a
DB: enable SQLite foreign key cascades
* fix(db): enable SQLite foreign keys so ondelete cascades actually fire

core/database.py declares DB-level FK actions throughout
(ondelete="CASCADE" / "SET NULL"), but SQLite disables foreign-key
enforcement per connection by default and the engine had no connect-event
listener turning it on. So every one of those ondelete actions was dead.

Concrete impact: cleanup_old_sessions() in src/cleanup_service.py removes
old sessions with a bulk `query(Session).delete()`, which bypasses the
ORM-level relationship cascade and relies solely on the DB-level
ondelete="CASCADE" on ChatMessage.session_id. With foreign keys off, the
messages are never deleted — they pile up as orphaned rows on every
cleanup cycle.

Add the standard SQLAlchemy connect listener issuing `PRAGMA
foreign_keys=ON`, guarded by `isinstance(conn, sqlite3.Connection)` so it
only affects SQLite and leaves other backends untouched.

tests/test_sqlite_foreign_keys.py inserts a Session + ChatMessage, deletes
the Session via bulk `query().delete()`, and asserts the ChatMessage is
cascade-deleted. Fails before this change (orphan remains).

* docs(db): clarify FK pragma scope per review; trim test comments

Address review feedback on the foreign_keys PRAGMA change:
- Note that the class-level connect listener fires for every Engine in the
  process and is a no-op on non-SQLite backends (isinstance guard).
- Warn near init_db() that FK enforcement is now global, so a migration
  that temporarily violates FK constraints must disable foreign_keys around
  that work.
- Drop the step-by-step narration comments from the regression test.

No behavior change.
2026-06-02 20:36:13 +09:00
..
__init__.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
atomic_io.py Add native Windows compatibility layer 2026-06-01 15:09:47 +09:00
auth.py Revoke stale sessions after password change 2026-06-02 05:59:22 +09:00
constants.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
database.py DB: enable SQLite foreign key cascades 2026-06-02 20:36:13 +09:00
exceptions.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
middleware.py Fix email-thread HTML injection, attachment path traversal, and missing authz (#475) 2026-06-01 22:20:17 +09:00
models.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
platform_compat.py Add native Windows compatibility layer 2026-06-01 15:09:47 +09:00
session_manager.py Fix chat message history timestamps 2026-06-01 11:18:18 +09:00