fix(backend+frontend): ?invitable=true ersetzt ?withoutGroup; Pending-Raeumung bei Gruppenbeitritt #209

Closed
opened 2026-07-03 19:10:36 +02:00 by niboer · 1 comment
Owner

Beschreibung

Unter app/groups/{groupId} listet der "Mitglied hinzufuegen"-Button keine Personen auf.

Ursache

Der Fetch ruft /api/v1/persons?withoutGroup=true auf. Funktioniert theoretisch, aber:

  • Kein archived=false → archivierte Personen ohne Haushalt werden ebenfalls angezeigt (bzw. blockieren ggf. die Liste)
  • Fehlende Pending-Raeumung: Personen mit ausstehenden Einladungen haben einen GroupMember-Eintrag und sind korrekt ausgeblendet. Aber wenn eine Einladung abgelehnt wird, bleibt der Eintrag als approvedBy: null bestehen.

Geplanter Fix

1. Backend: withoutGroupinvitable

backend/src/routes/persons.tswithoutGroup entfernen, invitable neu:

if (invitable === true) {
  where.archivedAt = null;
  where.groupMembers = { none: {} };
}

invitable kombiniert beide Filter (aktiv + kein Haushalt).

2. Backend: Pending-Raeumung bei Gruppenbeitritt

Wenn eine Person in einen Haushalt aufgenommen wird (Action approveJoin oder addMember), werden alle anderen ausstehenden GroupMember-Eintraege fuer diese Person geloescht:

await prisma.groupMember.deleteMany({
  where: {
    personId: personId,
    approvedBy: null,
    NOT: { groupId: acceptedGroupId },
  },
});

Damit ist sichergestellt, dass groupMembers: { none: {} } zuverlaessig bedeutet "Person ist keinem Haushalt zugeordnet".

Betroffene Dateien

Datei Aenderung
backend/openapi.yaml withoutGroup raus, invitable rein
backend/src/routes/persons.ts withoutGroupinvitable
backend/src/routes/groups.ts Pending-Raeumung bei addMember/approveJoin
backend/src/__tests__/persons.test.ts Test ersetzen
backend/src/__tests__/groups.test.ts Neuer Test fuer Pending-Raeumung
frontend/src/lib/api/generated.ts Orval regenerieren
frontend/src/routes/app/groups/[groupId]/+page.svelte ?withoutGroup=true?invitable=true

Akzeptanzkriterien

  • ?invitable=true gibt nur aktive (archivedAt: null) Personen ohne Haushalt zurueck
  • ?withoutGroup=true existiert nicht mehr (weder in OpenAPI noch im Code)
  • Bei addMember/approveJoin werden andere Pending-Eintraege der Person geloescht
  • Orval-Typen enthalten invitable
  • Frontend-Dialog zeigt korrekt einladbare Personen an
  • npm test laeuft ohne Fehler
  • npm run build ist erfolgreich
## Beschreibung Unter `app/groups/{groupId}` listet der "Mitglied hinzufuegen"-Button keine Personen auf. ### Ursache Der Fetch ruft `/api/v1/persons?withoutGroup=true` auf. Funktioniert theoretisch, aber: - Kein `archived=false` → archivierte Personen ohne Haushalt werden ebenfalls angezeigt (bzw. blockieren ggf. die Liste) - Fehlende Pending-Raeumung: Personen mit ausstehenden Einladungen haben einen `GroupMember`-Eintrag und sind korrekt ausgeblendet. Aber wenn eine Einladung abgelehnt wird, bleibt der Eintrag als `approvedBy: null` bestehen. ## Geplanter Fix ### 1. Backend: `withoutGroup` → `invitable` **`backend/src/routes/persons.ts`** — `withoutGroup` entfernen, `invitable` neu: ```typescript if (invitable === true) { where.archivedAt = null; where.groupMembers = { none: {} }; } ``` `invitable` kombiniert beide Filter (aktiv + kein Haushalt). ### 2. Backend: Pending-Raeumung bei Gruppenbeitritt Wenn eine Person in einen Haushalt aufgenommen wird (Action `approveJoin` oder `addMember`), werden alle anderen ausstehenden `GroupMember`-Eintraege fuer diese Person geloescht: ```typescript await prisma.groupMember.deleteMany({ where: { personId: personId, approvedBy: null, NOT: { groupId: acceptedGroupId }, }, }); ``` Damit ist sichergestellt, dass `groupMembers: { none: {} }` zuverlaessig bedeutet "Person ist keinem Haushalt zugeordnet". ### Betroffene Dateien | Datei | Aenderung | |-------|-----------| | `backend/openapi.yaml` | `withoutGroup` raus, `invitable` rein | | `backend/src/routes/persons.ts` | `withoutGroup` → `invitable` | | `backend/src/routes/groups.ts` | Pending-Raeumung bei addMember/approveJoin | | `backend/src/__tests__/persons.test.ts` | Test ersetzen | | `backend/src/__tests__/groups.test.ts` | Neuer Test fuer Pending-Raeumung | | `frontend/src/lib/api/generated.ts` | Orval regenerieren | | `frontend/src/routes/app/groups/[groupId]/+page.svelte` | `?withoutGroup=true` → `?invitable=true` | ## Akzeptanzkriterien - [ ] `?invitable=true` gibt nur aktive (`archivedAt: null`) Personen ohne Haushalt zurueck - [ ] `?withoutGroup=true` existiert nicht mehr (weder in OpenAPI noch im Code) - [ ] Bei addMember/approveJoin werden andere Pending-Eintraege der Person geloescht - [ ] Orval-Typen enthalten `invitable` - [ ] Frontend-Dialog zeigt korrekt einladbare Personen an - [ ] `npm test` laeuft ohne Fehler - [ ] `npm run build` ist erfolgreich
Author
Owner

