Skip to content

Kontakte ⊕ Personalbüro — Verschmelzung der Portal-Funktionen

Ausgangslage

Das alte Portal prilog-portal hat ein ausgereiftes "Personalbüro" (/users/accounts/office/) das den Schulalltag gut bedient:

  • Fristensteuerung — abgelaufene Konten erkennen + verlängern/deaktivieren
  • Bereinigungsvorschläge — Karteileichen mit Space-Zuordnungen
  • CSV-Bulk-Import mit reichem Schema (username, fullName, birthDate, email, phone, street, postalCode, city, country, expiresAt, isPermanent, password, admin)
  • Quick-Actions für Admins: +3 Mon / +6 Mon / +1 Jahr verlängern, deaktivieren
  • Einladungs-Links per Email
  • UserType-Manager (Lehrer/Schüler/Eltern/Sekretariat …)
  • Passwort-Reset durch Admin

Im Web-Client haben wir Settings → Workspace → Mitglieder, das wesentlich ist aber die Personalbüro-Logik (Fristen, Bulk-Import, Quick-Actions) fehlt noch. Gleichzeitig haben wir die neue Kontakte-CRM-App.

Problem: Der CRM-Hub und das Mitglieder-Settings sind getrennt — der Sekretariats-Mitarbeiter wechselt zwischen zwei Orten. Der Portal-Office-View war ein Single-Pane-Of-Glass.

Ziel

Eine "Kontakte"-Welt im Web-Client vereint:

  1. CRM (externe Kontakte) — schon live
  2. Mitglieder-Verzeichnis — schon live (vereinheitlicht)
  3. Personalbüro-Funktionen — noch zu migrieren
  4. Activity-Verlauf auch für Mitglieder (aus dem CRM-Modell, polymorph)

Sodass das Sekretariat alles an einem Ort macht: anlegen, importieren, verlängern, suchen, kontaktieren.


Was migriert werden soll

Block 1 — Fristen + Karteileichen (MVP)

  • Filter-Chip "Läuft bald ab" — Mitglieder mit expiresAt < now+30d
  • Filter-Chip "Abgelaufen aktiv"expiresAt < now AND active
  • Filter-Chip "Ohne Space" — keine Membership
  • Quick-Action im Detail-Pane (Admin only): Verlängern-Dropdown (+3 Mon / +6 Mon / +1 Jahr / 31.07. nächstes Jahr) — letzte Option ist deutscher Schul-Standard
  • Bulk-Aktion "Abgelaufene deaktivieren" — Toolbar-Button im Office-Filter-Modus (Confirmation-Dialog)
  • Ablauf-Pill in der Liste — kleine Badge "läuft in 14 Tagen" oder "abgelaufen" auf Mitgliedern

Block 2 — Mitglieder-Bulk-Import (mit Auto-Anlage)

  • Bestehender CSV-Import-Wizard wird erweitert mit Toggle "Als Mitglied (mit Login) anlegen"
  • Header-Auto-Detect erweitert um: username, password, expiresAt, isPermanent, admin
  • UserType + Space-Pre-Selection (genau wie im Portal)
  • Bei Erstellung: UserDirectoryEntry + Matrix-User über Synapse-Admin-API + erste Membership
  • Validierung: Username-Konflikt-Check, E-Mail-Eindeutigkeit
  • Schul-typische CSV-Vorlagen (downloadbar): "Lehrkräfte", "Schüler einer Klasse", "Eltern" — als CSV mit Header und Beispielzeile
  • "Einladen"-Button im Create-Modal als Alternative zur Passwort-Eingabe
  • Nutzer kriegt Email mit magischem Link → setzt selbst Passwort
  • Im Portal vorhanden, im Web-Client kennen wir die Logik schon (siehe prilog-web-client/src/features/invite/)

Block 4 — Polymorphe Activities (Member-Verlauf)

  • ContactActivity bekommt optionalen userMatrixId-Verweis (alternativ zu contactId)
  • Verlauf-Tab funktioniert für Mitglieder genauso — manuelle Notizen, Telefonate, Treffen
  • Auto-Aktivitäten für admin-relevante Events:
    • "Konto angelegt von X"
    • "Konto verlängert um 12 Monate"
    • "Passwort zurückgesetzt"
    • "Deaktiviert"
  • Vorteil: das Sekretariat sieht wer wann was mit dem Konto gemacht hat — Audit + Workflow-Ablauf

Block 5 — Geburtstage-Widget

  • Sidebar-Card "Geburtstage diese Woche" mit Foto + Tag → Klick öffnet Detail
  • Spielt für Schul-Sekretariat eine zentrale Rolle ("Maria hat morgen!")
  • Aus birthDate und/oder birthYear aller Mitglieder + externer Kontakte

