Zum Hauptinhalt springen

Visitenkarten (BusinessCards)

Zweck

BusinessCard ist die digitale Visitenkarte eines Mitarbeiters oder eines Kontakts. Pro Karte gibt es:

  • einen eigenen Slug mit Public-URL /c/{slug} — funktioniert ohne SpeamCore-Login
  • Override-Felder für Anzeige (Titel, Telefonnummern, Mail, Social-Links, Farbe)
  • einen vCard-Export (3.0 oder 4.0), z. B. zum Direkt-Speichern im Smartphone
  • ein anonymes Tracking für Page-Views und vCard-Downloads
  • optional die Verknüpfung als Ziel eines QR-Links (Aufkleber → BC statt externer URL)

Pro Mitarbeiter oder Kontakt eine Visitenkarte (1:1 pro Mandant).

Voraussetzungen

- Berechtigung `view:FE_BusinessCard`, `view:BusinessCard`. - Für Anlage/Update/Löschung: `create`/`update`/`delete:BusinessCard`. - Mindestens ein [Mitarbeiter](/employees) oder [Kontakt](/contacts) als Parent. - Optional: ein [Mail-Konto](/mail-accounts) für die Mailbox-Verknüpfung, ein Profilbild-Dokument, gepflegte [Social-Link-Policy](/customization/general).

Berechtigungen (CASL)

ActionSubjectWirkung
viewFE_BusinessCard, BusinessCardListe + Editor aufrufbar
createBusinessCardNeue Karte anlegen (Slug auto-gen)
updateBusinessCardFelder ändern (Slug ist nach Anlage unveränderbar)
deleteBusinessCardSoft-Delete — Events bleiben für Statistik erhalten, Public-Resolve liefert 404
viewEmployee / ContactParent-Auswahl
viewMailboxMailbox-Override

Datenmodell

BusinessCard

FeldPflichtTypWirkung
slugauto bei CreateString 3–64, regex ^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$URL-Teil hinter /c/. Tenant-eindeutig. Unveränderbar nach Anlage.
parentTypejaENUM (Employee | Contact)Polymorphe Bindung an einen Mitarbeiter oder Kontakt.
parentIdjaUUIDMitarbeiter-/Kontakt-ID.
activejaBoolean, default truefalse/c/:slug liefert 404.
displayTitleneinString 255Titel-Zeile auf der Karte. Fallback: EmployeeContract.jobTitle.
displaySubtitleneinString 255Zweite Zeile (z. B. Niederlassung).
phoneWork, phoneMobileneinString 64Override gegenüber Mitarbeiter-Attributen.
emailOverrideneinString 255Fallback: Mailbox.emailAddress oder Employee.email.
website, linkedinUrl, xingUrl, instagramUrlneinString 255Social-Media-Links. Fallback: Social-Link-Policy.
themeColorneinHex-StringAkzent-Farbe der Karte. Fallback: UiConfig.primaryColor.
mailboxIdneinUUID → MailboxOptional: spezifisches Postfach für die Kontakt-Mail (statt Employee.email).
showAbsenceStatusneinBoolean, default trueZeigt einen dezenten Hinweis, wenn der Mitarbeiter aktuell in einer genehmigten Abwesenheit ist.
showPoweredByneinBoolean, default true„powered by SpeamCore"-Footer ein-/ausblenden.

BusinessCardEvent

Append-only Event-Log (kein Soft-Delete):

FeldWirkung
kindENUM impression (Page-View) | exchange (vCard-Download).
occurredAtZeitstempel.
vcardVersion3 oder 4 — nur bei kind = exchange.
userAgent, uaFamily, osFamily, deviceTypeTelemetrie aus dem Browser.
countryCodeISO-2 aus Cloudflare-Header.

Schritt-für-Schritt-Anleitung

Visitenkarte anlegen

  1. Visitenkarten (/business-cards) → + Hinzufügen.
  2. SpeamCore generiert einen 8–10 Zeichen langen Slug (z. B. kvj8m21h) — vor dem Speichern überschreibbar, danach fix.
  3. Parent wählen: Mitarbeiter oder Kontakt.
  4. Override-Felder pflegen (Titel, Telefon, Mail, Socials, Farbe) — leer lassen, wenn Fallback aus Mitarbeiter-Daten reicht.
  5. Active = true setzen, sobald die Karte veröffentlicht werden soll.

