Files
ebook-extension/ebook_backend&admin_panel/README.md

23 KiB

📚 Ebook Coupon Management System

A comprehensive enterprise-grade FastAPI application for managing ebook coupon codes with an admin dashboard interface and translation file management system.

Python FastAPI PostgreSQL License


📑 Table of Contents


🎯 Overview

The Ebook Coupon Management System is a production-ready web application designed to manage ebook coupon codes efficiently. It provides a secure admin interface for generating, managing, and tracking coupon usage, along with translation file management capabilities.

Key Highlights:

  • Automatic database initialization on first run
  • Auto-creates admin user from environment variables
  • RESTful API with comprehensive documentation
  • Real-time coupon generation and validation
  • Excel file support for bulk operations
  • Translation file management system
  • Comprehensive test suite included
  • Production-ready logging and error handling

🚀 Features

🔐 Authentication & Authorization

  • Secure Admin Login: Session-based authentication with HTTP-only cookies
  • Auto Admin Creation: First-time setup automatically creates admin user
  • Password Hashing: Bcrypt password encryption
  • Logout Functionality: Clean session termination

🎫 Coupon Management

Generate Coupons

  • Single Generation: Create one coupon code at a time
  • Bulk Generation: Generate multiple coupons in one operation
  • Unique Codes: 10-character alphanumeric codes (uppercase)
  • Automatic Storage: Codes saved to database with metadata

Manage Coupons

  • List All Coupons: Paginated listing with usage statistics
  • Search Functionality: Case-insensitive search by coupon code
  • Usage Tracking: One time coupon code usage and timestamps
  • Delete Coupons: Remove unwanted or expired codes
  • Add Manual Codes: Add specific coupon codes manually

Bulk Operations

  • Excel Upload: Upload multiple coupons from Excel files (.xlsx, .xls)
  • Duplicate Detection: Automatically skips existing codes
  • Validation: Ensures data integrity during bulk upload

Coupon Validation

  • Code Verification: Check if coupon exists and is valid
  • Usage Validation: Prevent reuse of single-use coupons
  • Mark as Used: Track when and how coupons are redeemed

🌐 Translation File Management

  • Upload Translation Files: Admin can upload Excel translation files
  • Download Translations: Retrieve uploaded translation files
  • Delete Translations: Remove existing translation files
  • Status Check: Verify if translation file exists
  • Metadata Storage: Preserves original filename information
  • File Validation: Ensures only valid Excel files are accepted

🖥️ Admin Dashboard

  • Modern UI: Clean, responsive interface built with vanilla JavaScript
  • Real-time Updates: Live data refresh without page reload
  • File Upload: Drag-and-drop support for Excel files
  • Pagination: Efficient browsing of large coupon lists
  • Search Interface: Quick search functionality
  • Statistics Display: View total coupons and usage

📊 System Features

  • Health Monitoring: /health endpoint for system checks
  • Database Status: Real-time database connection monitoring
  • Automatic Migrations: Tables created automatically on startup
  • Logging System: Structured JSON logging with rotation
  • Error Handling: Comprehensive exception handling
  • Request Tracking: Unique request IDs for tracing

🛠️ Technology Stack

Backend

Technology Purpose Version
FastAPI Web framework Latest
Uvicorn ASGI server Latest
SQLAlchemy ORM 2.x
PostgreSQL Database 12+
Pydantic Data validation 2.x
Passlib Password hashing Latest
Bcrypt Encryption 4.0.1
Python-Jose JWT handling Latest

Frontend

Technology Purpose
HTML5 Structure
CSS3 Styling
Vanilla JavaScript Interactivity
Fetch API HTTP requests

Development & Testing

Tool Purpose
Pytest Testing framework
HTTPx Async HTTP client
Python-dotenv Environment management

📁 Project Structure