Block 6 — Smart-Office-Modi

Neuer Filter-Chip-Strang neben Alle/Mitglieder/Externe:

[Alle] [Mitglieder] [Externe]    [Geburtstage] [Läuft ab] [Karteileichen] [Ohne Space]

Klick auf einen Office-Filter zeigt die Liste passend gefiltert + spezifische Bulk-Aktionen oben in der Toolbar (z.B. "Alle markierten deaktivieren").

Block 7 — Passwort-Reset + Admin-Toggle

Im Detail-Pane für Mitglieder (Admin only):

  • Passwort zurücksetzen (Bestätigungsdialog mit kopierbarem temporärem Passwort)
  • Admin-Status toggeln (Bestätigung)
  • Konto deaktivieren / reaktivieren
  • Konto löschen mit DSGVO-Hinweis

Diese sind heute in Settings → Mitglieder, gehören aber zum Kontakt-Detail (man arbeitet mit dem Menschen, nicht mit der Sektion).


Datenmodell-Erweiterungen

UserDirectoryEntry — bereits vorhanden:

  • expiresAt, isPermanent, admin, birthDate, birthYear, phone, street, postalCode, city, country, source

Keine Migration nötig — Daten existieren schon, müssen nur in Hub kommen.

ContactActivity — Erweiterung (Block 4):

prisma
model ContactActivity {
  ...
  contactId       String?  // bestehend, jetzt optional
  userMatrixId    String?  // NEU — alternativ
  // Constraint: genau eines der beiden gefuellt
}

Migration 0061 — additiv, mit Constraint via CHECK.

MemberInvitation — bereits da (UserInvitation Tabelle), nur Frontend-Anbindung fehlt.


UI-Vision

┌─ Toolbar ─────────────────────────────────────────────────────────┐
│ 🔍 Suche...   [⬆ CSV-Import] [📥 vCard-Export] [+ Neu ▾]   ⚙️  ⛶ │
├─ Quellen-Filter ──────────────────────────────────────────────────┤
│ [Alle 245] [Mitglieder 187] [Externe 58]                          │
├─ Office-Filter ───────────────────────────────────────────────────┤
│ [🎂 Geburtstage 3] [⏰ Läuft ab 12] [💀 Karteileichen 4] [📭 Ohne Space 2] │
├─ Tag-Pills ───────────────────────────────────────────────────────┤
│ [Eltern] [Lehrer] [Schüler] [Behörde] ...                         │
├───────────────────────────────────────────────────────────────────┤
│ ┌─ Liste ─────────────────────┬─ Detail ─────────────────────────┐ │
│ │ 🟢 Maria Meyer (Lehrer)     │ 📷 Maria Meyer                   │ │
│ │    maria@schule.de       3d │    Lehrkraft Mathematik          │ │
│ │ 🟡 Klaus Schmidt   ⏰ 5T   │    [📞] [📧] [✉️ Einladen]        │ │
│ │    klaus@schule.de         │ ─────────────────────────────     │ │
│ │ 👤 Frau Müller  · Eltern   │ [Stammdaten | Verlauf | Verkn.]   │ │
│ │    +49 171 2345678         │                                   │ │
│ │                            │ Stammdaten:                       │ │
│ │                            │   📧 maria@schule.de              │ │
│ │                            │   📞 +49 171 ...                  │ │
│ │                            │   🏠 Musterstr. 1, 80000 ...      │ │
│ │                            │   🎂 14.05.1980                   │ │
│ │                            │   ⏰ Läuft ab am 31.07.2026       │ │
│ │                            │ Admin-Aktionen:                   │ │
│ │                            │   [+3 M] [+6 M] [+1 J] [Deakt.]   │ │
│ │                            │   [Passwort zurücksetzen]         │ │
└───────────────────────────────┴───────────────────────────────────┘

Sekretariats-Workflow (Beispiel):

  1. Klick "Geburtstage" → Liste der Personen mit Geburtstag in 7 Tagen
  2. Klick auf Maria → Detail mit Verlauf
  3. "Notiz" im Verlauf hinzufügen: "Geschenk besorgt"
  4. Klick "Läuft ab" → Klaus erscheint
  5. Klick "+1 Jahr" im Detail → Verlängert + Activity-Eintrag automatisch
  6. "CSV-Import" öffnen → Klassenliste 5b einlesen → 24 Schüler + 24 Eltern in einem Schwung

Phasenplan

