mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-05 13:41:36 +02:00
Both `created_at` columns the restore dedupes on are `server_default=func.now()`. SQLite fills those from `CURRENT_TIMESTAMP`, which has second precision and stores `'2026-08-02 11:28:41'`, while SQLAlchemy binds a Python datetime as `'2026-08-02 11:28:41.000000'`. SQLite compares the two as strings, so `Model.created_at == created_at` never matched a row the application itself created — not even when handed that row's own value straight back out of the ORM. Every dedupe keyed on it therefore missed, on the ordinary case rather than an edge one: * `_find_spool`'s composite fallback duplicated every tag-less spool on each restore, and `overwrite_existing=True` never reached the original; * the usage-history dedupe re-inserted the user's entire consumption history on each restore. Rows the restore itself had inserted did match, because those carry an explicit bind in the same microsecond format — which is why the existing repeat-restore tests passed throughout. Fixed by filtering the candidates in SQL and comparing `created_at` in Python, which sidesteps the bind format and behaves identically on PostgreSQL, where the column keeps microseconds and the SQL comparison happened to work. `_parse_dt` now also normalises an offset-bearing value to naive UTC, matching what the naive columns actually hold; the collector never writes one, so that guards hand-edited and foreign backups. Seven tests, six of which fail without the fix. They seed the "existing" row the way the application does — no explicit `created_at` — which is what the existing coverage was missing.