Initial-Backfill (Welle 137): Beim ersten Aktivieren des Moduls auf einem bestehenden Mandanten erzeugt die Migration 20260520200001-backfill-employee-business-cards.js pro Mitarbeiter eine inactive Karte. Aktivierung geschieht manuell oder per Bulk-Update.

Style + Mandanten-Branding

Pro Karte können Sie:

  • die themeColor als Akzent setzen (z. B. die Firmenfarbe einer Branch),
  • ein eigenes Document als Hintergrund hochladen (über die Customization),
  • showPoweredBy deaktivieren (für reine White-Label-Cards).

Falls die Felder leer bleiben, greifen die mandantenweiten Default-Werte aus UiConfig.

vCard-Export

Die Public-Seite bietet zwei Format-Buttons:

  • vCard 3.0 — kompatibel mit älteren iOS-/Android-Versionen
  • vCard 4.0 — moderner Standard

Beide laden eine .vcf-Datei herunter, die der Empfänger direkt in sein Adressbuch importieren kann. Jeder Download wird als BusinessCardEvent mit kind = exchange getrackt.

Statistik-Tab

/business-cards/:id/stats zeigt analog zur QR-Link-Stats-Page:

KPIBerechnung
ImpressionsCOUNT(kind = 'impression') — Page-Views
vCard-DownloadsCOUNT(kind = 'exchange') — echte „Adressbuch-Aufnahme"
By Country / UA / Deviceanalog zum QR-Link-Tracking
TagesverlaufImpressions + Downloads pro Tag

Ein QR-Link kann statt einer externen URL eine Visitenkarte als Ziel haben:

QrLink {
targetType: "businessCard",
targetBusinessCardId: <UUID>,
targetUrl: null
}

Beim Scan resolvet SpeamCore die BC-Slug, leitet auf /c/:slug weiter und forciert intern den anonymen Tracking-Modus (kein Bestätigungs-Screen, keine Confirmed-Stufe). Die Impressions werden im BusinessCardEvent geloggt, nicht im QrLinkScan — die Statistik liegt also bei der Visitenkarte, nicht beim QR-Link.

Verhalten:

BC-StatusQR-Scan-Ergebnis
active = trueRedirect auf /c/:slug, Event geloggt
active = false oder gelöscht404

Anwendungsfall: Druck-Aufkleber an Servicewagen oder Anlagen-Kästen → QR scannt → direkt zur Visitenkarte des zuständigen Außendienstlers (statt zu einer Marketing-URL).

Resolver-Hierarchie

Die Public-Sicht /c/:slug merged Daten aus zehn Quellen, jeweils mit Fallback:

displayTitle → BusinessCard.displayTitle
→ EmployeeContract.jobTitle
→ leer

email → BusinessCard.emailOverride
→ Mailbox.emailAddress
→ Employee.email

socials → BusinessCard.linkedinUrl/xingUrl/instagramUrl
→ SocialLink (Mitarbeiter)
→ SocialLink (Tenant-Fallback aus SocialLinkPolicy)

themeColor → BusinessCard.themeColor
→ UiConfig.primaryColor

absenceStatus → aktuelle genehmigte Absence (nur wenn showAbsenceStatus=true)
→ kein Hinweis

calendarPage → CalendarPage des Mitarbeiters (nur Employee, Welle 138)
→ kein Buchungs-Button

photo → Employee.profileImageDocument
→ kein Foto

Public-Page-Shell (Welle 137)

Visitenkarten und QR-Links nutzen seit Welle 137 ein gemeinsames PublicPageShell-Layout:

  • Mandanten-Logo + Branding-Farben aus UiConfig
  • Footer links: Firmen-Stammdaten (Name, Adresse, Telefon)
  • Footer rechts: Legal-Links (Impressum, Datenschutz, AGB) aus LegalDocument
  • Optional Background-Image und Overlay

Damit sehen alle Public-Pages (Visitenkarten, QR-Code-Landing, später auch Buchungsseite und Zertifikat-Verifizierung) einheitlich aus.

Tracking-Modell

Analog zum QR-Link-Tracking:

  • impression — anonymer Page-View. Keine IP-Speicherung, neue UUID pro Aufruf.
  • exchange — echte Conversion (vCard heruntergeladen). Wird mit Browser-/Device-/Geo-Metadaten, aber ohne Klartext-IP geloggt.

Append-only — Soft-Delete einer Karte entfernt die Events nicht, damit historische Auswertungen erhalten bleiben.

API/Schnittstellen

Authentifiziert

