# 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      | -                                                                      |
| `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 <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



Führe diese im Terminal aus:

IndexNow (Bing/Yandex + Partner): npm run submit:indexnow
Google Indexing API: npm run trigger:indexing