ebook_extension-feature-admin-dashboard/
│
├── admin-backend/                   # Backend API application
│   ├── models/                      # Database models
│   │   ├── user.py                  # Admin user model
│   │   └── coupon.py                # Coupon model
│   │
│   ├── routes/                      # API routes
│   │   └── auth.py                  # All API endpoints
│   │
│   ├── utils/                       # Utility modules
│   │   ├── auth.py                  # Authentication utilities
│   │   ├── coupon_utils.py          # Coupon generation
│   │   ├── exceptions.py            # Custom exceptions
│   │   ├── logger.py                # Logging configuration
│   │   ├── template_loader.py       # Template utilities
│   │   └── timezone_utils.py        # Timezone handling
│   │
│   ├── tests/                       # Test suite
│   │   ├── conftest.py              # Test configuration
│   │   ├── test_auth_routes.py      # Auth endpoint tests
│   │   ├── test_coupon_routes.py    # Coupon endpoint tests
│   │   ├── test_main.py             # Main app tests
│   │   ├── test_models.py           # Model tests
│   │   ├── test_schemas.py          # Schema tests
│   │   ├── test_translation_routes.py # Translation tests
│   │   └── test_utils.py            # Utility tests
│   │
│   ├── logs/                        # Application logs
│   │   ├── app.log                  # General logs
│   │   └── error.log                # Error logs
│   │
│   ├── translationfile/             # Translation storage
│   │   └── translation.xlsx         # Uploaded translation file
│   │
│   ├── main.py                      # FastAPI application
│   ├── init_db.py                   # Database initialization
│   ├── schemas.py                   # Pydantic schemas
│   ├── manage_test_db.py            # Test database manager
│   └── pytest.ini                   # Pytest configuration
│
├── admin-frontend/                  # Frontend files
│   ├── admin_login.html             # Login page
│   ├── admin_login.js               # Login logic
│   ├── admin_dashboard.html         # Dashboard UI
│   └── admin_dashboard.js           # Dashboard logic
│
├── .env.example                     # Environment template
├── .gitignore                       # Git ignore rules
├── requirements.txt                 # Python dependencies
├── README.md                        
└── start.sh                         # Startup script


📋 Prerequisites

Before installing, ensure you have the following:

  • Python: Version 3.10 or higher
  • PostgreSQL: Version 12 or higher
  • pip: Python package manager
  • Virtual Environment: venv or virtualenv
  • Git: For cloning the repository

System Requirements

  • OS: Linux, macOS, or Windows
  • RAM: Minimum 2GB
  • Disk Space: Minimum 500MB

💻 Installation & Setup

Step 1: Clone the Repository

git clone <repository-url>
cd ebook_extension-feature-admin-dashboard

Step 2: Create Virtual Environment

# Create virtual environment
python3 -m venv .venv

# Activate virtual environment
# On Linux/Mac:
source .venv/bin/activate

# On Windows:
.venv\Scripts\activate

Step 3: Install Dependencies

pip install --upgrade pip
pip install -r requirements.txt

Step 4: Set Up PostgreSQL Database

Create Database

# Option 1: Using psql
sudo -u postgres psql -c "CREATE DATABASE ebook_db;"

# Option 2: Using createdb
sudo -u postgres createdb ebook_db

# Option 3: Connect to PostgreSQL and create manually
sudo -u postgres psql
postgres=# CREATE DATABASE ebook_db;
postgres=# \q

Verify Database Creation

sudo -u postgres psql -c "\l" | grep ebook_db

Step 5: Configure Environment Variables

# Copy example environment file
cp .env.example .env

# Edit with your settings
nano .env  # or your preferred editor

Required Configuration:

  • Update DATABASE_URL if using different credentials
  • Change ADMIN_PASSWORD from default
  • Generate strong SECRET_KEY for production

Step 6: Initialize Database (Automatic)

The application automatically:

  • Creates all required tables on first run
  • Creates admin user from .env credentials
  • Validates database connection

No manual database setup required!


⚙️ Environment Configuration

Environment Variables Explained

Create a .env file in the project root with these variables:

Database Configuration

# PostgreSQL connection string
DATABASE_URL=postgresql://username:password@host:port/database

# Test database (for running tests)
TEST_DATABASE_URL=postgresql://username:password@host:port/test_database

Security Configuration

# Secret key for JWT and session encryption
# Generate with: python -c "import secrets; print(secrets.token_urlsafe(32))"
SECRET_KEY=your-super-secret-key-change-this-in-production

