Skip to main content
Mohamed Amine MIDENI
All projects

Rabbehni

Multi-tenant loyalty SaaS with QR check-ins, gamification, and native mobile apps

NestJS 11Prisma ORMPostgreSQL 16Socket.IO gatewayJWT + Passport
Rabbehni

About

Context, problem & solution

Rabbehni is a loyalty SaaS that lets any business — a café, a barber, a retail chain — run a real loyalty programme without building one: customers scan a QR code at the counter, the visit is recorded, and rewards or a game unlock instantly.

Context and problem. Loyalty is a solved problem for large chains with custom software and unsolved for everyone else. Building it as a SaaS raises three distinct hard problems at once. Tenancy: dozens of merchants share one database and must never see each other's customers. Trust: a check-in grants real economic value, so it cannot be something a client app can simply claim. Surface sprawl: the merchant needs a dashboard, the counter staff needs a fast scanner, and the customer needs a wallet — and the customer who just scanned a QR will not install an app, while the regular who returns weekly wants one.

Solution. A monorepo with a single NestJS 11 API and five client surfaces, none of which touches the database directly. The API is split by domain — checkin, games, rewards, redemptions, campaigns, billing, tenant, analytics, audit, localization — each a Nest module with a strict controller/service/Prisma split: controllers declare routes and validate DTOs, services hold all business logic, Prisma does data access and decides nothing. Shared concerns live in common as guards: authentication, tenant scoping, and subscription plan limits are enforced before a request reaches a service. Prisma models 26 entities across 9 versioned migrations against PostgreSQL 16. The web app is Next.js 16 with route groups per audience, and the customer app deliberately exists twice — as web for the just-scanned visitor and as an Expo app for the regular — both consuming exactly the same /api/me endpoints. A Socket.IO gateway pushes check-ins to merchant dashboards live.

Engineering and quality focus. The three-layer rule is the invariant the codebase is built around: no business logic in controllers, no req/res in services, no decisions in the data layer — which keeps services unit-testable without HTTP. Tenant isolation and plan enforcement are guards rather than per-endpoint checks, so a new module inherits them instead of re-implementing them and forgetting an edge case. Check-in validation is entirely server-side; the staff scanner submits a code and the API decides. The repository ships twelve chapters of technical documentation covering architecture, the data model, security, and functional journeys — plus seed scripts that bring up a complete demo dataset from an empty database.

Architecture

How the system is built

architecture.diagram
Client surfaces
Next.js web
Storefront & dashboardSuper-adminCustomer wallet
Expo — customer
Wallet & gamesQR scanning
Expo — staff
Validate check-insRedeem rewards
API
NestJS 11
Modular REST /apiJWT + role guardsDTO validation
Socket.IO gateway
Live check-in feedDashboard push
Domain
Check-in engine
QR validationVisit recording
Rewards & games
Instant rewardsRedemptions
Billing
SubscriptionsProration & plan caps
Data
PostgreSQL 16
26 models, 18 enums9 versioned migrations
Tenant scoping
Merchant → branchesRow-level isolation
One NestJS API serving five client surfacesMulti-tenant: merchant → branches → customersQR check-in validated server-side, never on the clientSubscription billing with proration and plan-limit guardsTwo Expo apps: customer wallet + staff scannerArabic (RTL) and English, multi-country and multi-currency

Tech stack

Technologies used

Backend

NestJS 11Prisma ORMPostgreSQL 16Socket.IO gatewayJWT + Passportclass-validator DTOs

Web

Next.js 16 (App Router)TypeScriptTanStack QueryRadix UITailwind CSSFramer MotionRecharts

Mobile

React Native (Expo)Expo Routerexpo-camera (QR scan)expo-secure-storeexpo-localization

Domain modules

Multi-tenant isolationBilling & prorationCheck-in & redemptionsGames & rewardsCampaignsAnalytics & audit

Platform

i18n (Arabic RTL + English)Multi-country / currencyQR generation + @zxing scanningDocker Compose (PostgreSQL)

Want to know more about Rabbehni?

This is a private repository, so the source isn't public — happy to walk through the architecture and the code on request.