fix(import): restore favorite + pinned on import/backup restore

A pinned entry came back unpinned after export→import. Wider than pinned:
`favorite` was WRITTEN into the export/backup/sync containers but nothing
ever read it back — not parseEntriesFromJSON, not encryptImportEntry, not
the server INSERTs. So it was a write-only field, and a restore silently
dropped both flags. `pinned` wasn't in any container at all.

Wired the full round-trip:
- containers: export + auto-backup now carry `pinned` (favorite was there).
- parseEntriesFromJSON reads both back (absent → 0, e.g. foreign CSV).
- encryptImportEntry passes them through to the body.
- server create + bulk-import INSERTs write favorite/pinned
  (GetValue<Boolean>(..., False) → 0 default). PUT still ignores them, so a
  sync update can't clobber local flags.

Sync stays device-local as decided 2026-07-11: buildSyncSnapshot now OMITS
favorite explicitly (it was dead weight before; with the passthrough live,
leaving it in would have started propagating it). Commented so the intent
isn't re-broken.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
r-zakarya
2026-07-25 16:06:05 +01:00
parent a6ba0100ee
commit 30e37b3fbd
6 changed files with 47 additions and 14 deletions
+11 -4
View File
@@ -965,10 +965,17 @@ le vide ET vide `FPendingURL` → écran noir permanent sur cold-start lent.
assumé device-local (purge de cache favicon). **`favorite` et `pinned`
(toggles `POST /entries/{id}/favorite|pin`) sont aussi exemptés exprès** :
absents de `buildSyncSnapshot`, donc **device-local par design** (décidé
2026-07-11) — comme l'avatar. `favorite` est quand même dans l'auto-backup +
export/import (round-trip local), juste pas propagé par le sync. Si un jour on
veut les synchroniser : ajouter au snapshot + bumper `updated_at` sur le toggle
+ appliquer au merge.
2026-07-11) — comme l'avatar. En revanche ils **round-trippent** par
export/import + auto-backup (restaurer une sauvegarde rend la liste telle
quelle) : container → `parseEntriesFromJSON` → `encryptImportEntry` →
INSERT create + bulk-import (`GetValue<Boolean>(…, False)` → 0 si absent,
ex. CSV étranger). **C'est l'omission dans le snapshot de sync qui les garde
device-local** — `encryptImportEntry` fait un passthrough générique, donc
les remettre dans `buildSyncSnapshot` suffirait à les propager (+ bumper
`updated_at` sur le toggle + appliquer au merge). Piège historique : le
snapshot écrivait `favorite` mais **rien ne le relisait** (ni parser, ni
body, ni INSERT) → l'export semblait le porter alors que l'import le
perdait, et `pinned` n'était nulle part.
- **Timestamps = UTC partout** : tout `created_at`/`updated_at`/`deleted_at`
écrit côté Delphi passe par `NowUTC`/`NowUTCStr` (`PM.Database`) — JAMAIS
`FormatDateTime(..., Now)` (heure locale). SQLite `CURRENT_TIMESTAMP` /