Datenstruktur-Register / Datenfelder

Öffentliche Schema-Referenz gemäß EU Data Act 2023/2854 Art. 26(b)

Dieses Register dokumentiert alle Datenfelder, die im Boncard-Kundenexport enthalten sind. Es wird gemäß Art. 26(b) Data Act vor Vertragsabschluss veröffentlicht, damit Kunden und Zielanbieter die Migration planen können. Die Export-Endpoints und Anleitungen finden Sie unter /data-portability.

1. Schema-Katalog

Alle Datenstrukturen, wie in der internen Schema-Truth-Datei src/lib/db/types.ts definiert. Jedes Feld mit Typ und Beschreibung.

Customer Customer (End-Kunde des Tenants)

FeldTypBeschreibung
idstringnanoid(16) primary key
barbershopIdstringTenant scope (foreign key to Barbershop.id)
firstNamestringCustomer first name (required)
lastNamestring?Customer last name (optional)
phonestring?Phone number, E.164 preferred (optional)
emailstring?Customer email address (optional)
birthdaystring?ISO date YYYY-MM-DD (optional)
notesstring?Free-text notes by owner/staff (optional)
gdprConsentbooleanArt. 6(1)(a) GDPR base consent
marketingConsentbooleanMarketing email consent (double opt-in)
birthdayConsentbooleanBirthday greeting consent (double opt-in)
marketingConsentConfirmedAtstring?ISO timestamp of marketing double opt-in
birthdayConsentConfirmedAtstring?ISO timestamp of birthday double opt-in
unsubscribeTokenstring?OMITTED from export (live credential)
lastMarketingEmailAtstring?ISO timestamp of last marketing email sent
lastBirthdayEmailAtstring?ISO timestamp of last birthday email sent
consentGivenAtstring?ISO timestamp when consent was given
consentSourceenum?CARD_ACTIVATION_FORM | ADMIN_MANUAL_ENTRY | IMPORT | PUBLIC_WEB_FORM
consentIpAddressstring?IP address captured at consent (Art. 7(1) proof)
consentUserAgentstring?User agent captured at consent
isAnonymizedbooleanTrue if personal data has been erased (Art. 17)
createdAtstringISO timestamp record created
updatedAtstringISO timestamp record last updated

Card Card (Bonuskarte)

FeldTypBeschreibung
idstringnanoid(16) primary key
barbershopIdstringTenant scope
customerIdstring?Owner of the card (optional until activation)
cardCodestringUnique card code printed on the physical card
statusenumNOT_ACTIVATED | ACTIVE | BLOCKED | LOST | EXPIRED
pointsBalancenumberCurrent points balance
totalPointsEarnednumberLifetime points earned
totalPointsRedeemednumberLifetime points redeemed
activatedAtstring?ISO timestamp of activation
blockedAtstring?ISO timestamp the card was blocked
expiresAtstring?ISO timestamp the card expires
replacedByCardIdstring?If replaced, points to the new card.id
createdAtstringISO timestamp record created
updatedAtstringISO timestamp record last updated

Transaction Transaction (Punkte-Transaktion)

FeldTypBeschreibung
idstringnanoid(16) primary key
barbershopIdstringTenant scope
cardIdstringCard the points moved on
customerIdstring?Customer reference (denormalized for queries)
userIdstring?Staff/owner who performed the action
typeenumEARN | REDEEM | MANUAL_ADJUSTMENT | EXPIRE | CANCEL
pointsnumberSigned points delta (positive = earn, negative = redeem)
balanceBeforenumberCard balance before this transaction
balanceAfternumberCard balance after this transaction
amountEuronumber?Euro amount of the underlying purchase (service price, when earned via a catalogue service)
reasonstringHuman-readable reason (service name, manual reason, etc.)
rewardIdstring?Reward reference when type=REDEEM
metadataobject?Arbitrary key-value metadata for future fields
createdAtstringISO timestamp of the transaction

Service Service (Dienstleistung)

FeldTypBeschreibung
idstringnanoid(16) primary key
barbershopIdstringTenant scope
categoryIdstringForeign key to ServiceCategory.id
namestringService name as shown to staff
descriptionstring?Service description (optional)
priceEurnumberBase price in EUR
pointsAwardnumberPoints granted when this service is delivered
durationMinnumber?Approximate duration in minutes (optional)
sortIndexnumberDisplay ordering within category
activebooleanTrue if currently bookable / shown to staff
createdAtstringISO timestamp record created
updatedAtstringISO timestamp record last updated

