Person ist die Lead-Tabelle für die Personen-Identität (Name, Geburtsdatum, Login) — im Gegensatz zum Member, das nur das Vertragsverhältnis trägt. Warum getrennt: Vorname/Adresse/Telefon sind personenbezogen, nicht mitgliedschaftsspezifisch (Person-Lead-Architektur, v0.14.60).
| Feld | Bedeutung |
|---|---|
display_name |
abgeleitetes Label: automatisch aus „Vorname Nachname" gepflegt (in save()). Nur mit display_name_override bleibt ein manueller Wert (Spitzname/Mononym) stehen. Fallback-Kette: Name → E-Mail-Local-Part |
person_number |
Anzeige-Nummer pro Verein, auto ab 0, UI-Format 5-stellig. 00000 = die zuerst angelegte Person (bei neuen Vereinen der Owner). Nicht editierbar. Auto-Vergabe mit Retry gegen Race-Conditions |
user |
OneToOne zu Django-User, NULL = Person ohne Login |
source |
import / manual / addon_wizard — steuert das Herkunfts-Tag in der Liste und was member_reset_all löschen darf |
Adresse, Telefon und E-Mail sind eigene Entitäten mit Links, keine Textfelder:
Address — M:N via LinkAddressPerson: eine Familienadresse ist ein Datensatz mit n Links (echtes Sharing statt String-Kopien)PhoneNumber — M:N via LinkPhoneNumberPerson (Familien-Festnetz teilbar). CH-Klassifikation: 075–079 = mobil (persönlich), Rest = Festnetz (teilbar) — steuert Sharing-DefaultsEmailAddress — bewusst 1:N (jede E-Mail gehört genau einer Person). Eine E-Mail nur EINMAL pro Verein, case-insensitiv erzwungen per DB-Constraint (club, Lower(email)). Grund: E-Mail = Login-Identität. save() normalisiert (trim + lowercase)Seit v0.18.5 gilt: Die Personen-E-Mail ist die einzige Wahrheit. Der Django-User spiegelt sie nur. Bei E-Mail-Änderung einer Login-Person wird User.username/email mitgezogen (mit blockierendem Bestätigungs-Dialog + Passwort-Reset-Mail an die neue Adresse).
Es gibt keine member-owned Kontakte und keine automatische Vererbung (Rückbau v0.16.77) — Teilen ist immer explizite Verdrahtung. Details: Design-Entscheidungen.
/clucore/personen/)Gleiche CluhuTable wie die Mitgliederliste, plus:
/clucore/personen/?ansicht=felder (v0.28.178). Je Feld steht dort der Block «Beim Anlegen» (Modus und Vorgabewert), beschrieben auf Mitglieder, Abschnitt «Custom-Felder»has_login-Filter; Login-Personen ohne EmailAddress zeigen die Login-Mail als E-Mail-WertDie Personenliste hat die Spalten «Eintritt» und «Austritt». Beide lassen sich sortieren, über den Trichter als Datumsbereich filtern und exportieren.
Warum so: Eintritt und Austritt gehören seit v0.28.126 zur Person in einer Mitgliedschaft (LinkMemberPerson.valid_from / valid_to), nicht zur Person allein. Die Liste zeigt darum eine Zusammenfassung und schreibt beim Bearbeiten immer genau eine Verbindung. Bei einer Verbindung ist klar, welche gemeint ist, also geht es direkt. Bei mehreren fragt das Fenster nicht «welche?», sondern zeigt alle.
Warum nicht anders: Ein eigenes Datumsfeld an der Person hätte eine zweite Wahrheit neben dem Link geschaffen (Wiedereintritt, zwei Mitgliedschaften mit verschiedenen Daten). Ein Datum, das beim Ändern alle Verbindungen überschreibt, hätte genau diese Unterschiede gelöscht. Eine Spalte je Mitgliedschaft hätte die Liste breit gemacht für den seltenen Fall.
Technik: services.person_entry_annotations() (Sortierung, Filter), person_entry_links(), person_entry_summary(); person_update nimmt entry_date / exit_date nur bei genau einer Verbindung an; das Fenster speichert über /api/org/links/member-person/<id>/update/. Mehr zu Eintritt und Austritt am Link: Mitgliedschaften.
/clucore/rollen/)Role/LinkRole/RoleContext: fachliche Vereinsrollen, polymorph zuweisbar (Person/Firma) mit optionalem Kontext (z. B. „Leitung" im Kontext Gruppe X). Rollennamen dürfen keine Kommas/Klammern enthalten — das ist Anzeige-Syntax des Herkunftsmodells.
Hinweis: „Vereins-Rollen" war früher ein eigenes Addon (vereins-rollen), wurde aber dem Bereich Personen zugeschlagen. Rollen an Mitgliedschaften wurden abgeschafft (v0.16.95) — LinkRole mit object_type='member' ist serverseitig geblockt.
/clucore/personen/duplikate/)Namensbasierte Paar-Erkennung (first+last oder display_name, case-insensitiv). Merge biegt alle Links (Member, Company, Group, Role) auf die behaltene Person um.
Nur lebende Personen (v0.28.177): Gelöschte Personen und gelöschte Mitgliedschaften zählen weder im Banner der Personenliste noch auf der Seite. Warum: Löschen setzt in CluHu nur archived_at, und Person.objects liefert solche Zeilen weiter mit. Nach einem zweiten Import in denselben Verein fand darum jede neue Person ihr gelöschtes Gegenstück aus dem früheren Import: «109 mögliche Duplikate» bei 69 neuen Personen, innerhalb des neuen Imports gab es kein einziges Paar. Zwei Zahlen: Das ToDo «mögliche Dubletten» unter «Import nachbearbeiten» nutzt dieselbe Namenslogik, zählt aber strenger (nur verschiedene Mitgliedschaften, gleiche oder fehlende Adresse). Banner und ToDo können darum verschiedene Zahlen zeigen.
⚠️ Läuft O(n²) bei jedem GET der Seite — bei >1000 Personen pro Verein braucht es eine Optimierung.
person_delete_all verlangt die exakte Texteingabe „ALLES LÖSCHEN". Login-Personen werden immer geschont — sonst sperrt sich der Admin selbst aus (die Tenant-Middleware prüft user.person.club_id; AuthRoleAssignment hat CASCADE auf Person).
Eine Person kann zwei Bilder haben, mit zwei Eigentümern. Das Vereinsfoto gehört dem Verein: Pflege in CluCore über die Bildspalte der Personen- und Mitgliederliste (Mini-Editor mit Archiv älterer Aufnahmen, «aktuell», Freigabe «Für die Webseite»), Massenimport über Personenliste › Aktionen › «Vereinsfotos importieren» (Zuordnung per Dateiname: Personen-Nr. oder Vor- und Nachname, sonst Handauswahl). Nur freigegebene Vereinsfotos erscheinen im Bild-Picker des Webseiten-Builders; der Entzug wirkt sofort.
Das Profilbild wählt nur die Person selbst im Portal unter «Meine Daten» (Hochladen, Vereinsfoto übernehmen, Entfernen); es sehen alle angemeldeten Mitglieder, und es erscheint öffentlich bei Beiträgen, die die Person selbst schreibt. Der Schalter «auch öffentlich» wurde in v0.28.54 entfernt: Wer das nicht will, setzt kein Profilbild. CluCore darf Profilbilder löschen (Moderation), aber nicht setzen; der Vorstand darf ein Profilbild nicht als Vereinsfoto übernehmen, umgekehrt schon.
Warum zwei Bilder: Der Verein braucht ein Erkennungsbild mit Historie, die Person ein Bild, das sie selbst verantwortet; ein Feld hätte beides vermischt. Warum kein Datei-Browser: dort hängen Rechte an Ordnern, hier an Personen. Anzeige-Regel: Portal, Header und Teilnehmende zeigen Profilbild → Vereinsfoto → Initialen, CluCore-Listen umgekehrt. Mit Blick auf viele Vereine werden nur 512 px und 96 px gespeichert (kein Original), Adressen tragen eine Marke mit Jahres-Cache, Anzeigen braucht keinen Dateizugriff. Offen: Zuschneiden im Browser, Kalender-Auswertung in CluCore ohne Bild.