# Debug mode (set to false in production)
DEBUG=true

# Environment: development, staging, production
ENVIRONMENT=development

Admin Credentials

# Auto-created admin user on first run
# IMPORTANT: Change these before production deployment!
ADMIN_USERNAME=admin
ADMIN_PASSWORD=admin@123

Application Configuration

# Application details
APP_NAME=Ebook Coupon Management System
APP_VERSION=1.0.0

# CORS allowed origins (comma-separated)
CORS_ORIGINS=http://localhost:3000,http://localhost:8000,http://127.0.0.1:8000

# Trusted hosts
TRUSTED_HOSTS=*

Logging Configuration

# Log level: DEBUG, INFO, WARNING, ERROR, CRITICAL
LOG_LEVEL=INFO

# Log file paths (relative to admin-backend)
LOG_FILE=logs/app.log
ERROR_LOG_FILE=logs/error.log

File Upload Configuration

# Maximum file size in bytes (10MB default)
MAX_FILE_SIZE=10485760

# Allowed file types
ALLOWED_FILE_TYPES=.xlsx,.xls

Server Configuration

# Server binding
HOST=0.0.0.0
PORT=8000

Security Best Practices

🔒 For Production:

  1. Generate strong SECRET_KEY: python -c "import secrets; print(secrets.token_urlsafe(32))"
  2. Change ADMIN_PASSWORD to a strong password (12+ characters)
  3. Set DEBUG=false
  4. Set ENVIRONMENT=production
  5. Update CORS_ORIGINS to specific domains

🚀 Running the Application

./start.sh

This script automatically:

  • Checks for .env file (creates from example if missing)
  • Activates virtual environment
  • Installs/updates dependencies
  • Starts the application with auto-reload

Method 2: Manual Start

# Navigate to backend directory
cd admin-backend

# Activate virtual environment
source ../.venv/bin/activate

# Start the server
uvicorn main:app --reload --host 0.0.0.0 --port 8000

Verify Application is Running

# Check health endpoint
curl http://localhost:8000/health

# Expected response:
# {
#   "status": "healthy",
#   "timestamp": 1762246309.91,
#   "version": "1.0.0",
#   "environment": "development",
#   "database_status": "connected"
# }

Access Points

Service URL Description
API http://localhost:8000 Main API endpoint
Admin Login http://localhost:8000/login Admin login page
Admin Dashboard http://localhost:8000/ Main dashboard (requires login)
API Docs http://localhost:8000/docs Swagger UI documentation
ReDoc http://localhost:8000/redoc Alternative API docs
Health Check http://localhost:8000/health System health status

Default Login Credentials

Username: admin
Password: admin@123

📡 API Endpoints

Authentication Endpoints

Admin Login

POST /admin/login
Content-Type: application/json

{
  "username": "admin",
  "password": "admin@123"
}

Response: 200 OK
{
  "status": "success"
}

Admin Logout

POST /admin/logout

Response: 200 OK
{
  "status": "success"
}

Coupon Management Endpoints

Generate Single Coupon

POST /generate
Content-Type: application/x-www-form-urlencoded

mode=single

Response: 200 OK
{
  "code": "A1B2C3D4E5"
}

Generate Bulk Coupons

POST /generate
Content-Type: application/x-www-form-urlencoded

mode=bulk&count=100

Response: 200 OK
{
  "codes": ["CODE1", "CODE2", ...]
}

List All Coupons

GET /list?page=1&limit=20

Response: 200 OK
{
  "codes": [
    {
      "code": "A1B2C3D4E5",
      "used_at": "2025-11-04 10:30:00 CEST",
      "usage_count": 1
    }
  ],
  "total": 100,
  "page": 1,
  "limit": 20,
  "total_pages": 5
}

Search Coupons

GET /search-codes?query=A1B2

Response: 200 OK
[
  {
    "code": "A1B2C3D4E5",
    "used": 1,
    "usage_count": 1,
    "used_at": "2025-11-04 10:30:00 CEST"
  }
]

Check Specific Coupon

GET /check-code/A1B2C3D4E5

Response: 200 OK
{
  "code": "A1B2C3D4E5",
  "used": 1
}

