ValYou
NFC & QR customer engagement platform for physical businesses.
A multi-location SaaS that turns a tap or scan at the counter into a Google review, an optional customer contact and analytics the owner actually reads — delivered as a weekly email report.
Role
Founder & Product Engineer — product, backend, frontend, data and deployment
Timeline
Aug 2026 — Present
Type
SaaS · Customer engagement
Overview
All locations
Taps (NFC)
Scans (QR)
Review clicks
Contacts
Interactions by source
Top locations
- Downtown
- Waterfront
- Mall kiosk
Problem
Restaurants, cafés and shops live on Google reviews, but asking for one is awkward, and the moment leaves no data behind. Owners can't tell which location, table or touchpoint drives engagement — and they don't have time to live in a dashboard.
Solution
Physical NFC/QR cards point to dynamic, server-side redirects. Each tap opens a branded bilingual page that leads to the Google review flow and optionally collects contact details. Every interaction is recorded by card, location and source, and summarised into dashboards and a weekly email report.
Stack
- Frontend
- Next.jsReactTypeScriptTailwind CSSshadcn/uiReact Query
- Backend
- Node.jsExpressTypeScriptPrismaPostgreSQLRedisBullMQ
- Infrastructure
- Ubuntu VPSNginxPM2SSLGitHubBrevo SMTP
01 — Problem
Reviews matter. Asking for them doesn't scale.
Physical businesses — restaurants, cafés, retail, salons, clinics — depend on Google reviews for discovery. In practice, staff forget to ask, customers forget to follow through, and the interaction leaves no trace.
Owners also lack a basic view of engagement: which branch, which counter, which card is actually generating interactions. The tools that exist are built for marketers who spend their day in dashboards, not for a café owner with ten minutes a week.
- Users
- Business owners, staff, end customers, platform admins
- Constraint
- Zero friction for customers — no app, no forced sign-up
- Constraint
- Owners need answers without opening a dashboard
02 — Product
A tap at the counter, a weekly answer in the inbox.
Each business receives NFC/QR cards for its locations. A tap or scan opens a branded page in English or Arabic that leads to the Google review flow and lets the customer optionally share their name and phone number — with clear, privacy-focused messaging and no mandatory promotional sign-up.
Every interaction is recorded with its card, location and source. Owners see engagement per location and card in a dashboard, and receive a weekly email summarising what happened. Plans scale by the number of locations and cards a business can run.
- 01
Tap or scan
NFC chip or printed QR opens a stable ValYou URL.
- 02
Resolve card
Lookup card → location → business; check it is active.
- 03
Record event
Append interaction with source (NFC / QR) and timestamp.
- 04
Redirect
Branded page → Google review, optional contact form.

03 — Architecture
A small number of well-separated moving parts.
The frontend is a Next.js App Router application serving three audiences: public customer pages, the business-owner dashboard and the super-admin console. It talks to a single Express + TypeScript REST API.
Inside the API, routes stay thin: validation and authorization happen at the edge, business rules live in services, and Prisma handles persistence to PostgreSQL. Anything slow, scheduled or dependent on a third party — weekly reports, transactional email, Google data sync — is pushed to BullMQ queues on Redis and processed by separate worker processes.
04 — Domain model
Business is the tenant, the billing boundary and the permission scope.
The most important early decision was getting the ownership graph right. A Business owns its Locations; Cards belong to a Location and carry a stable public code; every tap or scan is an immutable Event that references the card, the location and the source. The Subscription attaches to the Business, not to a location or a user.
Users relate to businesses through a role, so an owner, a staff member and a platform super-admin all resolve permissions through the same path — and every query is scoped by business.
05 — Decisions
Engineering decisions
Gate features at the business level
- Context
- Plans differ by how many locations and cards a business can run. Attaching plans to users or locations would make limits ambiguous for multi-location owners.
- Decision
- The subscription belongs to the business. A single entitlement resolver turns the active plan (or trial) into limits; services check it before creating locations or cards, and the dashboard reads the same entitlements to render upgrade states.
- Trade-off
- One resolver must stay in sync with the plan catalogue — in exchange, limits are enforced in exactly one place.
Dynamic redirects, never hard-coded card URLs
- Context
- A printed card is permanent. Its destination, owner or status may not be.
- Decision
- Cards encode a stable ValYou URL. The redirect target is resolved server-side on every request, which also records the interaction and its source (NFC or QR) before forwarding.
- Trade-off
- The redirect sits on the critical path, so it does the minimum — lookup, record, redirect — and defers everything else.
Short-lived access tokens, rotating refresh tokens
- Context
- Dashboards stay open for long periods; sessions must be revocable.
- Decision
- Access tokens are short-lived. Refresh tokens are stored server-side, rotated on use and revoked on logout. On the client, a single in-flight refresh is shared by concurrent requests, so a burst of 401s triggers one refresh instead of a race.
- Trade-off
- More state than stateless JWTs, but sessions can actually be ended.
Idempotent provisioning
- Context
- Super-admins provision businesses, owners, locations and subscriptions. Double-clicks, retries and slow networks are normal.
- Decision
- Provisioning runs as a single transaction guarded by unique constraints and an idempotency check, so a repeated request returns the existing result instead of creating a second business or re-applying a trial or payment.
Analytics from raw events
- Context
- Counters updated in place drift, and dashboards and emails start disagreeing.
- Decision
- Interactions are stored as append-only events with card, location, source and timestamp. Dashboards and weekly reports aggregate from the same events over explicit date ranges, so both always tell the same story.
Integrations behind queues and caches
- Context
- Google APIs have quotas and latency; a dashboard shouldn't wait on them.
- Decision
- Location connection and disconnection are explicit lifecycle actions. Review data is synced by background jobs and served from the database, rather than fetched live on each page load.
- Trade-off
- Review data can be slightly behind real time — acceptable for this product, and far more predictable.
06 — Auth flow
Authentication that survives real usage.
Concurrency is the hard part of refresh tokens. When a dashboard fires several requests with an expired access token, naive clients send several refresh calls, and with rotation enabled all but one fail — logging the user out.
The client wraps the fetch layer so the first 401 starts a refresh and every other request waits on that same promise, then retries with the new token.
07 — Background jobs
Keep the request path fast; do the rest in workers.
The API enqueues; workers execute. Weekly reports, transactional emails and integration sync are BullMQ jobs on Redis, with retries and backoff for transient failures. Workers run as separate PM2 processes, so a slow SMTP response or third-party API never blocks a customer's tap.
- Weekly report: aggregate events per business → render email → send via Brevo SMTP
- Transactional email: invitations, account and provisioning notifications
- Integration sync: refresh connected Google location data outside of page loads
08 — Production
Deployed and operated, not just built.
ValYou runs on an Ubuntu VPS. Nginx terminates TLS and reverse-proxies to the Next.js app and the API; PM2 supervises the web, API and worker processes. Configuration is environment-based, and email is delivered through Brevo SMTP on the product domain.
- TLS certificates and HTTPS redirects at the proxy
- Separate processes for API and workers so they scale and restart independently
- Environment-specific configuration, secrets kept out of the repository
- Error monitoring for production debugging
09 — Result
Live in production.
ValYou is live at valyou-lb.site with three tiers — Starter, Pro and Premium — that scale by locations and cards, and a provisioning flow for onboarding new businesses.
The architecture leaves room to grow: new plans are configuration, new reports are jobs, and new entry points are just another event source.
- Status
- Live in production
- Plans
- Starter · Pro · Premium
- Languages
- English · Arabic
- Next
- Access Business's Google Reviews and Add AI Analysis