Customer CRM

Know every diner like a regular

Materialized RFM scores, lifetime stats, normalized tags, append-only notes, allergen + dietary preferences, GDPR consent audit, double opt-in, and global delete with grace period — all built into your ordering platform. No external CDP, no extra subscription.

What is Customer CRM?

Every completed order updates a per-venue stats row for the customer — total orders, total spent, average order value, recency, frequency, and a composite RFM segment label (CHAMPION / LOYAL / POTENTIAL / NEW / AT_RISK / LOST / INACTIVE). The list page shows the segment as a colored badge so the manager can spot the regulars at a glance and the lost ones who need a winback.

Tags are global per customer (one VIP tag follows them across every venue you operate). Notes are venue-scoped and append-only — the history is preserved. Consent changes are recorded in an audit log with IP, user agent, and actor — GDPR Article 7 evidence on tap.

What you get

RFM segments computed automatically

Recency, frequency, monetary scoring with percentile bucketing for venues with 30+ customers and stable thresholds for smaller cohorts. No external tool to configure.

Saved segments for marketing + promos

Build customer groups via a JSON criteria DSL — high-value champions, dormant customers, VIP-tagged opt-ins. Memberships are materialized nightly; marketing campaigns and promo codes target them instantly.

Tags, notes, allergens — all in one dossier

Normalized tags (global per customer), append-only venue notes (with author + timestamp), and structured allergen / dietary preferences. Favorites and dislikes are auto-derived nightly from order history. Staff handovers stop losing context.

Full GDPR toolbox

Append-only consent log (Article 7 evidence) with IP / user agent / actor on every flip. Optional double opt-in per venue for EU compliance. Customer-initiated global delete with a 7-day grace period; force-execute path for DPA orders.

How it works

1

Order completes

An inline writer recomputes the customer's per-venue stats: total orders, total spent, AOV, recency, frequency, monetary scores. Cheap (one aggregate + one upsert).

2

Nightly cron rebalances

Once a day at 03:30 UTC the entire venue cohort is re-percentile-bucketed so segment labels stay accurate as the customer base evolves.

3

Marketing + promos read instantly

Saved segments materialize membership into a join table. Marketing campaign recipients and promo-code targeting get instant lookups instead of full-table scans.

4

Audit trail captures every consent flip + survives delete

Checkout opt-in, admin toggle, unsubscribe-link click, double opt-in confirmation — each writes a structured row to CustomerConsentLog. When a customer requests global deletion the consent log is preserved and a final REVOKED entry is appended; the personal record itself is anonymised in place after the grace period so Order/Bill financial integrity stays intact.

Capabilities

Materialized customer stats

Per-(customer, venue) row with totalOrders, totalSpent, AOV, firstOrderAt, lastOrderAt, daysSinceLastOrder, RFM scores 1-5, and composite segment label.

  • Inline updates on order completion
  • Nightly recompute via PM2-leader cron + external trigger
  • Sub-millisecond reads — admin list never scans Order table
  • Single source of truth for AI Conversational Admin tools

Saved segments with criteria DSL

JSON-driven criteria DSL — combine field/op/value predicates with all/any/not groups. Compile to Prisma where-fragment, materialize membership.

  • 6 system segments seeded automatically (matches legacy enum)
  • Custom segments unlimited per venue
  • Member counts + last-computed timestamp visible at a glance
  • Manual recompute button for instant feedback after a criteria edit

Tags, notes, allergens + dietary preferences

Tags are global per customer; notes are venue-scoped and append-only with author + timestamp. Allergen / dietary / favorite / disliked product preferences live in a structured table — explicit entries from the dossier, plus auto-derived favorites and dislikes from order history with a confidence score.

  • Up to 50 tags per customer (unique constraint), tag-based segment criteria (hasTag)
  • Allergen + dietary preferences surface during ordering and on the kitchen ticket
  • Favorites + dislikes auto-derived nightly (top 3 with ≥3 orders → favorite; ordered once + ≥5 skips → disliked)
  • Notes preserved forever with full author attribution

GDPR toolbox — consent log + double opt-in + global delete

Append-only CustomerConsentLog (channel, action, source, IP, user agent, actor) is your Article 7 evidence. Per-venue Venue.requireDoubleOptIn turns on EU-style double opt-in for marketing — a confirmation token email is sent and the consent flag stays false until the customer clicks. CustomerDeleteRequest schedules global anonymisation with a 7-day grace period; the nightly cron executes; ROLE_ADMIN can force-execute for DPA orders.

  • Records EMAIL_MARKETING / SMS_MARKETING / WHATSAPP_MARKETING / REVIEW_REQUEST
  • Double opt-in tokens have a 7-day TTL; idempotent — duplicates collapse
  • Global delete anonymises in place — Order/Bill FKs preserved for financial integrity
  • Cron auto-executes pending deletes daily; force-execute available for DPA compliance

Built for these workflows

Spot the regulars before they leave

AT_RISK badge appears 30 days after a regular's last visit. Filter the list, send a winback campaign, or have the manager call them — before the LOST badge turns up at 90 days.

Birthday campaigns without spreadsheets

Customer.dateOfBirth + birthday cron already shipped. Pair with a saved segment for VIP customers and the email goes only to the right people.

Multi-venue chains tracking the same customer

Tags are global; stats are per-venue. The dossier's Lifetime Stats card shows cross-venue totals + per-venue breakdown. The chain operator sees everything; each venue manager sees only their venue's notes.

Marketing campaigns with materialized recipients

Existing marketing/recipients flow now reads from CustomerSegmentMembership. Recipient counts return in milliseconds even on venues with 100K+ customers.

GDPR data subject requests, end-to-end

Customer asks 'when did I opt in?' — pull the CustomerConsentLog. Customer asks for deletion — schedule a global CustomerDeleteRequest with a 7-day grace period and the nightly cron anonymises everywhere; for DPA orders the platform owner force-executes immediately. EU venues can require double opt-in for marketing — the consent flag stays false until the customer clicks the email link.

AI Conversational Admin powered by clean data

The /admin/ask assistant calls customer-stats tools that read directly from CustomerVenueStats. Answers like 'who are my top 5 customers?' or 'who hasn't visited in 60 days?' return numerically-correct data, not LLM hallucinations.

Why a built-in CRM beats an external CDP

Most restaurant SaaS pushes you toward an external customer data platform — Segment, RudderStack, Klaviyo. For most independent restaurants and small chains those tools are overkill, expensive, and add operational complexity (a customer that exists in two places will diverge). A CRM built into the ordering platform reads from the authoritative bills + rounds data and gives you the 80% that matters: segments, tags, notes, consent.

Why materialized RFM beats on-the-fly compute

Computing RFM on every list-page load is slow once the customer base passes 5,000. Materializing the score on order completion (single aggregate + single upsert) keeps reads cheap forever and lets us add admin filters that were impossible before — sort by LTV, filter by segment, paginate without timeouts.

Why tags should be global

VIP follows the customer. If they're a VIP at your London venue and they walk into your Sofia venue, they're still a VIP. Per-venue tag scoping creates inconsistencies that operators have to remember to fix manually. Notes are venue-scoped because notes are about a specific interaction or service issue at a specific venue.

Why an audit log is non-negotiable

GDPR Article 7 requires you to demonstrate that consent was given. The previous 'last-write-wins' approach (a single timestamp on the Customer row) loses every prior consent change. The append-only CustomerConsentLog captures every flip with attribution — when the data protection authority asks, you have receipts.

Your customer data, finally usable

Always-on for every venue. No setup. No external CDP. RFM segments populated tonight by the cron sweep.