Verify and Use Coupon

POST /verify
Content-Type: application/json

{
  "code": "A1B2C3D4E5"
}

Response: 200 OK
{
  "message": "Coupon verified",
  "used_at": "2025-11-04 10:30:00 CEST"
}

Add Manual Coupon

POST /add-code
Content-Type: application/json

{
  "code": "CUSTOM123",
  "usage": 0
}

Response: 200 OK
{
  "message": "Code added successfully"
}

Delete Coupon

DELETE /delete-code/A1B2C3D4E5

Response: 200 OK
{
  "message": "Code deleted successfully"
}

Upload Coupons from Excel

POST /upload-codes
Content-Type: application/json

{
  "codes": [
    {"code": "CODE1", "usage": 0},
    {"code": "CODE2", "usage": 1}
  ]
}

Response: 200 OK
{
  "uploaded": 2,
  "skipped": 0,
  "total": 2
}

Translation File Endpoints

Upload Translation File

POST /upload-translations
Content-Type: multipart/form-data

file: <translation.xlsx>

Response: 200 OK
{
  "message": "Translation file uploaded successfully",
  "filename": "translation.xlsx"
}

Download Translation File

GET /download-translation

Response: 200 OK
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Content-Disposition: attachment; filename="translation.xlsx"

Delete Translation File

DELETE /delete-translation

Response: 200 OK
{
  "message": "Translation file deleted successfully"
}

Check Translation Status

GET /translations/status

Response: 200 OK
{
  "file_exists": true,
  "file_name": "translation.xlsx"
}

Get Latest Translation (Legacy)

GET /translations/latest

Response: 200 OK
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

System Endpoints

Health Check

GET /health

Response: 200 OK
{
  "status": "healthy",
  "timestamp": 1762246309.91,
  "version": "1.0.0",
  "environment": "development",
  "database_status": "connected"
}

Root Endpoint

GET /

Response: 302 Found
Location: /login (if not logged in)

🖥️ Admin Dashboard

Features

  1. Login Page (/login)

    • Secure authentication form
    • Session-based login
    • Error handling
  2. Dashboard (/)

    • Coupon generation (single/bulk)
    • Coupon listing with pagination
    • Search functionality
    • File upload for bulk operations
    • Translation file management
    • Statistics display

Usage

  1. Login: Navigate to http://localhost:8000/login
  2. Enter Credentials: Use admin username and password from .env
  3. Dashboard Access: Automatically redirected to dashboard on success
  4. Generate Coupons: Use the generation form
  5. Upload Files: Drag and drop or browse for Excel files
  6. Manage Translations: Upload, download, or delete translation files

🗄️ Database Schema

Table: admin_users

Column Type Constraints Description
id INTEGER PRIMARY KEY Auto-increment ID
username STRING UNIQUE, NOT NULL Admin username
password_hash STRING NOT NULL Bcrypt hashed password
created_at DATETIME DEFAULT NOW Account creation timestamp

Table: coupon_codes

Column Type Constraints Description
id INTEGER PRIMARY KEY Auto-increment ID
code STRING UNIQUE Coupon code
usage_count INTEGER DEFAULT 0 Number of times used
created_at DATETIME DEFAULT NOW Creation timestamp
used_at DATETIME NULLABLE Last usage timestamp

Timezone: All timestamps use Europe/Bratislava timezone for creation, Asia/Kolkata for usage.


🧪 Testing

Run All Tests

cd admin-backend
source ../.venv/bin/activate
pytest

Run Specific Test Files

# Test auth routes
pytest tests/test_auth_routes.py

# Test coupon routes
pytest tests/test_coupon_routes.py

# Test models
pytest tests/test_models.py

Run with Coverage

pytest --cov=. --cov-report=html

Test Database

Tests use a separate test database configured in TEST_DATABASE_URL.


🚢 Production Deployment

Pre-Deployment Checklist

  • Set DEBUG=false
  • Set ENVIRONMENT=production
  • Change ADMIN_PASSWORD to strong password
  • Generate secure SECRET_KEY
  • Update CORS_ORIGINS with production domains
  • Configure PostgreSQL with SSL
  • Set up Nginx reverse proxy
  • Configure SSL/TLS certificates
  • Enable firewall rules
  • Set up automated backups
  • Configure monitoring and logging

