- Node.js 18+ installed
- Supabase account
- Git
Add these packages to your project:
npm install qrcode jsqr
npm install --save-dev @types/qrcode @types/jsqr- Go to supabase.com
- Create a new project
- Note your project URL and anon key
- Go to Authentication > Providers
- Enable Phone provider
- Choose SMS provider:
- Option A: Use Twilio
- Add Twilio Account SID, Auth Token, and Messaging Service SID
- Option B: Use Supabase managed (if available in your region)
- Option A: Use Twilio
- Go to SQL Editor in Supabase dashboard
- Copy the entire schema from
Database Schema & RLS Policiesartifact - Run the SQL script
- Verify all tables are created
Create .env.local in your project root:
# Get these from Supabase > Settings > API
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key-here
# Get this from Supabase > Settings > API (service_role key - keep secret!)
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key-here
# Your app URL
NEXT_PUBLIC_APP_URL=http://localhost:3000Create these files in your Next.js project:
src/
├── app/
│ ├── login/page.tsx # Customer login (phone)
│ ├── wallet/page.tsx # Customer wallet
│ ├── redeem/[id]/page.tsx # Redeem reward page
│ ├── biz/
│ │ ├── login/page.tsx # Business login
│ │ ├── page.tsx # Business dashboard
│ │ └── [id]/
│ │ ├── staff/page.tsx # Staff scanner
│ │ ├── program/page.tsx # Program settings
│ │ ├── rewards/page.tsx # Rewards management
│ │ └── ledger/page.tsx # Transaction ledger
│ └── api/
│ ├── earn/route.ts # POST - credit points
│ └── redeem/
│ ├── issue/route.ts # POST - issue redeem token
│ └── consume/route.ts # POST - consume redeem token
├── components/
│ ├── qr/CustomerQR.tsx # QR code display
│ └── scan/CameraScanner.tsx # Camera scanner
└── lib/
└── supabase.ts # Already exists (provided)
After setup, you'll need to create the first business account manually:
-
Go to Supabase > Authentication > Users
-
Click "Add user" > Email
-
Enter email and password (this will be your business owner account)
-
Note the user ID
-
Go to SQL Editor and run:
-- Replace YOUR_EMAIL and YOUR_USER_ID
INSERT INTO business_users (business_id, email, role)
SELECT id, 'YOUR_EMAIL', 'owner'
FROM businesses
WHERE owner_user_id = 'YOUR_USER_ID';OR use the signup flow in the app once built.
npm run devVisit:
- Customer login: http://localhost:3000/login
- Business login: http://localhost:3000/biz/login
- Login at
/biz/login - Create a business
- Set earn rate in Program Settings (default: 5 pts/$1)
- Create rewards (e.g., "Free Coffee" for 50 pts)
- Go to Staff Terminal
- Login at
/loginwith your phone number - Receive and enter OTP code
- View wallet (empty at first)
- Show your QR code
- On staff terminal, click "Open Camera"
- Scan customer QR code (or use phone lookup)
- Enter bill amount (e.g., $10.00)
- Credit points
- Customer refreshes wallet to see new balance
- Customer taps on a reward they can afford
- Click "Generate Redeem Code"
- Show QR to staff
- Staff scans redeem QR
- Points deducted, reward consumed
- Check Twilio credentials are correct
- Verify phone number format: +1XXXXXXXXXX
- Check Supabase logs for SMS errors
- Fallback: Use email magic link temporarily
- HTTPS required for camera (localhost works)
- Grant camera permissions in browser
- Use phone number lookup as fallback
- Verify user is authenticated
- Check business_users table has correct email entries
- Review Supabase logs for policy violations
- Check SUPABASE_SERVICE_ROLE_KEY is set
- Verify program is active for the business
- Check API route logs in terminal
After core MVP works:
- Add loading states and skeletons
- Add toasts for success/error messages
- Rate limiting on API routes
- Better error handling
- "Are you sure?" prompts on critical actions
Before deploying:
- Change all environment variables
- Enable RLS on all tables
- Set up proper CORS if needed
- Configure production domain in Supabase
- Test on real mobile devices
- Set up error monitoring (Sentry, etc.)
- Add rate limiting
- Set up backup strategy
- Configure PWA manifest for installability# Karma