19. Deployment & Operations

19.1 Build Process

Development Build

Backend (Development)

cd packages/local-backend
python -m uvicorn app.main:app --reload --port 8000

Frontend (Development)

cd packages/desktop-app
npm run dev

Development Server URLs:

  • Backend API: http://localhost:8000
  • Frontend: http://localhost:5173
  • API Docs: http://localhost:8000/docs

Production Build

Desktop App (Electron)

cd packages/desktop-app

# Build frontend
npm run build

# Package desktop app
npm run electron:build

Electron Builder Configuration

File: electron-builder.json

{
  "appId": "com.currency.calculator",
  "productName": "Currency Denomination Calculator",
  "directories": {
    "buildResources": "build",
    "output": "dist-electron"
  },
  "files": [
    "dist/**/*",
    "dist-electron/**/*",
    "package.json"
  ],
  "win": {
    "target": ["nsis", "portable"],
    "icon": "build/icon.ico",
    "artifactName": "${productName}-${version}-${arch}.${ext}"
  },
  "nsis": {
    "oneClick": false,
    "allowToChangeInstallationDirectory": true,
    "createDesktopShortcut": true,
    "createStartMenuShortcut": true
  },
  "portable": {
    "artifactName": "${productName}-${version}-portable.exe"
  }
}

Build Outputs

Format File Size Use Case
NSIS Installer CurrencyCalculator-1.0.0-win.exe ~80 MB Standard installation
Portable CurrencyCalculator-1.0.0-portable.exe ~80 MB No installation required

19.2 Backend Deployment

Local Deployment (Default)

# Start backend server
cd packages/local-backend
python -m uvicorn app.main:app --host 127.0.0.1 --port 8000

# With production settings
python -m uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4

Configuration:

  • --host 127.0.0.1: Localhost only (secure)
  • --host 0.0.0.0: All network interfaces
  • --port 8000: Default API port
  • --workers 4: Multiple worker processes
  • --reload: Auto-reload on code changes (dev only)

Windows Service Deployment

Run backend as Windows Service (always running)

Using NSSM (Non-Sucking Service Manager)

# Download NSSM from https://nssm.cc/download

# Install service
nssm install CurrencyCalculatorAPI "C:\Python311\python.exe"
nssm set CurrencyCalculatorAPI AppParameters "-m uvicorn app.main:app --host 127.0.0.1 --port 8000"
nssm set CurrencyCalculatorAPI AppDirectory "C:\path\to\packages\local-backend"
nssm set CurrencyCalculatorAPI DisplayName "Currency Calculator API"
nssm set CurrencyCalculatorAPI Description "Backend API for Currency Denomination Calculator"

# Start service
nssm start CurrencyCalculatorAPI

# Stop service
nssm stop CurrencyCalculatorAPI

# Remove service
nssm remove CurrencyCalculatorAPI confirm

Production Configuration

Environment Variables

# .env.production
DATABASE_URL=sqlite:///./currency_calculator_prod.db
LOG_LEVEL=INFO
ALLOWED_ORIGINS=http://localhost:5173
MAX_UPLOAD_SIZE=10485760  # 10MB
CORS_ENABLED=true

Logging Configuration

# app/config/logging.py
import logging
from logging.handlers import RotatingFileHandler

def setup_logging():
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)
    
    # File handler with rotation
    file_handler = RotatingFileHandler(
        'logs/api.log',
        maxBytes=10*1024*1024,  # 10MB
        backupCount=5
    )
    
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )
    file_handler.setFormatter(formatter)
    
    logger.addHandler(file_handler)

19.3 Database Management

Backup Strategy

Manual Backup

# Backup database file
$date = Get-Date -Format "yyyyMMdd_HHmmss"
Copy-Item currency_calculator.db "backups\backup_$date.db"

# Verify backup
if (Test-Path "backups\backup_$date.db") {
    Write-Host "Backup created successfully" -ForegroundColor Green
}

Automated Backup Script

File: backup-database.ps1

param(
    [int]$RetentionDays = 30
)

$backupDir = "backups"
$dbFile = "currency_calculator.db"
$date = Get-Date -Format "yyyyMMdd_HHmmss"
$backupFile = "$backupDir\backup_$date.db"

# Create backup directory
if (-not (Test-Path $backupDir)) {
    New-Item -ItemType Directory -Path $backupDir | Out-Null
}

# Create backup
Write-Host "Creating backup..." -ForegroundColor Cyan
Copy-Item $dbFile $backupFile

# Verify backup
$originalSize = (Get-Item $dbFile).Length
$backupSize = (Get-Item $backupFile).Length

if ($originalSize -eq $backupSize) {
    Write-Host "? Backup successful: $backupFile" -ForegroundColor Green
} else {
    Write-Host "? Backup failed: Size mismatch" -ForegroundColor Red
    exit 1
}

# Cleanup old backups
Write-Host "Cleaning up old backups (retention: $RetentionDays days)..." -ForegroundColor Cyan
$cutoffDate = (Get-Date).AddDays(-$RetentionDays)
Get-ChildItem -Path $backupDir -Filter "backup_*.db" | 
    Where-Object { $_.LastWriteTime -lt $cutoffDate } |
    ForEach-Object {
        Remove-Item $_.FullName
        Write-Host "  Deleted: $($_.Name)" -ForegroundColor Yellow
    }