Production Environment Variables

# Database
DATABASE_URL=postgresql://dbuser:strong_password@localhost:5432/ebook_prod

# Security
SECRET_KEY=<generate-with: python -c "import secrets; print(secrets.token_urlsafe(32))">
DEBUG=false
ENVIRONMENT=production

# Admin (change after first login!)
ADMIN_USERNAME=admin
ADMIN_PASSWORD=<strong-password-here>

# CORS
CORS_ORIGINS=https://yourdomain.com,https://www.yourdomain.com
TRUSTED_HOSTS=yourdomain.com,www.yourdomain.com

# Application
APP_NAME=Ebook Coupon Management System
APP_VERSION=1.0.0
LOG_LEVEL=WARNING

# Server
HOST=0.0.0.0
PORT=8000

Deployment with Systemd

  1. Install Gunicorn

    pip install gunicorn
    
  2. Create Systemd Service File

    sudo nano /etc/systemd/system/ebook-api.service
    
    [Unit]
    Description=Ebook Coupon Management System API
    After=network.target postgresql.service
    
    [Service]
    Type=notify
    User=www-data
    Group=www-data
    WorkingDirectory=/var/www/ebook_extension-feature-admin-dashboard/admin-backend
    Environment="PATH=/var/www/ebook_extension-feature-admin-dashboard/.venv/bin"
    EnvironmentFile=/var/www/ebook_extension-feature-admin-dashboard/.env
    ExecStart=/var/www/ebook_extension-feature-admin-dashboard/.venv/bin/gunicorn \
              -w 4 \
              -k uvicorn.workers.UvicornWorker \
              --bind 0.0.0.0:8000 \
              main:app
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    
  3. Enable and Start Service

    sudo systemctl daemon-reload
    sudo systemctl enable ebook-api
    sudo systemctl start ebook-api
    sudo systemctl status ebook-api
    

Nginx Reverse Proxy

  1. Install Nginx

    sudo apt-get update
    sudo apt-get install nginx
    
  2. Create Nginx Configuration

    sudo nano /etc/nginx/sites-available/ebook-api
    
    upstream ebook_backend {
        server 127.0.0.1:8000;
    }
    
    server {
        listen 80;
        server_name yourdomain.com www.yourdomain.com;
        return 301 https://$server_name$request_uri;
    }
    
    server {
        listen 443 ssl http2;
        server_name yourdomain.com www.yourdomain.com;
    
        ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
        ssl_protocols TLSv1.2 TLSv1.3;
    
        add_header Strict-Transport-Security "max-age=31536000" always;
        add_header X-Frame-Options "SAMEORIGIN" always;
        add_header X-Content-Type-Options "nosniff" always;
    
        client_max_body_size 10M;
    
        location / {
            proxy_pass http://ebook_backend;
            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;
        }
    
        location /static {
            alias /var/www/ebook_extension-feature-admin-dashboard/admin-frontend;
            expires 30d;
        }
    }
    
  3. Enable Site

    sudo ln -s /etc/nginx/sites-available/ebook-api /etc/nginx/sites-enabled/
    sudo nginx -t
    sudo systemctl restart nginx
    

Logs and Debugging

# Application logs
tail -f admin-backend/logs/app.log

# Error logs
tail -f admin-backend/logs/error.log

# Search for errors
grep -i error admin-backend/logs/app.log

# Enable debug mode
DEBUG=true uvicorn main:app

Quick Reference Commands

# Start application (development)
./start.sh

# Start application (production)
gunicorn -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000 main:app

# Stop application
pkill -f "uvicorn main:app"

# Check if running
ps aux | grep uvicorn

# View health status
curl http://localhost:8000/health

# Database operations
sudo -u postgres psql -d ebook_db

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.


🙏 Acknowledgments

  • FastAPI team for the excellent framework
  • SQLAlchemy team for the powerful ORM
  • All contributors and users

📞 Support

For support and questions:

  • Review application logs: admin-backend/logs/
  • Check troubleshooting section above
  • Open an issue on GitHub