Felles Kundetabell¶
Denne siden beskriver anbefalt og delvis implementert struktur for felles kunderegister i golfbilappen.
Formål¶
Kunderegisteret skal være felles på tvers av tenants, men fortsatt støtte lokale klubbfordeler. En kunde skal kunne booke i flere klubber med samme identitet, mens rabatt, klippekort, års-/månedskort og legeattest kan være lokal per klubb.
Dagens Firestore collection heter:
members
Logisk bør den behandles som:
customers
Et senere rename eller alias kan vurderes, men dagens kode bruker members.
Dokument-ID¶
Stabil ID bygges i prioritert rekkefølge:
| Prioritet | Felt | Dokument-ID |
|---|---|---|
| 1 | GolfBox-ID / kunde-/medlemsnummer | golfbox-{normalisertId} |
| 2 | E-post | email-{normalisertEpost} |
| 3 | Telefon | phone-{telefonKunSiffer} |
Eksempler:
golfbox-073-1234567
email-kunde-eksempel-no
phone-4790000000
Kjernefelt¶
type Customer = {
name: string;
renterName: string;
memberName: string;
email: string;
phone: string;
golfboxId: string;
memberNumber: string;
membershipNumber: string;
isMember: boolean;
status: "active" | "inactive" | "suspended";
source: "booking" | "member" | "import" | "admin";
clubId: string;
clubIds: string[];
lastBookingClubId: string;
lastBookingDate: string;
hasDoctorsNote: boolean;
lastHasDoctorsNote: boolean;
createdAt: Timestamp;
updatedAt: Timestamp;
};
Tenant-Felter¶
Lokale fordeler skal ligge per klubb-ID:
type CustomerLocalBenefits = {
localBenefits: {
[clubId: string]: {
lastHasDoctorsNote?: boolean;
updatedAt?: Timestamp;
pass?: {
type: "none" | "clipCard" | "monthly" | "yearly";
status: "active" | "paused" | "expired";
validFrom?: string;
validUntil?: string;
totalClips?: number;
remainingClips?: number;
includedHoles?: number[];
lastUsedAt?: Timestamp;
lastBookingId?: string;
updatedAt?: Timestamp;
};
};
};
};
Viktige Regler¶
- GolfBox-ID er nasjonal kundeidentifikator, ikke tenant-sperre.
clubIder siste eller primær klubbkontekst.clubIdser alle klubber kunden er observert eller administrert i.localBenefits.{clubId}styrer lokale fordeler for den klubben.- Legeattest skal lagres som pris-/fordelsgrunnlag, ikke som tilgangsstyring.
- Medlemsnummer/GolfBox-ID skal ikke endres av proShop eller kunden selv uten tydelig kontrollflyt.
Bookinghistorikk¶
Bookinghistorikk ligger fortsatt i:
bookings
rentals
Kunderegisteret skal ikke duplisere hele bookinghistorikken permanent. UI kan bygge kundens historikk ved å slå opp booking/rental-data på:
golfboxIdmembershipNumbermemberNumberemailphone
Skriving Fra Booking¶
Når createBooking oppretter en kundebooking, skriver backend:
bookings/{bookingId}rentals/{bookingId}members/{customerDocId}
Backend bruker { merge: true } på kundekortet. Det betyr at ny booking oppdaterer kontaktdata, siste bookinginfo, legeatteststatus og klubbtilknytning uten å slette eksisterende lokale fordeler.
Anbefalt Neste Datasteg¶
- Definer
customerssom logisk domenenavn i dokumentasjon og kodekommentarer. - Behold fysisk collection
membersinntil migrering er planlagt. - Lag en backfill-jobb som normaliserer eksisterende rental-kunder inn i stabile kundedokumenter.
- Legg inn tydelig konfliktstrategi når samme e-post og GolfBox-ID peker på ulike personer.
- Legg indekser for
clubIds,email,membershipNumberogphoneetter faktisk query-mønster.