Update — Aktualisierter Loesungsplan (04.07.2026)

Neuer Ansatz

Statt ?withoutGroup=true wird ?invitable=true eingefuehrt. Der alte withoutGroup-Parameter entfaellt komplett.

Backend: ?invitable=true an GET /api/v1/persons

backend/src/routes/persons.tswithoutGroup entfernen, invitable neu:

if (invitable === true) {
  where.archivedAt = null;
  where.groupMembers = { none: {} };
}

Backend: Pending-Join-Aufraeumung bei Beitritt

Wenn eine Person in einen Haushalt aufgenommen wird (approvedBy gesetzt), werden alle anderen ausstehenden GroupMember-Eintraege fuer diese Person geloescht:

await tx.groupMember.deleteMany({
  where: {
    personId: personId,
    approvedBy: null,
    NOT: { groupId: groupId },
  },
});

Dadurch ist groupMembers: { none: {} } der alleinige Indikator fuer "einladbar".

Betroffene Dateien

Datei Aenderung
backend/openapi.yaml withoutGroup raus, invitable rein
backend/src/routes/persons.ts withoutGroupinvitable
backend/src/routes/groups.ts Pending-Raeumung bei Beitritt
backend/src/__tests__/persons.test.ts Test ersetzen
backend/src/__tests__/groups.test.ts Neuer Test
frontend/src/lib/api/generated.ts Orval regenerieren
frontend/src/routes/app/groups/[groupId]/+page.svelte ?invitable=true
## Update — Aktualisierter Loesungsplan (04.07.2026) ### Neuer Ansatz Statt `?withoutGroup=true` wird `?invitable=true` eingefuehrt. Der alte `withoutGroup`-Parameter entfaellt komplett. ### Backend: `?invitable=true` an `GET /api/v1/persons` **`backend/src/routes/persons.ts`** — `withoutGroup` entfernen, `invitable` neu: ```typescript if (invitable === true) { where.archivedAt = null; where.groupMembers = { none: {} }; } ``` ### Backend: Pending-Join-Aufraeumung bei Beitritt Wenn eine Person in einen Haushalt aufgenommen wird (`approvedBy` gesetzt), werden alle anderen ausstehenden `GroupMember`-Eintraege fuer diese Person geloescht: ```typescript await tx.groupMember.deleteMany({ where: { personId: personId, approvedBy: null, NOT: { groupId: groupId }, }, }); ``` Dadurch ist `groupMembers: { none: {} }` der alleinige Indikator fuer "einladbar". ### Betroffene Dateien | Datei | Aenderung | |-------|-----------| | `backend/openapi.yaml` | `withoutGroup` raus, `invitable` rein | | `backend/src/routes/persons.ts` | `withoutGroup` → `invitable` | | `backend/src/routes/groups.ts` | Pending-Raeumung bei Beitritt | | `backend/src/__tests__/persons.test.ts` | Test ersetzen | | `backend/src/__tests__/groups.test.ts` | Neuer Test | | `frontend/src/lib/api/generated.ts` | Orval regenerieren | | `frontend/src/routes/app/groups/[groupId]/+page.svelte` | `?invitable=true` |
niboer changed title from Gruppen-Mitglieder-Suche zeigt "Alle Personen sind bereits in einem Haushalt" trotz vorhandener personenOhneHaushalt to fix(backend+frontend): ?invitable=true ersetzt ?withoutGroup; Pending-Raeumung bei Gruppenbeitritt 2026-07-04 14:09:03 +02:00
niboer reopened this issue 2026-07-05 01:46:58 +02:00
Sign in to join this conversation.
No description provided.