Abfrage-Builder: NOT-Operator, explizite Klammern und vollständige Feldabdeckung #194
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Kontext
Der visuelle Abfrage-Builder (
src/components/QueryBuilder.vue,lib/Service/QueryService.php, Issue #53) bietet aktuell verschachtelte UND/ODER-Gruppen, aber weder eine Negation (NOT) noch eine ausreichend vollständige Feldabdeckung. Damit lassen sich praktische Abfragen wie „alle aktiven Mitglieder, die keine Juleica besitzen“ oder „wer hat eine Nussallergie vermerkt?“ nicht ausdrücken.Diese Issue erweitert den Builder in einem Schritt um drei zusammengehörige Fähigkeiten:
Allergienund verknüpfter Entitäten (Telefone, E-Mails, Beiträge, Lagerteilnahme, Familie, Verletzungen)Aktueller Zustand
{ "and": [...] }/{ "or": [...] }) bis Tiefedepth < 3hardcodedQueryService::getAvailableFields()) enthält 18 Felder und ignoriert u. a.notizen,zusatz_notizen,einwilligung_datum,juleica_nummer,juleica_ablaufdatum,allergien_encryptedsowie sämtliche verknüpfte EntitätenÄnderungen
1. NOT-Operator
NOT (A AND B))not: truetragen, das beim Übersetzen in SQL einenNOT(...)-Wrapper erzeugt. Beispiel:not-Schlüssel funktionieren unverändert2. Explizite Klammerung (UX)
Die bisherige verschachtelte-Blöcke-Darstellung bleibt, wird aber um echte visuelle Klammern
()um Gruppen ergänzt. Zusätzlich:depth < 3-Grenze aufheben; stattdessen weiches Maximum entsprechend Backend-Validierung (aktuell 10) verwendenZielbild (ASCII-Mockup):
3. Feldliste erweitern
Alle Felder werden als Auswahl in
getAvailableFields()ergänzt. Gruppierung im Dropdown nach Herkunft (z. B.optgroupoder Präfix) ist wünschenswert.Fehlende Member-Spalten:
notizenzusatz_notizeneinwilligung_datumjuleica_nummerjuleica_ablaufdatumVerschlüsseltes Feld:
allergienVerknüpfte Entitäten (über EXISTS-Subqueries bzw. LEFT JOIN):
telefonemailfamilie_id(bestehend)familie_namebeitrag_bezahlt_jahrbeitrag_offen_jahrbeitrag_betraglager_teilnahmelager_nameverletzung_vorhandenFür Beziehungsfelder:
=,contains,starts_withsuchen auf mindestens einer verknüpften Zeile (SQLEXISTS)is_empty/is_not_emptyprüfen auf Abwesenheit / Anwesenheit einer verknüpften ZeileVerschlüsselte Abfrage auf
AllergienQueryServiceerkennt, ob die AbfrageallergienreferenziertQueryServicedieallergien_encrypted-Werte der Ergebniszeilen viaEncryptionServiceund filtert in PHPtotalwerden nach PHP-Filter berechnet (Gesamtzahl bezieht sich auf die gefilterte Menge)is_empty/is_not_emptyreicht ein reiner SQL-NULL/Empty-Check (keine Entschlüsselung nötig)Akzeptanzkriterien
Funktional — NOT
¬oder „NICHT“-PrefixNOT(...)gewrappedNOT (A AND NOT B))notwerden unverändert ausgeführtFunktional — Klammern
()gerendertdepth < 3-Grenze entfernt; maximale Tiefe wird nur durch Backend-Validierung begrenztFunktional — Felder
allergienist als Feld auswählbar und liefert korrekte Ergebnisse für=,!=,contains,starts_with,is_empty,is_not_emptyEXISTS-/JOIN-SQLSicherheit
allergienEncryptedohnehin liefert)FIELD_MAP(Whitelist) — kein dynamisches SQLTests
QueryService: NOT-Knoten (Leaf und Gruppe), neue Felder inkl. EXISTS-Joins, Allergien-PHP-Filter, Rückwärtskompatibilität mit AST ohnenotsaved_queries) laufen ohne ÄnderungDokumentation
docs/requirements.md/ Feature-Doku aktualisiertTechnische Hinweise
not-Flag ist additiv. Ein Knoten{ not: true, and: [...] }entsprichtNOT (A AND B). Auf Leaf-Ebene:{ not: true, field, op, value }entsprichtNOT (field op value).QueryService::validateAst()mussnotals optionales Flag akzeptierenQueryService::buildConditions()wrapped das zurückgegebene Expression-Objekt in$qb->createFunction('NOT (' . $inner . ')')wenn$node['not'] === truemembersExistsClause($qb, $subTable, $column, $op, $value)als private Helper-Methodesaved_queries: nicht nötig (JSON-Spalte ist frei strukturiert)Out-of-Scope
SearchBar)Abhängigkeiten / verwandte Issues
Umgesetzt in PR #195 (squash-merged nach
mainalsfa702e3) und released in v0.2.8. Alle Akzeptanzkriterien erfüllt; 25 neue Unit-Tests grün (1118/1118 gesamt).