# QR Master - Create Custom QR Codes in Seconds A production-ready SaaS application for creating and managing QR codes with advanced tracking, analytics, and Stripe payment integration. ## Features - 🎨 **Custom QR Codes** - Create static and dynamic QR codes with full customization - 📊 **Advanced Analytics** - Track scans, locations, devices, and user behavior - 🔄 **Dynamic Content** - Edit QR code destinations anytime without reprinting - 📦 **Bulk Operations** - Import CSV/Excel files to create up to 1,000 QR codes at once - 💳 **Stripe Integration** - FREE, PRO, and BUSINESS subscription plans with secure billing - 🎨 **Custom Branding** - Logo upload, custom colors (PRO+ plans) - 🌍 **SEO Optimized** - Schema.org structured data, meta tags, breadcrumbs - 🔒 **Privacy-First** - GDPR-compliant, hashed IPs, DNT headers respected - 📱 **Responsive Design** - Works perfectly on all devices ## Tech Stack - **Frontend**: Next.js 14 (App Router), TypeScript, Tailwind CSS - **Backend**: Next.js API Routes, Prisma ORM - **Database**: PostgreSQL (with Prisma migrations) - **Cache**: Redis (optional) - **Auth**: NextAuth.js (Credentials + Google OAuth) - **Payments**: Stripe (Subscriptions & Webhooks) - **QR Generation**: qrcode library - **Bulk Processing**: Papa Parse (CSV), XLSX, JSZip - **Analytics**: PostHog (optional) - **SEO**: next-sitemap, Schema.org structured data ## Quick Start ### Prerequisites - Node.js 18+ - Docker and Docker Compose V2 - Git ### Installation #### Option 1: Development Mode (Recommended) Run database in Docker, app on host machine: 1. Clone the repository: ```bash git clone https://github.com/yourusername/qr-master.git cd qr-master ``` 2. Install dependencies: ```bash npm install ``` 3. Copy and configure environment: ```bash cp env.example .env ``` Edit `.env` and set: - `NEXTAUTH_SECRET` (generate: `openssl rand -base64 32`) - `IP_SALT` (generate: `openssl rand -base64 32`) - (Optional) Google OAuth credentials 4. Start database services: ```bash npm run docker:dev ``` 5. Run database migrations and seed: ```bash npx prisma migrate dev npm run db:seed ``` > **Note**: If you get migration errors, you can reset the database: > > ```bash > npx prisma migrate reset > ``` > > This will drop the database, recreate it, run all migrations, and seed data. 6. Start development server: ```bash npm run dev ``` 7. Access the application: - **App**: http://localhost:3050 - **Database UI**: http://localhost:8080 (Adminer - username: `root`, password: `root`) - **Database**: localhost:5435 (username: `postgres`, password: `postgres`) - **Redis**: localhost:6379 #### Option 2: Full Docker (Production) Run everything in Docker: 1. Clone and setup: ```bash git clone https://github.com/yourusername/qr-master.git cd qr-master cp env.example .env # Edit .env with your configuration ``` 2. Build and start: ```bash npm run docker:prod ``` 3. Run migrations: ```bash docker-compose exec web npx prisma migrate deploy ``` 4. Access at http://localhost:3050 📚 **For detailed Docker setup, see [DOCKER_SETUP.md](DOCKER_SETUP.md)** ## Demo Account After running `npm run db:seed`, use these credentials to test the application: - **Email**: demo@qrmaster.com - **Password**: demo123 - **Plan**: FREE (3 QR codes limit) The seed script also creates sample QR codes for testing. ## Development ### Available Scripts ```bash # Development npm run dev # Start Next.js dev server (port 3050) npm run build # Build for production npm run start # Start production server # Database npm run db:generate # Generate Prisma Client npm run db:migrate # Run migrations (dev mode) npm run db:deploy # Deploy migrations (production) npm run db:seed # Seed database with demo data npm run db:studio # Open Prisma Studio UI npx prisma migrate reset # Reset database (drop, recreate, migrate, seed) # Docker npm run docker:dev # Start DB & Redis only npm run docker:dev:stop # Stop dev services npm run docker:dev:clean # Stop and clean containers npm run docker:prod # Start full stack (production) npm run docker:stop # Stop all services npm run docker:logs # View container logs npm run docker:db # PostgreSQL CLI npm run docker:redis # Redis CLI npm run docker:backup # Backup database to SQL file ``` ### Local Development (without Docker) 1. Install dependencies: ```bash npm install ``` 2. Set up PostgreSQL and Redis locally 3. Configure `.env` with local database URL: ```env DATABASE_URL=postgresql://postgres:postgres@localhost:5435/qrmaster?schema=public ``` 4. Run migrations and seed: ```bash npx prisma migrate dev npm run db:seed ``` 5. Start dev server: ```bash npm run dev ``` ### Resetting the Database If you need to reset your database (drop all tables, recreate, and reseed): ```bash # Full reset (drops database, reruns migrations, seeds data) npx prisma migrate reset # Or manually: npx prisma migrate reset --skip-seed # Reset without seeding npm run db:seed # Then seed manually ``` This is useful when: - Schema has changed significantly - You have migration conflicts - You want to start fresh with clean data ### Project Structure ``` qr-master/ ├── src/ │ ├── app/ # Next.js app router pages │ ├── components/ # React components │ ├── lib/ # Utility functions and configurations │ ├── hooks/ # Custom React hooks │ ├── styles/ # Global styles │ └── i18n/ # Translation files ├── prisma/ # Database schema and migrations ├── docker/ # Docker initialization scripts │ ├── init-db.sh # PostgreSQL initialization │ └── README.md # Docker documentation ├── public/ # Static assets ├── docker-compose.yml # Production Docker setup ├── docker-compose.dev.yml # Development Docker setup ├── Dockerfile # Container definition ├── DOCKER_SETUP.md # Complete Docker guide └── env.example # Environment template ``` ## API Endpoints ### Authentication - `POST /api/auth/signin` - Sign in with credentials - `POST /api/auth/signout` - Sign out - `GET /api/auth/session` - Get current session ### QR Codes - `GET /api/qrs` - List all QR codes - `POST /api/qrs` - Create a new QR code (dynamic or static) - `POST /api/qrs/static` - Create a static QR code - `GET /api/qrs/[id]` - Get QR code details - `PATCH /api/qrs/[id]` - Update QR code - `DELETE /api/qrs/[id]` - Delete QR code - `DELETE /api/qrs/delete-all` - Delete all user's QR codes ### Analytics - `GET /api/analytics/summary` - Get analytics summary for a QR code ### User & Settings - `GET /api/user/plan` - Get current user plan - `GET /api/user/stats` - Get user statistics - `POST /api/user/password` - Update password - `POST /api/user/profile` - Update profile - `DELETE /api/user/delete` - Delete account ### Stripe Payments - `POST /api/stripe/checkout` - Create checkout session - `POST /api/stripe/portal` - Create customer portal session - `POST /api/stripe/webhook` - Handle Stripe webhooks - `POST /api/stripe/cancel-subscription` - Cancel subscription ### Public Redirect - `GET /r/[slug]` - Redirect and track QR code scan ## Environment Variables | Variable | Description | Required | Default | | ------------------------------------ | ----------------------------- | -------- | ---------------------------------------------------------------------- | | `DATABASE_URL` | PostgreSQL connection string | Yes | `postgresql://postgres:postgres@localhost:5435/qrmaster?schema=public` | | `NEXTAUTH_URL` | Application URL | Yes | `http://localhost:3050` | | `NEXTAUTH_SECRET` | Secret for JWT encryption | Yes | Generate with `openssl rand -base64 32` | | `IP_SALT` | Salt for IP hashing (privacy) | Yes | Generate with `openssl rand -base64 32` | | `GOOGLE_CLIENT_ID` | Google OAuth client ID | No | - | | `GOOGLE_CLIENT_SECRET` | Google OAuth client secret | No | - | | `STRIPE_SECRET_KEY` | Stripe secret key | No | - | | `STRIPE_WEBHOOK_SECRET` | Stripe webhook signing secret | No | - | | `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY` | Stripe public key | No | - | | `NEXT_PUBLIC_INDEXABLE` | Allow search engine indexing | No | `false` (set to `true` in production) | | `REDIS_URL` | Redis connection string | No | `redis://redis:6379` | | `NEXT_PUBLIC_POSTHOG_KEY` | PostHog analytics key | No | - | | `NEXT_PUBLIC_POSTHOG_HOST` | PostHog host URL | No | - | **Note**: Copy `env.example` to `.env` and update the values before starting. ### Generating Secrets ```bash # Generate NEXTAUTH_SECRET openssl rand -base64 32 # Generate IP_SALT openssl rand -base64 32 ``` ## Security & Privacy - **IP Hashing**: IP addresses are hashed with salt before storage (GDPR-compliant) - **DNT Respect**: Honors Do Not Track browser headers - **Rate Limiting**: API endpoints protected against abuse - **CSRF Protection**: Token-based CSRF validation on mutations - **Secure Sessions**: NextAuth.js with encrypted JWT tokens - **Stripe Security**: PCI-compliant payment processing - **SQL Injection Prevention**: Prisma ORM parameterized queries ## Database Schema The application uses PostgreSQL with Prisma ORM. Key models: - **User**: User accounts with Stripe subscription data - **QRCode**: QR code records (static/dynamic, multiple content types) - **QRScan**: Scan analytics data (hashed IP, device, location, UTM params) - **Integration**: Third-party integrations (Zapier, etc.) - **Account/Session**: NextAuth authentication data ### Supported QR Code Types - **URL**: Website links - **VCARD**: Contact cards (name, email, phone, company) - **GEO**: GPS locations - **PHONE**: Phone numbers (tel: links) - **TEXT**: Plain text - **SMS**: SMS messages - **WHATSAPP**: WhatsApp messages ### Plans - **FREE**: 3 dynamic QR codes, unlimited static - **PRO**: 50 codes, custom branding, advanced analytics - **BUSINESS**: 500 codes, bulk upload, API access, priority support ## Deployment ### Docker (Recommended for Self-Hosting) The application includes production-ready Docker configuration with PostgreSQL and Redis: ```bash # Build and start all services docker-compose up -d --build # Run migrations docker-compose exec web npx prisma migrate deploy # View logs docker-compose logs -f ``` For detailed deployment instructions, see [DOCKER_SETUP.md](DOCKER_SETUP.md). ### Vercel 1. Push your code to GitHub 2. Import the project in Vercel 3. Add a PostgreSQL database (Vercel Postgres, Supabase, or other) 4. Add environment variables in Vercel dashboard 5. Deploy **Note**: For Vercel deployment, you'll need to set up a PostgreSQL database separately. ## Troubleshooting ### Database Issues **Problem**: Migration errors or schema conflicts ```bash # Solution: Reset the database npx prisma migrate reset ``` **Problem**: "Error: P1001: Can't reach database server" ```bash # Check if Docker containers are running docker ps # Restart database npm run docker:dev:stop npm run docker:dev ``` **Problem**: Prisma Client out of sync ```bash # Regenerate Prisma Client npx prisma generate ``` **Problem**: Need to start completely fresh ```bash # Stop all Docker containers npm run docker:dev:stop # Remove volumes (⚠️ deletes all data) docker volume prune # Restart everything npm run docker:dev npx prisma migrate dev npm run db:seed ``` ### Port Already in Use If port 3050 is already in use: ```bash # Find and kill the process (Windows) netstat -ano | findstr :3050 taskkill /PID /F # Or change the port in package.json "dev": "next dev -p 3051" ``` ### Docker Issues **Problem**: Permission denied errors ```bash # Windows: Run PowerShell as Administrator # Linux/Mac: Use sudo for docker commands ``` **Problem**: Out of disk space ```bash # Clean up Docker docker system prune -a ``` ## Contributing 1. Fork the repository 2. Create your feature branch (`git checkout -b feature/amazing-feature`) 3. Commit your changes (`git commit -m 'Add some amazing feature'`) 4. Push to the branch (`git push origin feature/amazing-feature`) 5. Open a Pull Request ## License This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. ## Support For support, email support@qrmaster.net or open an issue on GitHub. ## Acknowledgments - Next.js team for the amazing framework - Vercel for hosting and deployment - All open-source contributors --- Built with ❤️ by QR Master Team