ServiceCategory ServiceCategory (Leistungskategorie)

FeldTypBeschreibung
idstringnanoid(16) primary key
barbershopIdstringTenant scope
namestringCategory name as shown to staff
colorstring?Hex accent colour for the UI (optional)
sortIndexnumberDisplay ordering of the category
activebooleanTrue if currently shown to staff
createdAtstringISO timestamp record created
updatedAtstringISO timestamp record last updated

Reward Reward (Prämie)

FeldTypBeschreibung
idstringnanoid(16) primary key
barbershopIdstringTenant scope
categoryIdstring?Optional reward category reference
titlestringReward title shown to customers
descriptionstring?Reward description (optional)
pointsCostnumberPoints required to redeem this reward
typeenumDISCOUNT | FREE_SERVICE | GIFT | CUSTOM
discountAmountnumber?Fixed discount in EUR for DISCOUNT type
discountPercentnumber?Percentage discount for DISCOUNT type
activebooleanTrue if currently available for redemption
validFromstring?ISO date — reward available from this date
validUntilstring?ISO date — reward available until this date
maxRedemptionsnumber?Hard cap on total redemptions (optional)
iconNamestring?Curated lucide-react icon key
createdAtstringISO timestamp record created
updatedAtstringISO timestamp record last updated

Redemption Redemption (Prämien-Einlösung)

FeldTypBeschreibung
idstringnanoid(16) primary key
barbershopIdstringTenant scope
rewardIdstringReward that was redeemed
cardIdstringCard the points came off
customerIdstringCustomer who redeemed
userIdstring?Staff/owner who confirmed the redemption
pointsSpentnumberPoints debited for this redemption
statusenumCOMPLETED | CANCELLED
cancelledAtstring?ISO timestamp if status=CANCELLED
createdAtstringISO timestamp of the redemption

Coupon Coupon (Gutschein-Aktion)

FeldTypBeschreibung
idstringnanoid(16) primary key
barbershopIdstringTenant scope
titlestringCoupon title shown to staff and customer
descriptionstring?Coupon description (optional)
kindenumBONUS_POINTS | DISCOUNT_NOTE
bonusPointsnumber?Points credited for kind=BONUS_POINTS
discountLabelstring?Free-text discount note for kind=DISCOUNT_NOTE
validFromstring?ISO date — coupon valid from
validUntilstring?ISO date — coupon valid until
maxRedemptionsnumber?Hard cap on total redemptions (optional)
perCustomerLimitnumberHow often one customer may use it
activebooleanTrue if currently applicable
createdBystringUser id that created the coupon
createdAtstringISO timestamp record created
updatedAtstringISO timestamp record last updated

CouponRedemption CouponRedemption (Gutschein-Einlösung)

FeldTypBeschreibung
idstringnanoid(16) primary key
barbershopIdstringTenant scope
couponIdstringCoupon that was applied
cardIdstringCard the coupon was applied to
customerIdstring?Customer holding the card (optional)
userIdstringCashier (User id) who applied it
pointsAwardednumberPoints credited (0 for DISCOUNT_NOTE)
createdAtstringISO timestamp of the redemption

Barbershop Barbershop (Tenant / Geschäftseinheit)