Write-Host "? Backup process complete" -ForegroundColor Green

Schedule Automated Backup (Windows Task Scheduler)

# Create scheduled task (run daily at 2 AM)
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
    -Argument "-File C:\path\to\backup-database.ps1"
    
$trigger = New-ScheduledTaskTrigger -Daily -At 2am

Register-ScheduledTask -TaskName "CurrencyCalculator-Backup" `
    -Action $action -Trigger $trigger `
    -Description "Daily database backup for Currency Calculator"

Database Restore

# Stop backend service
Stop-Process -Name "python" -Force

# Restore from backup
$backupFile = "backups\backup_20250115_140000.db"
Copy-Item $backupFile "currency_calculator.db" -Force

# Restart backend
python -m uvicorn app.main:app --reload

Database Migration

Using Alembic for schema migrations

# Initialize Alembic
alembic init migrations

# Create migration
alembic revision --autogenerate -m "Add new column"

# Apply migration
alembic upgrade head

# Rollback migration
alembic downgrade -1

19.4 Monitoring & Logging

Log Files

Log File Content Retention
logs/api.log API requests, errors 5 files × 10MB
logs/ocr.log OCR processing logs 3 files × 10MB
logs/calculation.log Calculation engine logs 3 files × 10MB

Health Check System

File: health-check.ps1

Write-Host "=== Currency Calculator Health Check ===" -ForegroundColor Cyan
Write-Host ""

# 1. Check Backend API
Write-Host "[1/4] Checking Backend API..." -ForegroundColor Yellow
try {
    $response = Invoke-RestMethod -Uri "http://localhost:8000/health" -TimeoutSec 5
    Write-Host "  ? Backend: HEALTHY" -ForegroundColor Green
    Write-Host "    Database: $($response.database)"
    Write-Host "    Version: $($response.version)"
} catch {
    Write-Host "  ? Backend: OFFLINE" -ForegroundColor Red
}

# 2. Check Database
Write-Host "[2/4] Checking Database..." -ForegroundColor Yellow
if (Test-Path "currency_calculator.db") {
    $dbSize = (Get-Item "currency_calculator.db").Length / 1MB
    Write-Host "  ? Database: $($dbSize.ToString('F2')) MB" -ForegroundColor Green
    
    if ($dbSize > 50) {
        Write-Host "    ? WARNING: Database > 50MB (consider cleanup)" -ForegroundColor Yellow
    }
} else {
    Write-Host "  ? Database: NOT FOUND" -ForegroundColor Red
}

# 3. Check Tesseract OCR
Write-Host "[3/4] Checking Tesseract OCR..." -ForegroundColor Yellow
try {
    $tesseractVersion = & tesseract --version 2>&1 | Select-Object -First 1
    Write-Host "  ? Tesseract: $tesseractVersion" -ForegroundColor Green
} catch {
    Write-Host "  ? Tesseract: NOT FOUND" -ForegroundColor Red
}

# 4. Check Poppler (PDF processing)
Write-Host "[4/4] Checking Poppler..." -ForegroundColor Yellow
try {
    $popplerVersion = & pdftoppm -v 2>&1 | Select-Object -First 1
    Write-Host "  ? Poppler: $popplerVersion" -ForegroundColor Green
} catch {
    Write-Host "  ? Poppler: NOT FOUND" -ForegroundColor Red
}

Write-Host ""
Write-Host "=== Health Check Complete ===" -ForegroundColor Cyan

19.5 Maintenance Tasks

Regular Maintenance Checklist

Daily Tasks

  • ? Monitor log files for errors
  • ? Check database size
  • ? Verify backups are running

Weekly Tasks

  • ? Review backup retention
  • ? Test restore procedure
  • ? Check disk space
  • ? Update dependencies (security patches)

Monthly Tasks

  • ? Database vacuum (optimize)
  • ? Clean up old log files
  • ? Review performance metrics
  • ? Update Tesseract/Poppler if needed

Database Optimization

# SQLite VACUUM (reclaim space)
sqlite3 currency_calculator.db "VACUUM;"

# Analyze tables (update statistics)
sqlite3 currency_calculator.db "ANALYZE;"

# Check integrity
sqlite3 currency_calculator.db "PRAGMA integrity_check;"

Log Cleanup

# Remove logs older than 30 days
$cutoffDate = (Get-Date).AddDays(-30)
Get-ChildItem -Path "logs" -Filter "*.log*" | 
    Where-Object { $_.LastWriteTime -lt $cutoffDate } |
    Remove-Item -Force
? Section Complete

This section covers deployment processes: Development build (backend: uvicorn, frontend: npm run dev), Production build (Electron packaging with NSIS/Portable), Backend deployment (local server, Windows Service with NSSM), Database management (backup/restore scripts, automated backups with Task Scheduler, Alembic migrations), Monitoring & logging (rotating file handlers, health check script), Maintenance tasks (daily/weekly/monthly checklists, database optimization, log cleanup).