From 53eed8eda360e861542204c2726acb19ba430e09 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Mon, 8 Jun 2026 10:24:30 +0200 Subject: [PATCH] Fix: recreate genuinely-deleted Starface contacts instead of keeping dead mapping Der vorherige Fix war zu konservativ: bei einem in der geladenen Liste fehlenden Starface-Kontakt wurde das Mapping immer behalten und nichts neu angelegt - auch wenn der Kontakt in Starface wirklich geloescht war. In Richtung Outlook->Starface wurden geloeschte Kontakte dadurch nie wieder angelegt. Jetzt wird der Kontakt per ID abgefragt: - existiert noch (anderes Adressbuch) -> Mapping behalten, nichts anlegen - 404 (wirklich geloescht) -> in Both/OutlookToStarface neu anlegen (Phase 2), in StarfaceToOutlook Loeschung nach Outlook spiegeln Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 10 ++-- .../Services/SyncEngine.cs | 47 +++++++++++++++---- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 79e1496f..58cbefed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,9 +16,13 @@ Versionsschema ist `x.x.x.x` (siehe `release.sh`). "geloescht" ansehen, ihr Mapping verwerfen und sie beim naechsten Lauf neu anlegen. Der Kontakt-Abruf bricht jetzt mit Fehlermeldung ab (inkl. Wiederholversuch), statt still mit einer Teil-Liste weiterzuarbeiten. - - Ist ein Starface-Kontakt nicht in der geladenen Liste (z.B. anderes - Adressbuch), wird das Mapping jetzt **behalten** statt verworfen und neu - angelegt. + - Ist ein Starface-Kontakt nicht in der geladenen Liste, wird er jetzt per + ID direkt abgefragt: existiert er noch (liegt also in einem **anderen + Adressbuch**), bleibt das Mapping erhalten und es wird nichts neu angelegt + (keine Dublette). Ist er **wirklich geloescht** (404), wird er je nach + Sync-Richtung in Starface neu angelegt bzw. die Loeschung nach Outlook + gespiegelt. (Vorher wurde das Mapping faelschlich behalten und der Kontakt + in Outlook->Starface gar nicht neu angelegt.) - Das Wiederzuordnen bestehender Kontakte war zu streng: eine von Starface umformatierte Telefonnummer konnte einen eindeutigen E-Mail- oder Namens-Treffer ueberstimmen und so eine Neuanlage statt Verknuepfung diff --git a/src/StarfaceOutlookSync/Services/SyncEngine.cs b/src/StarfaceOutlookSync/Services/SyncEngine.cs index b2b87361..52189041 100644 --- a/src/StarfaceOutlookSync/Services/SyncEngine.cs +++ b/src/StarfaceOutlookSync/Services/SyncEngine.cs @@ -181,15 +181,44 @@ namespace StarfaceOutlookSync.Services if (oc != null && sc == null) { - // Starface-Kontakt nicht in der geladenen Liste. - // Da unvollstaendige Ladevorgaenge inzwischen abgebrochen - // werden (siehe StarfaceApiClient), liegt das hoechstens an - // einem anderen Adressbuch. NICHT loeschen und NICHT neu - // anlegen - sonst entstehen Dubletten. Mapping behalten, - // beim naechsten Sync wird es erneut abgeglichen. - Log($" Starface-Kontakt nicht in Liste (anderes Adressbuch?), behalte Mapping: {oc.DisplayName}"); - newMappings.Add(mapping); - continue; + // Starface-Kontakt nicht in der geladenen Liste. Zwei Faelle + // unterscheiden, indem wir ihn per ID direkt abfragen: + // (a) per ID noch vorhanden -> liegt in einem ANDEREN + // Adressbuch -> Mapping behalten, NICHT neu anlegen + // (sonst Dublette). + // (b) per ID 404 -> in Starface WIRKLICH geloescht. + bool stillExists = !string.IsNullOrEmpty(mapping.StarfaceId) + && await starface.GetContactAsync(mapping.StarfaceId) != null; + + if (stillExists) + { + Log($" Starface-Kontakt in anderem Adressbuch, behalte Mapping: {oc.DisplayName}"); + newMappings.Add(mapping); + continue; + } + + // Wirklich geloescht. + if (profile.SyncDirection == SyncDirection.Both + || profile.SyncDirection == SyncDirection.OutlookToStarface) + { + // Outlook ist (mit-)fuehrend -> Kontakt in Starface neu + // anlegen. Mapping verwerfen und oc wieder freigeben, + // damit Phase 2 ihn anlegt (inkl. Duplikat-Pruefung). + Log($" Starface-Kontakt geloescht, wird neu angelegt: {oc.DisplayName}"); + processedOutlookIds.Remove(oc.OutlookEntryId); + continue; + } + else + { + // StarfaceToOutlook: Starface ist fuehrend, Loeschung + // nach Outlook spiegeln. + if (_outlookService.DeleteContact(oc.OutlookEntryId)) + { + result.Updated++; + Log($" Geloescht (SF->OL): {oc.DisplayName}"); + } + continue; + } } if (oc != null && sc != null)