fix: group_members beim Kontakt-Löschen bereinigen

Neue Funktion delete_group_members_by_uids in db.py entfernt
Member-Einträge aus group_members wenn ein Kontakt gelöscht wird.
Nutzt JOIN über groups Tabelle für Account-Scoping.
Doku in README.md aktualisiert.
This commit is contained in:
2026-08-07 15:33:31 +02:00
parent cccb4217b0
commit 57739f99a4
3 changed files with 18 additions and 3 deletions
+3 -3
View File
@@ -163,9 +163,9 @@ Gruppen sind über die API abrufbar:
- `GET /api/contacts/{id}` — Enthält `groups`-Feld mit Gruppennamen - `GET /api/contacts/{id}` — Enthält `groups`-Feld mit Gruppennamen
Wird eine Gruppe gelöscht, werden zugehörige Memberschaften automatisch Wird eine Gruppe gelöscht, werden zugehörige Memberschaften automatisch
entfernt (`ON DELETE CASCADE`). Gelöschte Mitglied-Kontakte verbleiben entfernt (`ON DELETE CASCADE`). Wird ein Mitglied-Kontakt gelöscht,
als Member-Eintrag in der Gruppe (ohne aufgelöste Kontaktdaten). Beim wird der Member-Eintrag in allen Gruppen ebenfalls entfernt (manueller
nächsten vollen Re-Sync werden tote Memberschaften bereinigt. Cleanup im Sync-Code). Die Gruppe selbst bleibt erhalten.
### Migration bei erstem Deploy ### Migration bei erstem Deploy
+14
View File
@@ -130,6 +130,20 @@ def delete_contacts_by_href_uids(conn, account: str, uids: list[str]):
conn.commit() conn.commit()
def delete_group_members_by_uids(conn, account: str, uids: list[str]):
if not uids:
return
with conn.cursor() as cur:
placeholders = ", ".join(["%s"] * len(uids))
cur.execute(
f"""DELETE gm FROM group_members gm
JOIN `groups` g ON g.id = gm.group_id
WHERE g.account = %s AND gm.member_uid IN ({placeholders})""",
[account] + uids,
)
conn.commit()
def _build_full_name(row: dict) -> str | None: def _build_full_name(row: dict) -> str | None:
parts = [ parts = [
row.get("prefix"), row.get("prefix"),
+1
View File
@@ -86,6 +86,7 @@ def sync_account(conn, account, href_to_uid_cache: dict):
else: else:
logger.warning("[%s] Konnte UID nicht aus href extrahieren: %s", account.name, href) logger.warning("[%s] Konnte UID nicht aus href extrahieren: %s", account.name, href)
db.delete_contacts_by_href_uids(conn, account.name, deleted_uids) db.delete_contacts_by_href_uids(conn, account.name, deleted_uids)
db.delete_group_members_by_uids(conn, account.name, deleted_uids)
db.delete_groups_by_uids(conn, account.name, deleted_uids) db.delete_groups_by_uids(conn, account.name, deleted_uids)
if new_token: if new_token: