Browse + select
Customer picks one or more services and a barber on the React frontend; Framer Motion handles the transition between selection and confirmation.
Portrait-driven editorial site fronting a full booking platform — bookings, payments, ratings, an admin AI assistant.
A neighborhood barbershop needed an online identity that matched the room — brown/gold, editorial, neighborhood-rooted — plus a real booking system, ratings, reschedules, payments, and customer comms. Not a brochure; the operating layer.
Most barbershop websites fail on operations, not branding. The owner needed bookings, payments, ratings, reminders, and a way to query the business in English — built so the shop could run on it day one and the operator wouldn't need a developer to ask 'how many bookings this month?'
Designer, engineer, deployer. Single-shop SaaS, four-month build.
Booking platforms exist (Booksy, Square) but they take a cut, lock the brand into their template, and surface customer data only on their dashboard. For a shop that wanted full brand control and full data ownership, the build-your-own path is cheaper at month 12 than month 1.
A booking flows through Stripe, a reminder cron, and a per-booking rating loop. The operator sees it all in one admin view.
Customer picks one or more services and a barber on the React frontend; Framer Motion handles the transition between selection and confirmation.
Google OAuth or email/password. JWT with refresh-token rotation; tokens never leak via local storage.
Booking row + booking_services rows committed in a transaction. Stripe Checkout for payment; webhook updates payment_status on confirmation.
node-cron job sweeps upcoming bookings on a schedule, sends reminders via Resend (email). SMS is wired but safe-disabled pending A2P.
Barber sees the schedule. After the cut, a rating link goes to the customer; rating_results writes back to the booking.
Admin LLM assistant answers business questions in English ('revenue by barber this month?'), gated by a metrics registry and a per-user rate limit.
Timezone-aware modal; existing payment is preserved or refunded based on policy.
Customers can join a waitlist when a barber's schedule is full; promoted to bookings when slots open.
React 18 frontend with a brown/gold design system, Framer Motion transitions on core pages, Recharts for admin analytics, react-toastify notifications. Node/Express backend with JWT + refresh-token rotation, Google OAuth, and PostgreSQL across 15+ tables (users, services, bookings, booking_services, barber_services, refresh_tokens, rating_results, sms_dnd_numbers, waitlist_entries). Booking lifecycle: multi-service bookings, per-booking ratings, reschedule and cancel with timezone awareness, node-cron reminder pipeline. Stripe Checkout with webhook-driven payment status and a 'Pay Now' flow for post-booking collection. Admin LLM assistant — natural-language queries against business data, gated by a metrics registry, safety validator, and per-user rate limiter. Deploy is a safe-deploy script with git-readiness checks, commit-marker backend-change detection, SSH multiplexing, and UFW rate limiting on the droplet.
React frontend, Express API, Postgres data layer, and integrations — all on a single DigitalOcean droplet with managed Postgres.
Brown/gold design system, Framer Motion transitions on core pages, Recharts on the admin view.
Two surfaces, one codebase. Admin AI assistant lives behind the auth wall.
Helmet, express-rate-limit, express-validator. JWT + refresh-token rotation; Google OAuth.
Metrics registry + safety validator + per-user rate limiter wrap every OpenAI call.
users, services, bookings, booking_services, barber_services, refresh_tokens, rating_results, sms_dnd_numbers, waitlist_entries.
Reminder pipeline sweeps upcoming bookings on a schedule.
Webhooks update payment_status; idempotent on retry.
Booking confirmations, reminders, rating prompts.
Switchable SMS path, off until A2P registration clears.
Admin natural-language assistant only — not customer-facing.
deploy-do-safe.sh runs git-readiness checks, detects backend-change commit markers, multiplexes SSH, and rolls back atomically on failure.
Twilio integration is switchable, safe-disabled by default. Email + in-app notifications handle reminders until US A2P approval lands.