FeldTypBeschreibung
idstringnanoid(16) primary key
namestringBusiness display name
legalNamestring?Full legal company name (optional)
ownerNamestring?Contact person (optional)
addressstringStreet and house number
postalCodestringPostal code
citystringCity
countrystringISO country code, default DE
phonestringBusiness phone number
emailstringBusiness contact email
websitestring?Business website URL (optional)
logoUrlstring?Logo image URL (R2/CDN)
primaryColorstring?Brand color in hex (default #C9A04A)
currencystringISO 4217 currency code (default EUR)
timezonestringIANA timezone (default Europe/Berlin)
programRulesstring?Public program rules / terms of participation
birthdayMessagestring?Birthday greeting email body
statusenumACTIVE | SUSPENDED | ARCHIVED | SCHEDULED_FOR_DELETION
cardDesignobject?Two-sided card design (front + back + QR placement)
betaSignupboolean?True if the business signed up during the beta (AGB §3a customer floor)
planIdenum?free | starter | pro | business | enterprise (undefined = free)
limitOverridesobject?Per-tenant plan limit overrides
businessHoursarray?Weekly opening hours per weekday
instagramUrlstring?Instagram profile URL
facebookUrlstring?Facebook profile URL
googleMapsUrlstring?Google Maps profile URL
descriptionDestring?Public profile description (German, max 800 chars)
descriptionEnstring?Public profile description (English, max 800 chars)
descriptionUkstring?Public profile description (Ukrainian, max 800 chars)
descriptionRustring?Public profile description (Russian, max 800 chars)
emailSignaturestring?Appended to outgoing marketing/birthday emails (max 500 chars)
autoAnonymizeMonthsnumber?GDPR Art. 5 retention threshold in months (0 = disabled)
autoAnonymizeNotifyDaysstring?Comma-separated days before anonymize (e.g. '30,14,7')
customGdprConsentDestring?Per-tenant override of GDPR consent text (German)
customGdprConsentEnstring?Per-tenant override of GDPR consent text (English)
customGdprConsentUkstring?Per-tenant override of GDPR consent text (Ukrainian)
customGdprConsentRustring?Per-tenant override of GDPR consent text (Russian)
avvAcceptedAtstring?ISO timestamp of AVV (DPA) acceptance
avvAcceptedIpstring?IP address captured at AVV acceptance
avvAcceptedUserAgentstring?User agent captured at AVV acceptance
avvVersionstring?Version of AVV accepted
policyAcceptancesarray?Append-only log of AVV/AUP/AGB/Widerruf/data-act-switching acceptances
createdAtstringISO timestamp record created
updatedAtstringISO timestamp record last updated

2. Export-Formate

Alle Exporte werden als JSON gemäß RFC 8259, UTF-8-kodiert, mit 2-Leerzeichen-Einrückung ausgegeben. Schema-Versionen: boncard.tenant.v1 (Tenant-Export, gesamtes Geschäft) und boncard.customer.v1 (End-Kunden-Export, Einzeldaten). Datumsfelder sind ISO-8601-Strings; optionale Felder sind weggelassen statt null.

3. Interoperabilität

Punkte-Berechnungslogik: Punkte werden über den Leistungskatalog vergeben — jede Leistung definiert einen festen pointsAward, der beim Erfassen durch das Personal gutgeschrieben wird; manuelle Korrekturen (mit dokumentiertem Grund) sind möglich. AVV-Pflichten: Vor Vertragsabschluss wird ein elektronischer Auftragsverarbeitungsvertrag (Art. 28 DSGVO) abgeschlossen; alle Personaldaten werden bcrypt-gehasht, Audit-Logs 90 Tage gespeichert. Aufbewahrungsfristen: Marketing-E-Mail-Events 90 Tage, Transaktionale 1 Jahr, Legal-Notices 3 Jahre; Einwilligungs-Logs 3 Jahre nach Widerruf; Löschprotokolle 3 Jahre.

Internationaler Zugriff & IKT-Infrastruktur (Art. 28(1) Data Act)

Gemäß Art. 28(1) Verordnung (EU) 2023/2854 (Data Act) legt Boncard offen, in welcher Jurisdiktion die für den Dienst eingesetzte IKT-Infrastruktur betrieben wird (lit. a) und welche Maßnahmen gegen rechtswidrigen behördlichen Zugriff aus Drittländern auf nicht-personenbezogene Daten bestehen (lit. b).

(a) Jurisdiktion der IKT-Infrastruktur

(b) Maßnahmen gegen rechtswidrigen behördlichen Drittlandszugriff auf nicht-personenbezogene Daten

Diese Angaben erfüllen Art. 28(1)(a)/(b) Data Act. Die jeweils aktuelle Subprozessoren-Liste: /subprocessors.

4. Versionierungs-Richtlinie

Schema-Bumps sind entweder rückwärtskompatibel (zusätzliche optionale Felder) oder werden mit 90 Tagen Vorlauf angekündigt. Änderungen werden den aktiven Tenants per LEGAL_NOTICE-E-Mail mitgeteilt. Die aktuelle Schema-Version steht in jeder Export-Datei im Feld schemaVersion.

5. Kontakt und zuständige Behörden

Technische Fragen zu Schema und Export: support@boncard.app. Zuständige Behörde gemäß Art. 37(1)(a) Data Act: Bundesnetzagentur (BNetzA), Tulpenfeld 4, 53113 Bonn, https://www.bundesnetzagentur.de. Datenschutz-Aufsicht: Landesbeauftragte für Datenschutz und Informationsfreiheit NRW (LDI NRW), https://www.ldi.nrw.de.

Datenportabilität (Art. 20 / EU Data Act) · Auftragsverarbeitungsvertrag (AVV) · Datenschutzerklärung · Sub-Auftragsverarbeiter