arrow_backBack to Portfolio
Marketplace / Booking·v1.0.0·Jun 2026

Zavia

A two-sided marketplace for beauty & grooming services, connecting clients, salons, and platform admins — map-based discovery, no-overlap booking, and integrated marketplace payments.

NestJSNext.js 15PostgreSQL + PostGISRedis + BullMQStripe ConnectExpo
dashboard

Zavia

Zavia screenshot
01

warningThe Challenge

Independent beauty salons manage bookings manually — phone calls, WhatsApp, paper diaries — with no visibility into real staff availability or revenue. Clients have no single place to discover nearby salons, compare services, and book directly. The platform had to support a full two-sided marketplace: salon onboarding and verification, staff and working-hours management, a real-time availability engine, and marketplace payments — with zero slot overlaps under concurrent demand.

  • arrow_forwardSalon onboarding with address geocoding and admin verification
  • arrow_forwardPer-staff availability engine with working hours and time-off
  • arrow_forwardBooking slot locks to eliminate overlaps under concurrent requests
  • arrow_forwardMarketplace payments — the platform retains a commission, the salon gets the rest
02

architectureThe Solution

I built a Turborepo monorepo with a NestJS API, two Next.js 15 apps (company dashboard + admin panel), and an Expo/React Native app for clients. PostgreSQL with PostGIS powers geographic salon search, while Redis + BullMQ handle async job queues and booking slot locks. Authentication combines Argon2 password hashing with JWT (15-minute access, 30-day refresh with rotation) plus phone + OTP login. Stripe Connect processes marketplace payments, automatically routing the platform's commission and the salon's share. A role-based access system (RBAC) cleanly separates permissions for clients, salon owners, and platform admins.

Architecture

NestJS APIarrow_forward
Next.js 15 (Dashboard + Admin)arrow_forward
Expo / React Nativearrow_forward
PostgreSQL + PostGISarrow_forward
Redis + BullMQarrow_forward
Stripe Connect