PhaseInhaltAufwand
AOffice-Filter-Chips (Geburtstage / Läuft ab / Karteileichen / Ohne Space) — clientseitige Logik auf vorhandenen Daten~3h
BDetail-Pane Admin-Aktionen für Mitglieder (Verlängern / Deaktivieren / Passwort-Reset / Admin-Toggle)~4h
CPolymorphe ContactActivity (Migration 0061 + UI für Member-Verlauf)~3h
DCSV-Bulk-Import erweitert: Toggle "Als Mitglied anlegen" + Username/Password/expiresAt/admin Felder + Schul-Vorlagen-Downloads~5h
EEinladungs-Link statt Passwort + UI im Create-Modal~2h
FGeburtstage-Widget (Sidebar + Mobile-First-Card)~2h
GAuto-Activities für admin-relevante Events (Konto-Anlage, Verlängerung, Deaktivierung, Passwort-Reset)~2h

MVP = A+B+G (~9h, ein Tag) — löst die wichtigsten Personalbüro-Workflows + macht Verlauf für Mitglieder sichtbar. Ausbau = +C+D+E+F (~12h zusätzlich) — kompletter Office-Modus, Bulk-Anlage, Einladungs-Flow, Geburtstage.

Status 2026-05-07 ALLE PHASEN LIVE (A–G):

  • Migration 0061 (ContactActivity polymorph: contactId? + userMatrixId?)
  • Office-Filter-Chips: 🎂 Geburtstage / ⏰ Läuft ab / 💀 Karteileichen / 📭 Ohne Space
  • Status-Pills in der Liste (rot/gelb/blau)
  • Admin-Aktionen im Detail-Pane: Verlängern (+3M/+6M/+1J/31.07.), Aktivieren/Deaktivieren, Admin-Toggle, Passwort-Reset (mit Modal)
  • Verlauf-Tab für Mitglieder (manuelle Einträge + Auto-Activities)
  • Auto-Activity-Logging bei Admin-Aktionen für Audit-Trail
  • Phase D LIVE: CSV-Bulk-Import erweitert mit Toggle "Externe / Mitglieder", Schul-Vorlagen-Downloads (Lehrkräfte, Klasse, Eltern), member-spezifische Felder (username/password/expiresAt/admin), Backend /workspace/users/bulk-import
  • Phase E LIVE: InviteMemberModal mit Token-Link-Erstellung (14d gültig), kopierbarer Link, Backend /workspace/users/invite. "Neu"-Dropdown im Hub mit drei Optionen: Mitglied einladen / Externer Kontakt / CSV-Bulk-Import
  • Phase F LIVE: BirthdaysBox als Dashboard-Widget (Geburtstage 7d voraus, Mitglieder + Externe gemixt, Klick navigiert in den Kontakte-Hub)

"Spass mit Prilog" — Design-Prinzipien

  1. Ein Ort, eine Logik — Mitarbeiter denken nicht "wo ist das jetzt", sondern "ich klick im Kontakt"
  2. Aktion folgt Person — alle Operationen am Detail-Pane, nie verstreut über Settings
  3. Sichtbar bevor Klick — Ablauf-Pill in der Liste, nicht erst beim Öffnen
  4. Bulk ist ein Modus, kein Modal — Office-Filter aktiv → Liste hat Checkboxen + Sammel-Aktionen oben, raus aus dem Modus → wieder normal
  5. Keine Tabs für Modi — Filter-Chips, weil flexibler kombinierbar
  6. Konsistente Akzente — gelbe Pills für "Achtung" (Ablauf), rote für "kritisch" (abgelaufen+aktiv), grüne für Mitglied-Marker

Was wir NICHT migrieren

  • Tenant-weite User-Type-Verwaltung — bleibt in Settings (Konfiguration ist nicht Tagesgeschäft)
  • Server-Tier-Statistiken — bleibt in Settings → System
  • Space-Templates-Editor — bleibt in Spaces-Hub (gehört zum Space, nicht zum Mitglied)
  • Tenant-weite Health-Übersichten — bleibt im Admin-Portal (wenn überhaupt)

Offene Fragen

  1. Bulk-Anlage von Membern via CSV — sollen wir Matrix-Accounts wirklich automatisch erzeugen, oder nur "Einladungen" verschicken (Pull-Pattern)? — Empfehlung: Toggle im Wizard, Schule entscheidet.
  2. Office-Modi mit Selektions-Modus: brauchen wir Mehrfach-Selektion mit Checkboxen, oder reicht "alle Vorgeschlagene deaktivieren"-Bulk-Aktion? — Empfehlung: erst Bulk-Aktion, später Mehrfach-Selektion wenn gefordert.
  3. Geburtstag-Privacy: zeigen wir bei externer Person das Geburtsjahr per Default? — Empfehlung: nein, optional aktivierbar.
  4. Wann Einladung vs. Passwort: Standard-Pfad sollte einer sein. — Empfehlung: Einladungs-Link als Default (modern, sicher), Passwort als "Erweitert"-Toggle.