✨ New Features: - Complete backup lifecycle management (create, list, download, delete, cleanup) - Web-based backup interface with real-time status updates - Individual backup deletion and bulk cleanup for old backups - Docker-aware backup operations with volume persistence - Automated backup scheduling and retention policies 📁 Added Files: - backup.py - Core backup script for creating timestamped archives - docker_backup.sh - Docker-compatible backup wrapper script - app/templates/backup.html - Web interface for backup management - BACKUP_SYSTEM.md - Comprehensive backup system documentation - BACKUP_GUIDE.md - Quick reference guide for backup operations 🔧 Enhanced Files: - Dockerfile - Added backup.py copy for container availability - docker-compose.yml - Added backup volume mount for persistence - app/routes/api.py - Added backup API endpoints (create, list, delete, cleanup) - app/routes/main.py - Added backup management route - app/templates/index.html - Added backup management navigation - README.md - Updated with backup system overview and quick start 🎯 Key Improvements: - Fixed backup creation errors in Docker environment - Added Docker-aware path detection for container operations - Implemented proper error handling and user confirmation dialogs - Added real-time backup status updates via JavaScript - Enhanced data persistence with volume mounting 💡 Use Cases: - Data protection and disaster recovery - Environment migration and cloning - Development data management - Automated maintenance workflows
619 lines
18 KiB
Markdown
Executable File
619 lines
18 KiB
Markdown
Executable File
# QR Code Manager
|
||
|
||
A modern Flask web application for generating and managing QR codes with authentication and dynamic link pages.
|
||
|
||
## 🚀 Features
|
||
|
||
- **Multiple QR Code Types**: Text, URL, WiFi, Email, SMS, vCard
|
||
- **Dynamic Link Pages**: Create collections of links accessible via QR codes
|
||
- **URL Shortener**: Generate shortened URLs with custom domains and QR codes
|
||
- **Admin Authentication**: Secure login with bcrypt password hashing
|
||
- **Customizable Styling**: Different QR code styles (square, rounded, circle)
|
||
- **Logo Integration**: Add custom logos to QR codes
|
||
- **Click Tracking**: Monitor short URL usage and statistics
|
||
- **🆕 Comprehensive Backup System**: Full backup lifecycle management
|
||
- Create backups on-demand or automated
|
||
- Download, delete, and cleanup old backups
|
||
- Web-based backup management interface
|
||
- Docker-aware backup operations
|
||
- **Docker Deployment**: Production-ready containerization
|
||
- **Responsive Design**: Modern web interface that works on all devices
|
||
|
||
## 📁 Project Structure
|
||
|
||
```
|
||
qr-code_manager/
|
||
├── README.md # Project documentation
|
||
├── main.py # Application entry point
|
||
├── Dockerfile # Docker container definition
|
||
├── docker-compose.yml # Docker orchestration
|
||
├── requirements.txt # Python dependencies
|
||
├── .env.example # Environment variables template
|
||
├── deploy.sh # Deployment script
|
||
├── app/ # Main application package
|
||
│ ├── __init__.py # Flask app factory
|
||
│ ├── templates/ # Jinja2 templates
|
||
│ │ ├── index.html # Main dashboard
|
||
│ │ ├── login.html # Authentication page
|
||
│ │ ├── link_page.html # Public link display
|
||
│ │ └── edit_links.html # Link management interface
|
||
│ ├── static/ # Static files
|
||
│ │ ├── qr_codes/ # Generated QR code images
|
||
│ │ └── logos/ # Uploaded logo files
|
||
│ ├── routes/ # Route handlers
|
||
│ │ ├── __init__.py # Route package
|
||
│ │ ├── main.py # Main page routes
|
||
│ │ ├── auth.py # Authentication routes
|
||
│ │ └── api.py # API endpoints
|
||
│ └── utils/ # Utility modules
|
||
│ ├── __init__.py # Utils package
|
||
│ ├── auth.py # Authentication utilities
|
||
│ ├── qr_generator.py # QR code generation
|
||
│ ├── link_manager.py # Dynamic link management
|
||
│ ├── url_shortener.py # URL shortening utilities
|
||
│ └── data_manager.py # Data storage utilities
|
||
```
|
||
|
||
## 🛠️ Quick Start
|
||
|
||
### Method 1: Docker (Recommended)
|
||
|
||
1. **Clone and navigate to the project:**
|
||
```bash
|
||
git clone <your-repo-url>
|
||
cd qr-code_manager
|
||
```
|
||
|
||
2. **Create environment file:**
|
||
```bash
|
||
cp .env.example .env
|
||
# Edit .env with your preferred settings
|
||
```
|
||
|
||
3. **Deploy with Docker:**
|
||
```bash
|
||
./deploy.sh
|
||
```
|
||
|
||
4. **Access the application:**
|
||
- Open http://localhost:5000
|
||
- Login with: admin / admin123 (change in production!)
|
||
|
||
### Method 2: Local Development
|
||
|
||
1. **Set up Python environment:**
|
||
```bash
|
||
python -m venv .venv
|
||
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
||
```
|
||
|
||
2. **Install dependencies:**
|
||
```bash
|
||
pip install -r requirements.txt
|
||
```
|
||
|
||
3. **Run the application:**
|
||
```bash
|
||
python main.py
|
||
```
|
||
|
||
## <20> Production vs Development Modes
|
||
|
||
The QR Code Manager supports two distinct runtime modes with different behaviors and optimizations.
|
||
|
||
### 🛠️ Development Mode (Default)
|
||
|
||
**When it runs:**
|
||
- When `FLASK_ENV` is not set to "production"
|
||
- When running `python main.py` locally
|
||
- Default mode for local development
|
||
|
||
**Characteristics:**
|
||
- Uses Flask's built-in development server
|
||
- Debug mode enabled with auto-reload
|
||
- Detailed error messages and stack traces
|
||
- Console shows default login credentials
|
||
- Not suitable for production use
|
||
|
||
**How to run:**
|
||
```bash
|
||
# Method 1: Direct execution
|
||
python main.py
|
||
|
||
# Method 2: With explicit development environment
|
||
FLASK_ENV=development python main.py
|
||
|
||
# Method 3: Using environment file
|
||
echo "FLASK_ENV=development" > .env
|
||
python main.py
|
||
```
|
||
|
||
**Console output in development:**
|
||
```
|
||
🛠️ Starting QR Code Manager in DEVELOPMENT mode
|
||
🔐 Admin user: admin
|
||
🔑 Default password: admin123
|
||
🌐 Domain configured: localhost:5000
|
||
🔗 URL shortener available at: /s/
|
||
* Serving Flask app 'app'
|
||
* Debug mode: on
|
||
* Running on all addresses (0.0.0.0)
|
||
* Running on http://127.0.0.1:5000
|
||
```
|
||
|
||
### 🚀 Production Mode
|
||
|
||
**When it runs:**
|
||
- When `FLASK_ENV=production` is set
|
||
- When deployed with Docker (automatic)
|
||
- For live/production deployments
|
||
|
||
**Characteristics:**
|
||
- Uses Gunicorn WSGI server (4 workers)
|
||
- Debug mode disabled
|
||
- Optimized for performance and security
|
||
- No default credentials shown
|
||
- Production-grade error handling
|
||
|
||
**How to run:**
|
||
|
||
#### Option 1: Docker (Recommended)
|
||
```bash
|
||
# Copy and edit production environment
|
||
cp .env.production .env
|
||
# Edit .env with your production settings
|
||
|
||
# Deploy with Docker
|
||
docker-compose up -d
|
||
```
|
||
|
||
#### Option 2: Manual Gunicorn
|
||
```bash
|
||
# Set production environment
|
||
export FLASK_ENV=production
|
||
export SECRET_KEY=your-super-secret-key
|
||
export ADMIN_USERNAME=your-admin-username
|
||
export ADMIN_PASSWORD=your-secure-password
|
||
export APP_DOMAIN=your-domain.com
|
||
|
||
# Run with Gunicorn
|
||
gunicorn -c gunicorn.conf.py main:app
|
||
```
|
||
|
||
#### Option 3: Environment File + Gunicorn
|
||
```bash
|
||
# Create production environment file
|
||
cp .env.production .env
|
||
|
||
# Edit .env with your settings:
|
||
# FLASK_ENV=production
|
||
# SECRET_KEY=your-super-secret-key
|
||
# ADMIN_USERNAME=your-admin-username
|
||
# ADMIN_PASSWORD=your-secure-password
|
||
# APP_DOMAIN=your-domain.com
|
||
|
||
# Run with Gunicorn
|
||
gunicorn -c gunicorn.conf.py main:app
|
||
```
|
||
|
||
**Console output in production:**
|
||
```
|
||
Admin user initialized: your-admin-username
|
||
Default password: your-secure-password
|
||
[2025-07-16 17:27:27 +0000] [1] [INFO] Starting gunicorn 21.2.0
|
||
[2025-07-16 17:27:27 +0000] [1] [INFO] Listening at: http://0.0.0.0:5000 (1)
|
||
[2025-07-16 17:27:27 +0000] [1] [INFO] Using worker: sync
|
||
[2025-07-16 17:27:27 +0000] [7] [INFO] Booting worker with pid: 7
|
||
[2025-07-16 17:27:27 +0000] [8] [INFO] Booting worker with pid: 8
|
||
[2025-07-16 17:27:27 +0000] [9] [INFO] Booting worker with pid: 9
|
||
[2025-07-16 17:27:27 +0000] [10] [INFO] Booting worker with pid: 10
|
||
```
|
||
|
||
### 🔧 Environment Configuration
|
||
|
||
Create a `.env` file in the project root with your configuration:
|
||
|
||
**For Development:**
|
||
```bash
|
||
# Development settings
|
||
FLASK_ENV=development
|
||
SECRET_KEY=dev-secret-key
|
||
ADMIN_USERNAME=admin
|
||
ADMIN_PASSWORD=admin123
|
||
APP_DOMAIN=localhost:5000
|
||
```
|
||
|
||
**For Production:**
|
||
```bash
|
||
# Production settings (copy from .env.production and customize)
|
||
FLASK_ENV=production
|
||
SECRET_KEY=your-super-secret-key-change-this
|
||
ADMIN_USERNAME=your-admin-username
|
||
ADMIN_PASSWORD=your-secure-password
|
||
APP_DOMAIN=your-domain.com
|
||
|
||
# Security settings
|
||
SESSION_COOKIE_SECURE=true # Set to true for HTTPS
|
||
SESSION_COOKIE_HTTPONLY=true
|
||
SESSION_COOKIE_SAMESITE=Lax
|
||
|
||
# Performance settings
|
||
UPLOAD_MAX_SIZE=10485760 # 10MB
|
||
CACHE_TIMEOUT=3600 # 1 hour
|
||
```
|
||
|
||
### 🛡️ Security Considerations
|
||
|
||
**Development Mode:**
|
||
- ⚠️ Never use in production
|
||
- Default credentials are visible
|
||
- Debug information exposed
|
||
- Single-threaded server
|
||
|
||
**Production Mode:**
|
||
- ✅ Use Gunicorn WSGI server
|
||
- ✅ Change default credentials
|
||
- ✅ Use strong SECRET_KEY
|
||
- ✅ Enable HTTPS when possible
|
||
- ✅ Set secure cookie flags
|
||
- ✅ Multiple worker processes
|
||
|
||
### 📊 Performance Comparison
|
||
|
||
| Feature | Development | Production |
|
||
|---------|-------------|------------|
|
||
| Server | Flask dev server | Gunicorn (4 workers) |
|
||
| Performance | Basic | Optimized |
|
||
| Concurrency | Single-threaded | Multi-worker |
|
||
| Auto-reload | Yes | No |
|
||
| Debug info | Full | Minimal |
|
||
| Error handling | Verbose | Secure |
|
||
| Session security | Basic | Enhanced |
|
||
|
||
## <20>🔐 Authentication
|
||
|
||
- **Default Credentials**: admin / admin123
|
||
- **Environment Variables**:
|
||
- `ADMIN_USERNAME`: Set custom admin username
|
||
- `ADMIN_PASSWORD`: Set custom admin password
|
||
- `SECRET_KEY`: Set Flask secret key for sessions
|
||
|
||
## 🐳 Docker Deployment
|
||
|
||
The application is fully containerized with Docker:
|
||
|
||
- **Build and run**: `docker-compose up -d`
|
||
- **View logs**: `docker-compose logs -f`
|
||
- **Stop**: `docker-compose down`
|
||
- **Full rebuild**: `docker-compose up --build -d`
|
||
|
||
### Production Configuration
|
||
|
||
1. **Set environment variables in .env:**
|
||
```bash
|
||
FLASK_ENV=production
|
||
SECRET_KEY=your-super-secret-key-here
|
||
ADMIN_USERNAME=your-admin-username
|
||
ADMIN_PASSWORD=your-secure-password
|
||
APP_DOMAIN=[your-domain] # Your custom domain for URL shortener
|
||
```
|
||
|
||
2. **Deploy:**
|
||
```bash
|
||
docker-compose up -d
|
||
```
|
||
|
||
### URL Shortener Configuration
|
||
|
||
The URL shortener feature uses the `APP_DOMAIN` environment variable to generate short URLs:
|
||
|
||
- **Development**: `APP_DOMAIN=localhost:5000`
|
||
- **Production**: `APP_DOMAIN=[your-domain]` or `APP_DOMAIN=https://[your-domain]`
|
||
|
||
Short URLs will be available at: `https://[your-domain]/s/[short-code]`
|
||
|
||
## 🌐 Reverse Proxy Configuration (Nginx)
|
||
|
||
When deploying behind a reverse proxy like Nginx Proxy Manager or standard Nginx, configure the proxy to route **HTTPS traffic to HTTP backend**:
|
||
|
||
### ⚠️ Important Proxy Configuration
|
||
|
||
- **Frontend (Public)**: HTTPS (Port 443)
|
||
- **Backend (Docker)**: HTTP (Port 8066)
|
||
- **SSL Termination**: At the proxy level
|
||
|
||
### Nginx Proxy Manager Setup
|
||
|
||
1. **Create Proxy Host**:
|
||
- Domain: `[your-domain]` (your domain)
|
||
- Forward Hostname/IP: `your-server-ip`
|
||
- Forward Port: `8066`
|
||
- **Protocol**: HTTP (not HTTPS)
|
||
|
||
2. **SSL Configuration**:
|
||
- Enable SSL certificate (Let's Encrypt)
|
||
- Force SSL: Yes
|
||
- HTTP/2 Support: Yes
|
||
|
||
3. **Advanced Settings** (if needed):
|
||
```nginx
|
||
# Custom Nginx configuration
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
```
|
||
|
||
### Standard Nginx Configuration
|
||
|
||
```nginx
|
||
server {
|
||
listen 443 ssl http2;
|
||
server_name [your-domain];
|
||
|
||
# SSL Configuration
|
||
ssl_certificate /path/to/ssl/cert.pem;
|
||
ssl_certificate_key /path/to/ssl/private.key;
|
||
|
||
# Proxy to Docker container
|
||
location / {
|
||
proxy_pass http://localhost:8066; # Note: HTTP, not HTTPS
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
proxy_set_header X-Forwarded-Host $host;
|
||
proxy_set_header X-Forwarded-Port $server_port;
|
||
}
|
||
}
|
||
|
||
# Redirect HTTP to HTTPS
|
||
server {
|
||
listen 80;
|
||
server_name [your-domain];
|
||
return 301 https://$server_name$request_uri;
|
||
}
|
||
```
|
||
|
||
### Common Proxy Issues & Solutions
|
||
|
||
| Issue | Cause | Solution |
|
||
|-------|-------|----------|
|
||
| 502 Bad Gateway | HTTPS→HTTPS routing | Change backend to HTTP |
|
||
| SSL errors | Missing certificates | Configure SSL at proxy level |
|
||
| 404 on subpaths | Missing headers | Add proxy headers |
|
||
| Session issues | Domain mismatch | Set correct `APP_DOMAIN` |
|
||
|
||
### Docker Configuration for Proxy
|
||
|
||
Ensure your `docker-compose.yml` exposes the correct port:
|
||
|
||
```yaml
|
||
services:
|
||
qr-manager:
|
||
ports:
|
||
- "8066:5000" # Maps container port 5000 to host port 8066
|
||
environment:
|
||
- APP_DOMAIN=[your-domain] # Your public domain
|
||
```
|
||
|
||
## 📱 Usage
|
||
|
||
### Generating QR Codes
|
||
|
||
1. **Login** to the admin interface
|
||
2. **Select QR type**: Text, URL, WiFi, Email, SMS, or vCard
|
||
3. **Fill in the details** for your chosen type
|
||
4. **Customize appearance**: Size, colors, style, border
|
||
5. **Add logo** (optional): Upload custom logo for branding
|
||
6. **Generate and download** your QR code
|
||
|
||
### Dynamic Link Pages
|
||
|
||
1. **Create a link page** from the main interface
|
||
2. **Add links** to your collection via the edit interface
|
||
3. **Share the QR code** that points to your link page
|
||
4. **Update links anytime** without changing the QR code
|
||
|
||
### URL Shortener
|
||
|
||
1. **Create shortened URLs** with optional custom codes
|
||
2. **Generate QR codes** for shortened URLs
|
||
3. **Track clicks** and monitor usage statistics
|
||
4. **Redirect seamlessly** from short URLs to original destinations
|
||
5. **Integrate with link pages** by enabling shortener for individual links
|
||
|
||
**Examples:**
|
||
- Original: `https://very-long-domain.com/extremely/long/path/to/resource`
|
||
- Short: `https://[your-domain]/s/abc123`
|
||
|
||
## 🛡️ Security Features
|
||
|
||
- **Password Hashing**: Uses bcrypt for secure password storage
|
||
- **Session Management**: Secure Flask sessions with signing
|
||
- **Authentication Required**: All admin functions require login
|
||
- **Docker Security**: Non-root user in container
|
||
- **Environment Variables**: Sensitive data via environment configuration
|
||
|
||
## 🔧 Development
|
||
|
||
### Project Architecture
|
||
|
||
The application follows a modular Flask structure:
|
||
|
||
- **App Factory Pattern**: Clean application initialization
|
||
- **Blueprint Organization**: Separate route modules for different features
|
||
- **Utility Modules**: Reusable components for QR generation, auth, etc.
|
||
- **Template Organization**: Structured Jinja2 templates
|
||
- **Static File Management**: Organized asset storage
|
||
|
||
### Adding New Features
|
||
|
||
1. **New Routes**: Add to appropriate blueprint in `app/routes/`
|
||
2. **New Utilities**: Create modules in `app/utils/`
|
||
3. **New Templates**: Add to `app/templates/`
|
||
4. **New Dependencies**: Update `requirements.txt`
|
||
|
||
## 📊 API Endpoints
|
||
|
||
### QR Code Management
|
||
- `POST /api/generate` - Generate QR code
|
||
- `GET /api/qr_codes` - List all QR codes
|
||
- `GET /api/qr_codes/{id}` - Get specific QR code
|
||
- `DELETE /api/qr_codes/{id}` - Delete QR code
|
||
|
||
### Dynamic Link Pages
|
||
- `POST /api/create_link_page` - Create dynamic link page
|
||
- `POST /api/link_pages/{id}/links` - Add link to page
|
||
- `PUT /api/link_pages/{id}/links/{link_id}` - Update link
|
||
- `DELETE /api/link_pages/{id}/links/{link_id}` - Delete link
|
||
|
||
### URL Shortener
|
||
- `POST /api/shorten` - Create standalone short URL
|
||
- `POST /api/generate_shortened_qr` - Generate QR code with short URL
|
||
- `GET /api/short_urls` - List all short URLs
|
||
- `GET /api/short_urls/{code}/stats` - Get short URL statistics
|
||
- `GET /s/{code}` - Redirect short URL to original
|
||
- `POST /api/link_pages/{id}/links` - Add link to page
|
||
- `PUT /api/link_pages/{id}/links/{link_id}` - Update link
|
||
- `DELETE /api/link_pages/{id}/links/{link_id}` - Delete link
|
||
|
||
## 🚨 Troubleshooting
|
||
|
||
### Common Issues
|
||
|
||
1. **Permission Denied**: Ensure Docker has proper permissions
|
||
2. **Port 5000 in use**: Change port in docker-compose.yml
|
||
3. **Authentication Failed**: Check admin credentials in .env
|
||
4. **Image Generation Failed**: Verify PIL/Pillow installation
|
||
|
||
### Health Check
|
||
|
||
Visit `/health` to check application status:
|
||
```bash
|
||
curl http://localhost:5000/health
|
||
```
|
||
|
||
## 📝 License
|
||
|
||
This project is licensed under the MIT License - see the LICENSE file for details.
|
||
|
||
## 💾 Backup & Restore System
|
||
|
||
The QR Code Manager includes a comprehensive backup system for data protection and migration.
|
||
|
||
### Quick Start
|
||
|
||
**Create Backup:**
|
||
- Via Web: Navigate to backup management page → "Create Backup"
|
||
- Via API: `curl -X POST http://localhost:8066/api/backup/create`
|
||
- Via CLI: `python backup.py` or `./docker_backup.sh`
|
||
|
||
**Manage Backups:**
|
||
- **List**: View all backups with timestamps and sizes
|
||
- **Download**: Get backup files directly from web interface
|
||
- **Delete**: Remove individual backups with confirmation
|
||
- **Cleanup**: Bulk remove backups older than 7 days
|
||
|
||
### What Gets Backed Up
|
||
|
||
Each backup includes:
|
||
- ✅ All QR code data and metadata
|
||
- ✅ Short URL database
|
||
- ✅ Dynamic link page configurations
|
||
- ✅ Generated QR code images
|
||
- ✅ Application settings
|
||
|
||
### Restore Process
|
||
|
||
```bash
|
||
# 1. Stop application
|
||
docker compose down
|
||
|
||
# 2. Extract backup to data directory
|
||
cd data/
|
||
unzip ../backups/backup_20250801_143022.zip
|
||
|
||
# 3. Restart application
|
||
docker compose up -d
|
||
```
|
||
|
||
### Automated Backups
|
||
|
||
**Daily Backup (2 AM):**
|
||
```bash
|
||
0 2 * * * cd /opt/qr-code_manager && ./docker_backup.sh
|
||
```
|
||
|
||
**Weekly Cleanup:**
|
||
```bash
|
||
0 3 * * 0 curl -X POST http://localhost:8066/api/backup/cleanup
|
||
```
|
||
|
||
> 📖 **Detailed Documentation**: See [BACKUP_SYSTEM.md](BACKUP_SYSTEM.md) for complete backup system documentation.
|
||
|
||
## 🤝 Contributing
|
||
|
||
1. Fork the repository
|
||
2. Create a feature branch
|
||
3. Make your changes
|
||
4. Add tests if applicable
|
||
5. Submit a pull request
|
||
|
||
## 🧹 Data Cleanup for Deployment
|
||
|
||
When preparing for a fresh deployment or when you need to clear all data, use the provided cleanup scripts:
|
||
|
||
### Option 1: Python Script (Recommended)
|
||
|
||
```bash
|
||
python clean_data.py
|
||
```
|
||
|
||
### Option 2: Shell Script (Quick)
|
||
|
||
```bash
|
||
./clean_data.sh
|
||
```
|
||
|
||
### What Gets Cleaned
|
||
|
||
Both scripts will remove:
|
||
|
||
- **All QR codes and their data** - Clears the QR codes database and deletes all generated PNG images
|
||
- **All dynamic link pages** - Removes all link collections and their settings
|
||
- **All short URLs** - Clears the URL shortener database
|
||
- **All Flask sessions** - Removes user session files
|
||
- **All log files** - Deletes any application log files
|
||
- **Python cache files** - Removes `__pycache__` directories and `.pyc` files
|
||
|
||
### Safety Features
|
||
|
||
- **Confirmation prompt** - Both scripts require typing 'YES' to confirm the action
|
||
- **Directory preservation** - Required directories are recreated after cleanup
|
||
- **Error handling** - Scripts handle missing files/directories gracefully
|
||
|
||
### Post-Cleanup Steps
|
||
|
||
After running the cleanup script:
|
||
|
||
1. Start the application: `python main.py`
|
||
2. Login with default credentials: `admin` / `admin123`
|
||
3. **Important**: Change the default admin password immediately
|
||
4. Begin creating your QR codes and link pages
|
||
|
||
### Use Cases
|
||
|
||
- **Fresh deployment** - Clean slate for production deployment
|
||
- **Development reset** - Clear test data during development
|
||
- **Data migration** - Prepare for moving to a new system
|
||
- **Security cleanup** - Remove all data when decommissioning
|
||
|
||
## 📞 Support
|
||
|
||
For support, please open an issue on GitHub or contact the development team.
|
||
|
||
---
|
||
|
||
**Made with ❤️ for easy QR code management**
|