Member ist die Lead-Tabelle für das Vertragsverhältnis Mitglied↔Verein — nicht für den Menschen (das ist die Person). Verknüpfung M:N über LinkMemberPerson mit relation_type: eine Familienmitgliedschaft kann mehrere Personen haben, eine Person mehrere Mitgliedschaften.
| Feld | Bedeutung |
|---|---|
display_name |
Bezeichnung der Mitgliedschaft (Fallback: Hauptkontakt-Name oder „Mitglied {nr}") |
member_number |
optional, unique pro Club; Auto-Vergabe: max(bestehende int-Nummern)+1, mindestens 1000. Alphanumerische Nummern (M-2026-001) bleiben unangetastet |
member_single |
Einzelperson vs. Kollektiv — wird automatisch abgeleitet aus der Anzahl verlinkter Personen |
status |
nur aktiv/passiv |
exited / exit_date |
Austritt ist unabhängig vom Status. Ein Austrittsdatum setzen impliziert exited=True. Der 3-Wert-Import „aktiv/passiv/ausgetreten" wird zu status=passiv + exited=True aufgeteilt |
additional_person_data |
JSON-Parkplatz für Personen-Spalten aus Mehrpersonen-Excels (Legacy — seit v0.16.17 landet hier fast nichts mehr) |
relation_type-Werte: contact (Label „Mitglied", Standard bei Einzelmitgliedschaft), primary_contact, secondary_contact, billing, legal_guardian, child, emergency_contact, participant, player, custom (+ Freitext).
/clucore/mitglieder/)Vue3-„CluhuTable"-Power-Widget, gefüttert von member_list in apps/organization/api.py.
sort=address__postal_code)filter[feld]=… typenspezifisch (text/exact/boolean/number/date/select), auch für Custom-Felder und Adress-Komponenten. member_number filtert exakt — damit „2" nicht auch „12" trifftLeadtableView), speichern Spalten/Sortierung/Ergebniszeile; eines kann Default sein. Zusätzlich Session-Persistenz des aktuellen Zustands?filter[member_number]=… / ?filter[person_number]=…) — jede Liste übernimmt URL-Filter beim Laden. ⚠️ Der Filter wird in der Session gemerkt und bleibt bis zum manuellen Entfernen?manual=1 überspringt ihnmember_reset_all; bis v0.28.126 «ALLE LÖSCHEN», bis v0.28.163 «Alle Mitglieder archivieren» mit «ARCHIVIEREN»): Dialog mit Blocker-Klassen, Bestätigungswort «löschen» (klein, Gross-/Kleinschreibung egal). Die Oberfläche sagt seit v0.28.165 überall «löschen»; technisch werden Mitgliedschaften und importierte Personen ohne Login archiviert (archived_at, Grundeintrag mit Name und Nummer bleibt) und gelöscht werden Zellwerte, Import-Batches, verwaiste Adressen/Telefone; Felddefinitionen bleiben (seit v0.28.127). Login-Personen bleiben. Siehe Mitgliedschaften › Archiv/clucore/mitglieder/zuordnung/)Siehe Mehrpersonen-Mitgliedschaft für den Canvas und Design-Entscheidungen für die Feld-Eigentümerschafts-Geschichte. Kurzfassung:
?view=list — „Spalten-Eigenschaft" (Simpel-Modus): Regel „Spalte → Person/Feld" ohne Canvas?view=firmen — Firmen-Canvas (braucht Addon „Firmen Mitglieder")Der Apply-Motor befüllt nur leere Ziele und konsumiert den Member-Wert (Verschieben, nicht Kopieren — „eine Wahrheit"). Danach projiziert die Mitglieder-Spalte das Personen-Feld; Edits schreiben durch (Write-Through). Regeln liegen in PersonFieldMapping (persistent, Import-Sync via sync_import_mappings, verwaiste Regeln bleiben sichtbar statt still zu verschwinden).
EAV-System: CustomColumnDefinition (pro Club + Ziel-Objekt, Datentypen: text, textarea, checkbox, dropdown, multiselect, date_picker, number, asset, email/phone/address = strukturierte Kontakt-Typen, entity_link = read-only Fremdfeld) → CustomColumnCellValue (polymorph, typisierte Slots). Validierungsregeln in CustomColumnAttribute, Dropdown-Optionen mit Farbe/Icon.
Was kann es: «Aktionen › eigene Felder» in der Mitgliederliste und der Personenliste öffnet die Feldverwaltung (direkt erreichbar mit ?ansicht=felder). Im Detail eines Feldes steht am Ende des Registers «Grunddaten» der Block «Beim Anlegen»: der Modus (abfragen, verbergen, mit Vorgabe abfragen, stumm befüllen) mit einem erklärenden Satz und, bei den zwei Modi mit Vorgabe, der Vorgabewert. Lesen, Bearbeiten und «+ Feld» zeigen denselben Block. Das Eingabe-Element folgt der Feldart: Text, Zahl, Datum, Ja/Nein, Auswahl aus den Optionen, Mehrfachauswahl als Checkboxen, Verrechnungsartikel als Auswahl der Artikel. Bei einem neuen Dropdown stehen die eben erfassten Optionen sofort als Vorgabewert zur Wahl.
Wer liest das: die Erfassungsmaske für neue Mitgliedschaften und der Mitglieder-Import (leere Zellen einer zugeordneten Spalte). Bestehende Einträge ändern sich nie. Dieselben Angaben stehen gesammelt unter Einstellungen › Vereinsdaten › Mitgliedschaften, siehe Mitgliedschaften.
Regeln:
entry_defaults.SKIP_TYPES, dieselbe Liste wie organization/api.MC_SKIP_TYPES).Warum so gebaut: Modus und Vorgabewert gehören zum Feld, nicht zu einem Importlauf. Bis v0.28.177 liessen sie sich nur im Import-Schritt «Vorgabe» setzen und danach nie mehr ändern (Hintergrund auf Import). Der Block steht unter «Grunddaten», weil er für jedes Feld gilt und kein eigenes Register rechtfertigt.
Warum nicht anders: Freier Text als Vorgabewert (wie im alten Schritt) liess «irgendwas» für ein Datum zu, und die Maske scheiterte dann beim Anlegen. Eine stille Korrektur beim Entfernen einer Option wäre bequemer, würde aber verstecken, dass neue Mitgliedschaften das Feld ab jetzt leer bekommen; darum der Hinweis.
Technik: apps/columns/entry_defaults.py (prüfen clean, Lesefassung display, aufräumen settle, Befund stale_reason, Formular der Vereinsdaten submit), apps/columns/api.py (fields/create/ in einer Transaktion, fields/<pk>/update/, Detail mit default_display, entry_choices, entry_stale), static/js/cluhu-field-manager.js (data-entry-block). Speicherform von default_value: Zahl 1200.5, Datum JJJJ-MM-TT, Checkbox true/false, Dropdown Optionswert, Mehrfachauswahl Werte mit , verbunden, Artikel als ID. Tests apps/columns/tests_beim_anlegen.py (31).
Strukturierte Kontaktfelder (v0.16.53): eine zweite E-Mail-/Telefon-/Adress-Spalte wird als Custom-Feld definiert, die Werte liegen aber in den echten Entitäten (EmailAddress/PhoneNumber/Address), nicht als Text — dadurch bleiben sie validier- und verknüpfbar.
Feldtyp-Konvertierung bestehender Werte: /api/columns/fields/<id>/convert/ mit Dry-Run-Prüfung aller Werte vor der Umstellung.
Was sich in der Mitgliederliste geändert hat (Details und Warum auf Mitgliedschaften):
/api/org/empfaenger/, Komponente static/js/cluhu-komm-matrix.js, Partial templates/organization/_mitglied_empfaenger.html, dasselbe unter Mail › Mitglied-Empfänger). Zeilenmenü ⋯ › Mitglied-Empfänger öffnet das Popup für eine Mitgliedschaft.sort=entry), im Trichter der Spalte Datumsbereich und (seit v0.28.131, nicht in Form E) das Radio «Eintritte der Personen: alle / alle gleich (gemeinsamer Start) / verschieden» (filter[entry_same]), Info-«i» mit der Rechenregel; in Form E direkt editierbar. Austritt je Person im Personen-Popup (static/js/cluhu-person-links.js: Art «macht mit»/«betreut», Etikett, Eintritt, Austritt, Hauptperson, «Austritt setzen/aufheben»); der Haken «ausgetretene Personen mit anzeigen» sitzt seit v0.28.131 im Trichter der Spalte «Personen» (filter[show_exited]=1, ?exited=1 gilt weiter) — er ist kein Zeilenfilter, sondern blendet nur die ausgetretenen Namen in dieser Spalte grau wieder ein.CluhuTable kennt je Spalte filterExtras — Radio- oder Haken-Blöcke, die im Trichter-Popover unter dem Hauptfilter erscheinen, mit demselben «Zurücksetzen / Anwenden», leuchtendem Trichter, Sicherung mit Session/Profil und Übernahme aus der URL (?filter[entry_same]=1). filterType: 'none' = Spalte nur mit Zusatzoptionen (so die Spalte «Personen», deren Trichter vorher eine leere Auswahlliste war). Künftige Sonderoptionen einer Spalte sind damit ein Eintrag in der Spaltendefinition, kein neues Bedienelement. Warum im Trichter und nicht in der Werkzeugleiste: die Leiste brach am Handy über den Rand und scrollte die ganze Seite; Optionen, die eine Spalte betreffen, gehören an die Spalte.flex-wrap), «Mitglied hinzufügen» und «Aktionen» bleiben rechts (ml-auto), auch in der zweiten Zeile; dasselbe in der Personenliste.PATCH /api/org/links/member-person/<id>/update/ (Haken, Etikett, Eintritt, Austritt, Hauptperson, Rechnung); Anlegen nimmt die Haken statt eines Rollencodes. _member_to_dict liefert entry, entry_kind, exited, exit_date, archived_at, designation; member_update nimmt entry, exit_date, designation.?archived=1 zeigt archivierte Mitgliedschaften/Personen (sonst ausgeblendet, auch im Export). Löschen einer Zeile archiviert technisch; bei Blockern antwortet die API 409 und die Tabelle zeigt die Liste (blockiert durch / bleibt erhalten / würde mit gelöscht) statt die Zeile stumm stehen zu lassen. Nach dem Löschen heisst der Ergebnisdialog «Gelöscht» (v0.28.165). Eine Oberfläche für ?archived=1, Wiederherstellen oder endgültiges Löschen gibt es nicht.relation_type; seit v0.28.126 stehen die massgebenden Felder am Link als Haken (participates, caretaker, Bereiche, receives_invoice), relation_type ist nur noch lesbarer Übergang.Was kann es: «Mitglied hinzufügen» zeigt feste Blöcke je Mitgliedschaftsform. Form E: Block «‹Vereinswort›» (Vorname, Nachname, Geburtsdatum oder Jahrgang, Geschlecht w/m/x mit Vorschlag «abgeleitet aus Vorname», E-Mail und Telefon optional, Adresse) und Block «Mitgliedschaft» (Mitgliedernummer mit Vorschlag «nächste freie», Eintritt, Status, Zusatzfelder). Form V: Block Vereinswort («macht mit · Kind oder Erwachsener»), «Erziehungsberechtigte 1» (Rechnung, Mitgliederportal, Termine, Vereinsinfos laut Vorgabe; Adresse «gleich wie oben» vorgewählt), «Erziehungsberechtigte 2» eingeklappt, «Kontaktangabe» («+ Notfallnummer hinzufügen», Name und Telefon ohne eigene Person), Mitgliedschaft. Form H: «Bezeichnung» (Vorgabe «Familie ‹Nachname›», D55), bis zu sechs Personen mit Art (macht mit / betreut / beides / Kind ohne Teilnahme), Kontaktangabe. Personenvorschlag: bei bekannter E-Mail oder gleichem Nachnamen mit Adresse erscheint «gehört bereits Anna Muster, Erziehungsberechtigte 1 von Lea Muster (Nr. 1042) · Diese Person verwenden / Andere Adresse»; nie stilles Zusammenführen. Zusatzfelder nach Modus (D86): abfragen, mit Vorgabe abfragen, verbergen, stumm befüllen — für Mitgliedschaft und Personen. Den Modus und den Vorgabewert stellt man seit v0.28.178 am Feld ein (Block «Beim Anlegen», Abschnitt «Custom-Felder» oben), nicht mehr im Import. Nach dem Speichern gilt die Vorgabe beim Anlegen (Register Mitglied-Empfänger), Warnungen nennen «niemand erreichbar» oder fehlende Geburtsdaten. Der frühere Block «Personen-Felder gemäss Spalten-Zuordnung» (PersonFieldMapping) ist aus der Maske weg; die Regeln wirken weiter in der Projektion der Mitgliederliste und im Verdrahtungs-Canvas («Erweitert»).
Technik: POST /api/org/members/create/ nimmt neu {form, designation, blocks: {p1, c1, c2, h1…, contact}, member} (alter Body mit nur display_name bleibt gültig), GET /api/org/persons/suggest/; Komponente static/js/cluhu-member-create.js (<cluhu-member-create>), Partial templates/organization/_member_create.html; alles in einer Transaktion, E-Mail je Verein eindeutig (400 nennt die Person), dieselben Regeln wie der Import-Motor. Tests apps/organization/tests_etappe4_maske.py.
Warum so: Die Form ist eine Obergrenze je Zeile und je Maske (D1); der Canvas war für E und V ein Umweg mit positionalen Slots. Vorschlag statt Zusammenführen, weil eine Familien-Mailbox zwei Personen gehören kann, aber nur eine sie als Adresse trägt.