Pulse is a SaaS platform that helps businesses collect authentic voice feedback from customers through simple QR codes. Instead of traditional text surveys, customers scan a QR code and leave voice messages that are automatically transcribed, analyzed for sentiment, and displayed in a real-time dashboard.
π Live at: pulseapp.click
- π€ Voice Feedback Collection - Customers record voice messages via QR code scanning
- π Automatic Transcription - Powered by ElevenLabs Speech-to-Text
- π Sentiment Analysis - Automatically categorizes feedback as positive, neutral, or negative
- π Real-Time Dashboard - View all feedback with audio playback and transcripts
- π Unique QR Codes - Each business gets a custom QR code for feedback collection
- π³ Credit-Based System - Pay-as-you-go model with Pulse credits
- π Privacy First - GDPR compliant with encrypted storage
- π§ OTP Authentication - Secure email-based login system
- Next.js - Full-stack React framework with App Router and SSR
- React - UI library
- TanStack Query - Data fetching and state management
- Tailwind CSS - Styling
- Shadcn UI - UI components
- Lucide React - Icons
- React QR Code - QR code generation
- ElysiaJS - Fast web framework for API routes
- Eden Treaty - End-to-end type safety
- Drizzle ORM - TypeScript ORM
- Neon Database - Serverless PostgreSQL
- Resend - Transactional emails
- ElevenLabs - Speech-to-text transcription
- Google Gemini AI - Sentiment analysis and name extraction
- Cloudflare R2 - Object storage for audio files
- Next.js Compiler - Application build and bundling
- TypeScript - Type safety
- Zod - Schema validation
- T3 Env - Type-safe environment variables for Next.js
- Vitest - Testing framework
- ESLint & Prettier - Code quality
- Bun (recommended) or Node.js 18+
- A Neon database (or PostgreSQL)
- Cloudflare R2 account (for audio storage)
- Google Gemini API key
- Resend API key (for emails)
- Clone the repository:
git clone <repository-url>
cd pulse- Install dependencies:
bun install- Set up environment variables:
cp .env.example .env-
Configure your
.envfile with the required variables (see Environment Variables) -
Set up the database:
bun run db:push- Start the development server:
bun run devThe application will be available at http://localhost:3000
Create a .env file in the root directory with the following variables:
# Server
SERVER_URL=http://localhost:3000
SESSION_SECRET=your-session-secret-min-32-chars
# Database
DATABASE_URL=your-neon-postgres-connection-string
# Email (Resend)
SERVER_RESEND_API_KEY=your-resend-api-key
# AI (Google Gemini)
SERVER_GEMINI_API_KEY=your-gemini-api-key
# Speech-to-text (ElevenLabs)
ELEVEN_LABS_API_KEY=your-elevenlabs-api-key
# Storage (Cloudflare R2)
CLOUDFLARE_ACCOUNT_ID=your-cloudflare-account-id
CLOUDFLARE_ACCESS_KEY_ID=your-r2-access-key-id
CLOUDFLARE_SECRET_ACCESS_KEY=your-r2-secret-access-key
CLOUDFLARE_R2_BUCKET_NAME=your-bucket-name
# Payments (Polar.sh)
POLAR_API_KEY=your-polar-api-key
# Client
NEXT_PUBLIC_APP_TITLE=Pulse
NEXT_PUBLIC_APP_URL=http://localhost:3000This project uses Neon (serverless PostgreSQL) with Drizzle ORM.
# Generate migrations
bun run db:generate
# Push schema changes to database
bun run db:push
# Run migrations
bun run db:migrate
# Open Drizzle Studio (database GUI)
bun run db:studioCreate a Neon Postgres database, copy the connection string into DATABASE_URL, then run bun run db:push to apply the Drizzle schema.
pulse/
βββ app/
β βββ api/[[...slugs]]/ # Elysia API mounted inside Next.js
β βββ dashboard/ # Business dashboard
β βββ f/[id]/ # Public QR-code feedback page
β βββ login/ # OTP login page
β βββ ... # Other App Router routes
βββ src/
β βββ components/ # React components
β β βββ ui/ # Shadcn UI components
β β βββ ...
β βββ lib/ # Utility libraries
β β βββ ai/ # AI integrations (ElevenLabs + Gemini)
β β βββ storage/ # Storage utilities (R2)
β β βββ utils/ # Helper utilities
β βββ db/ # Database schema and migrations
β βββ emails/ # React Email templates
β βββ contexts/ # React contexts (Auth, etc.)
β βββ styles.css # Global styles
βββ public/ # Static assets
βββ package.json
# Development
bun run dev # Start dev server on port 3000
# Building
bun run build # Build for production
bun run start # Start production server
# Database
bun run db:generate # Generate migrations
bun run db:push # Push schema to database
bun run db:migrate # Run migrations
bun run db:studio # Open Drizzle Studio
# Code Quality
bun run lint # Run ESLint
bun run format # Format with Prettier
bun run check # Format and lint
# Tunnels
bun run dev:tunnel # Expose local app with ngrok- OTP-based email authentication
- Session management with HTTP-only cookies
- Protected dashboard routes via server-side auth checks
- Real-time audio streaming (WhatsApp-like experience)
- Chunks uploaded every 2 seconds during recording
- Automatic transcription with ElevenLabs Speech-to-Text
- Sentiment analysis with Google Gemini (positive/neutral/negative)
- Customer name extraction from transcripts with Google Gemini
- Audio files stored in Cloudflare R2
- Presigned URLs for secure access
- Unique keys per feedback:
feedback/{userId}/{feedbackId}/audio.webm
- Credit-based system (Pulses)
- Integration with Polar.sh for payment processing
- Packages: 10, 25, 50, 100 pulses
This project uses Shadcn UI. To add new components:
pnpx shadcn@latest add button
pnpx shadcn@latest add card
# etc.- Environment Variables: Type-safe with
@t3-oss/env-core - API Routes: End-to-end type safety with Eden Treaty
- Database: Type-safe queries with Drizzle ORM
- Forms: Schema validation with Zod
Private - All rights reserved
Built with β€οΈ by Timothy Osaretin Ogbemudia