MethodeEndpointZweckCASL
GET/api/business-cardsListe, paginiert + filterbarview BusinessCard
POST/api/business-cardsAnlegen (Slug auto-gen)create BusinessCard
GET/api/business-cards/:idDetail (Roh-Felder)view BusinessCard
GET/api/business-cards/:id/resolvedMerged-Sicht — auch wenn active=falseview BusinessCard
GET/api/business-cards/:id/stats?from=&to=Event-Statistikview BusinessCard
PATCH/api/business-cards/:idUpdate — Slug bleibt fixupdate BusinessCard
DELETE/api/business-cards/:idSoft-Deletedelete BusinessCard

Public (keine Auth)

MethodeEndpointZweck
GET/api/c/:slugResolved-Payload (nur active = true)
GET/api/c/:slug/vcard?v=3|4vCard-Download (.vcf)
POST/api/c/:slug/impressionAnonyme Page-View-Erfassung
GET/api/c/:slug/photoProfilbild-Stream (auch bei active=false; Slug ist das Token)

Social-Media-Settings auf Tenant-Ebene (Welle 142)

In den Mandanten-Einstellungen unter Settings → Social Media (/settings/social-media) lassen sich die für Visitenkarten erlaubten Plattformen zentral steuern:

  • Whitelist: Welche der 10 unterstützten Plattformen darf ein Mitarbeiter auf seiner BC pflegen — LinkedIn, Xing, Instagram, Facebook, X, GitHub, YouTube, TikTok, Threads, Bluesky.
  • Unternehmens-Defaults pro Plattform mit drei Modi:
    • Force (rot) — der Unternehmens-Link wird immer angezeigt, Mitarbeiter-Eintrag wird ignoriert
    • Fallback (blau) — wird nur gerendert, wenn der Mitarbeiter selbst keinen Link gepflegt hat
    • Hidden — Plattform ist deaktiviert, taucht auf keiner BC auf

Damit lässt sich ein einheitliches Corporate-Profil (z. B. „LinkedIn → immer Firmen-Page, Instagram → erlaubt aber kein Default") mandantenweit durchsetzen.

Verknüpfungen zu anderen Modulen

Häufige Fehler und Lösungen

FehlerLösung
/c/:slug zeigt 404active = false, Karte gelöscht oder Slug-Tippfehler. Im Editor reaktivieren oder neuen Slug nutzen.
Telefonnummer fehlt obwohl im Mitarbeiter gepflegtOverride-Feld phoneWork/phoneMobile ist leer und das Mitarbeiter-Attribut phone ist nicht auf „public" gesetzt. Im Mitarbeiter-Detail prüfen.
Profilbild fehltEmployee.profileImageDocument ist nicht gepflegt — Document im Dokumenten-Modul hochladen und als Profilbild markieren.
Slug-Eingabe ist disabledSlug ist nach dem Speichern unveränderbar (Datenschutz: gedruckte Aufkleber sollen stabil bleiben). Neue Karte anlegen, alte deaktivieren.
QR-Code zeigt 404, obwohl Visitenkarte existiertBusinessCard.active = false oder Soft-Delete — QR-Resolver lehnt inaktive BCs ab.
vCard sieht im iPhone-Adressbuch falsch aus?v=4 (vCard 4.0) hat strengere Felder. ?v=3 (3.0) ist toleranter bei Sonderzeichen.
Mehrere Visitenkarten pro MitarbeiterNicht erlaubt — 1:1 pro parentType + parentId (Index uq_business_cards_parent_deletedAt).

Versionshinweise

  • 2026-05-21 (Welle 137): Initiale Veröffentlichung. Quelle: BE-Commit 179f8adc (3 neue Models, 7 Auth-Endpoints, 4 Public-Endpoints, 6 Migrationen) + FE-Commit 6430804b (BusinessCardEditor, BusinessCardStatsPanel, BusinessCardPublicPage, PublicPageShell als Shared Layout). Migration 20260520200001-backfill-employee-business-cards.js legt pro Mitarbeiter eine inaktive Karte an. QR-Link um Ziel-Typ businessCard erweitert — Scans auf eine BC-Card werden anonym getrackt (kein Bestätigungs-Screen) und im BusinessCardEvent geloggt.
  • 2026-05-21 (Welle 142): Neue Social-Media-Settings-Seite (/settings/social-media) auf Tenant-Ebene — Whitelist der 10 Plattformen plus Force/Fallback/Hidden-Modi pro Plattform. Bestimmt, welche Links auf der BC erscheinen.