ayoo is a next-generation loyalty platform where venues publicly compete on their points exchange rate to attract customers. Users earn points anywhere (via receipt scan) or at partner venues (10× better rate), and spend them only at partners.
This monorepo contains the API (tRPC, for the mobile app) and the Merchant Web App (Next.js dashboard for venue owners).
| Layer | Technology |
|---|---|
| Framework | Next.js 15 App Router |
| API | tRPC v11 |
| Auth | NextAuth v5 (Auth.js) |
| ORM | Prisma + PostgreSQL |
| Database | Supabase (Postgres + Storage) |
| Cache / Cron | Upstash Redis + QStash |
| OCR | Google Vision (free) → GPT-4o (paid) |
| AI verification | Anthropic Claude Sonnet |
| i18n | next-intl (EN / RU / SR) |
| Styling | Tailwind CSS |
| Monorepo | pnpm workspaces + Turborepo |
ayoo-backend/
├── apps/
│ ├── api/ # Next.js — tRPC handler for mobile app (port 3000)
│ └── merchant/ # Next.js — Merchant Web App (port 3001)
├── packages/
│ ├── db/ # Prisma schema + client singleton
│ ├── trpc/ # tRPC routers (shared between both apps)
│ ├── auth/ # NextAuth configs (user: magic link, merchant: credentials)
│ ├── i18n/ # Translations EN / RU / SR
│ ├── shared/ # Constants, types, utilities
│ └── jobs/ # Cron handlers (expire points)
├── .env.example
├── pnpm-workspace.yaml
└── turbo.json
git clone <repo>
cd ayoo-backend
pnpm install- Go to supabase.com → New project
- Settings → Database → Connection string
- Copy Transaction pooler URL →
DATABASE_URL - Copy Session pooler URL →
DIRECT_URL
- Copy Transaction pooler URL →
- Settings → API → copy
anonkey andservice_rolekey
cp .env.example .env
# Fill in: DATABASE_URL, DIRECT_URL, AUTH_SECRET, RESEND_API_KEY
# Minimum required to boot: DATABASE_URL + DIRECT_URL + AUTH_SECRETGenerate AUTH_SECRET:
openssl rand -base64 32pnpm db:migrate
# Creates all tables in your Supabase Postgres instancepnpm dev
# api: http://localhost:3000
# merchant: http://localhost:3001| Command | Description |
|---|---|
pnpm dev |
Start all apps in parallel |
pnpm build |
Build all apps |
pnpm test |
Run all tests |
pnpm typecheck |
TypeScript check across all packages |
pnpm db:migrate |
Run Prisma migrations (dev) |
pnpm db:migrate:prod |
Run Prisma migrations (production) |
pnpm db:studio |
Open Prisma Studio |
pnpm db:generate |
Regenerate Prisma client |
Two separate Vercel projects, both pointing to this monorepo:
| Project | Root directory | Environment |
|---|---|---|
ayoo-api |
apps/api |
DATABASE_URL, AUTH_SECRET, RESEND_API_KEY, ... |
ayoo-merchant |
apps/merchant |
DATABASE_URL, MERCHANT_AUTH_SECRET, ... |
Add all variables from .env.example to each project's Vercel dashboard.
Scheduled via QStash instead of Vercel Cron (free tier):
| Job | Endpoint | Schedule |
|---|---|---|
| Expire welcome points | POST /api/cron/expire-welcome |
Daily 03:00 UTC |
| Expire earned points | POST /api/cron/expire-earned |
1st of month 04:00 UTC |
Configure in your Upstash QStash dashboard after deployment.