Skip to content

Purcell-Analytics/package_optimizer

Repository files navigation

PackageSorter

A production-ready, full-stack package classification and sorting system built with React, FastAPI, and Django.

📋 Technical Challenge? If you're reviewing the Thoughtful Automation technical challenge submission, see TECHNICAL_CHALLENGE.md for:

  • Core sort() function implementation
  • 45 comprehensive unit tests (100% pass rate)
  • Quick testing instructions
  • Challenge requirements checklist

Overview

PackageSorter is an automated package classification system that categorizes packages into three categories based on their physical dimensions and weight, enabling efficient routing and handling decisions.

Classification Categories

  • STANDARD: Packages that can be handled automatically (not bulky and not heavy)
  • SPECIAL: Packages requiring manual handling (bulky OR heavy, but not both)
  • REJECTED: Packages that cannot be processed (both bulky AND heavy)

Classification Rules

Bulky Package: A package is considered bulky if:

  • Its volume (Width × Height × Length) ≥ 1,000,000 cm³, OR
  • Any dimension (height, width, or length) ≥ 150 cm

Heavy Package: A package is considered heavy if:

  • Its weight ≥ 20 kg

Core Sorting Function

The heart of PackageSorter is the sort() function, which implements the classification logic:

from sort_function import sort

# Returns: "STANDARD", "SPECIAL", or "REJECTED"
result = sort(width=10, height=10, length=10, mass=5)
print(result)  # → "STANDARD"

Quick Test:

# Run demonstration
python sort_function.py

# Run test suite (45 tests)
python test_sort_function.py

For complete documentation of the core function, see TECHNICAL_CHALLENGE.md.

Technology Stack

Frontend

  • React 19 - Modern UI library with latest features
  • TypeScript 5.9 - Type-safe development
  • Vite 7 - Lightning-fast build tool and dev server
  • Tailwind CSS 3 - Utility-first CSS framework
  • Axios - HTTP client for API communication

API Layer

  • FastAPI 0.104+ - High-performance Python web framework
  • Pydantic 2 - Data validation using Python type hints
  • Uvicorn - Lightning-fast ASGI server

Backend

  • Django 4.2+ - Robust web framework with ORM
  • Django REST Framework - Powerful toolkit for building Web APIs
  • PostgreSQL 15 - Production database (SQLite for development)
  • psycopg2 - PostgreSQL adapter for Python

DevOps & Deployment

  • Docker - Containerization
  • Docker Compose - Multi-container orchestration
  • Nginx - Reverse proxy and static file serving
  • Gunicorn - Production WSGI server

Additional Tools

  • OR-Tools - Advanced optimization capabilities (future features)
  • pandas - Data manipulation and analysis (future features)
  • python-decouple - Environment variable management

Architecture

3-Layer Stack Design

┌─────────────────────────────────────────────┐
│  Frontend (React + TypeScript + Vite)      │
│  Port: 5173 (dev) / 80,443 (prod)          │
│  ─────────────────────────────────────────  │
│  • Package entry form                       │
│  • JSON bulk upload                         │
│  • Real-time classification results         │
│  • Responsive Tailwind UI                   │
└─────────────────────────────────────────────┘
                    ↓ HTTP/REST
┌─────────────────────────────────────────────┐
│  API Layer (FastAPI)                        │
│  Port: 8000                                 │
│  ─────────────────────────────────────────  │
│  • POST /packages/sort/                     │
│  • CRUD endpoints for packages              │
│  • Django ORM integration                   │
│  • Interactive API docs (Swagger)           │
└─────────────────────────────────────────────┘
                    ↓ ORM
┌─────────────────────────────────────────────┐
│  Backend (Django + Database)                │
│  Port: 8001                                 │
│  ─────────────────────────────────────────  │
│  • Package model with UUID                  │
│  • Admin interface                          │
│  • PostgreSQL/SQLite persistence            │
│  • Migration management                     │
└─────────────────────────────────────────────┘

Why This Architecture?

  • Separation of Concerns: Each layer has a distinct responsibility
  • Scalability: Layers can be scaled independently
  • Developer Experience: FastAPI for modern async APIs, Django for robust data management
  • Flexibility: Easy to swap components or add new services
  • Performance: FastAPI's speed + Django's maturity

Quick Start

Prerequisites

Installation & Running

  1. Clone and navigate to the project:

    cd package_optimizer
  2. Start all services:

    ./scripts/start.sh

    This automated script will:

    • Create and activate a Python virtual environment
    • Install all Python dependencies
    • Run Django database migrations
    • Start Django backend server (port 8001)
    • Start FastAPI API server (port 8000)
    • Install frontend dependencies
    • Start Vite development server (port 5173)
  3. Access the application:

Management Commands

# Check service status
./scripts/status.sh

# Stop all services
./scripts/stop.sh

# Restart services
./scripts/stop.sh && ./scripts/start.sh

# Initialize admin user (username: admin, password: admin123)
./scripts/init_db.sh

# Test API endpoints
python scripts/test_api.py

Features

Frontend Features

  • Manual Entry: Add packages individually with form validation
  • Bulk Upload: Upload JSON files with multiple packages
  • Real-time Classification: Instant categorization with visual feedback
  • Summary Dashboard: Count cards for each category (STANDARD, SPECIAL, REJECTED)
  • Responsive Design: Mobile-friendly interface built with Tailwind CSS
  • Visual Indicators: Color-coded categories and status badges

API Endpoints

Classification Endpoint

POST /packages/sort/

Classify and sort packages based on dimensions and weight.

Request:

{
  "packages": [
    {
      "name": "Small Box",
      "height": 10,
      "width": 10,
      "length": 10,
      "weight": 5
    }
  ]
}

Response:

{
  "packages": [
    {
      "name": "Small Box",
      "height": 10,
      "width": 10,
      "length": 10,
      "weight": 5,
      "volume": 1000,
      "category": "STANDARD",
      "isBulky": false,
      "isHeavy": false
    }
  ]
}

CRUD Operations

  • GET /packages/ - List all packages with timestamps
  • POST /packages/ - Create a new package in database
  • GET /packages/{package_id}/ - Retrieve specific package
  • PUT /packages/{package_id}/ - Update package details
  • DELETE /packages/{package_id}/ - Delete package

Documentation

Project Structure

package_optimizer/
├── sort_function.py           # ⭐ Core sorting function (challenge solution)
├── test_sort_function.py      # ⭐ 45 unit tests with 100% pass rate
├── TECHNICAL_CHALLENGE.md     # ⭐ Technical challenge documentation
│
├── api/                       # FastAPI Application Layer
│   └── main.py               # API routes, classification logic, Pydantic models
│
├── backend/                   # Django Backend
│   ├── core/                 # Core Django app
│   │   ├── models.py         # Package model (UUID, dimensions, timestamps)
│   │   ├── admin.py          # Django admin configuration
│   │   ├── views.py          # Django views
│   │   └── migrations/       # Database migrations
│   ├── thoughtful/           # Django project configuration
│   │   ├── settings.py       # Django settings
│   │   ├── urls.py           # URL routing
│   │   └── wsgi.py           # WSGI configuration
│   └── manage.py             # Django management script
│
├── frontend/                  # React Frontend Application
│   ├── src/
│   │   ├── App.tsx           # Main React component
│   │   ├── api.ts            # API client (Axios)
│   │   ├── types.ts          # TypeScript interfaces
│   │   ├── main.tsx          # React entry point
│   │   └── index.css         # Tailwind CSS imports
│   ├── public/               # Static assets
│   ├── package.json          # Node.js dependencies
│   ├── tsconfig.json         # TypeScript configuration
│   ├── vite.config.ts        # Vite build configuration
│   └── tailwind.config.js    # Tailwind CSS configuration
│
├── scripts/                   # Utility Scripts
│   ├── start.sh              # Start all services (development)
│   ├── stop.sh               # Stop all services
│   ├── status.sh             # Check service status
│   ├── init_db.sh            # Initialize database with admin user
│   ├── test_api.py           # API testing script
│   ├── deploy.sh             # Local Docker deployment
│   ├── deploy-to-server.sh   # Remote server deployment
│   ├── setup-ssl.sh          # SSL certificate setup
│   └── test_ssh.sh           # SSH connection test
│
├── docs/                      # Documentation
│   ├── GETTING_STARTED.md    # Detailed setup guide
│   ├── QUICK_REFERENCE.md    # Command reference
│   ├── DEPLOYMENT.md         # Deployment instructions
│   ├── DEPLOYMENT_SUMMARY.md # Deployment overview
│   ├── DEPLOY_NOW.md         # Quick deploy guide
│   └── SERVER_INFO_NEEDED.md # Server setup checklist
│
├── .env.example               # Development environment template
├── .env.production.example    # Production environment template
├── .gitignore                # Git ignore rules
├── .dockerignore             # Docker ignore rules
├── Dockerfile                # Multi-stage Docker build
├── docker-compose.yml        # Docker services orchestration
├── docker-entrypoint.sh      # Docker startup script
├── nginx.conf                # Nginx reverse proxy configuration
├── requirements.txt          # Python dependencies
├── sample_packages.json      # Test data (6 sample packages)
└── README.md                 # This file

Testing

Sample Data

The project includes sample_packages.json with 6 test packages covering all categories:

  • Small Box - STANDARD (normal size, normal weight)
  • Heavy Box - SPECIAL (normal size, heavy weight)
  • Bulky Box - SPECIAL (tall dimension, normal weight)
  • Rejected Package - REJECTED (tall + heavy)
  • Large Volume - SPECIAL (high volume, normal weight)
  • Medium Standard - STANDARD (normal size, normal weight)

Manual Testing

  1. Open http://localhost:5173
  2. Upload sample_packages.json using the file upload feature
  3. Click "Sort & Classify Packages"
  4. View the classification results with visual indicators

API Testing

Interactive Documentation: Visit http://localhost:8000/docs to use the Swagger UI for testing.

Command Line:

# Run the included test script
python scripts/test_api.py

# Or use curl
curl -X POST http://localhost:8000/packages/sort/ \
  -H "Content-Type: application/json" \
  -d @sample_packages.json

Development

Local Development Setup

The scripts/start.sh script handles all setup automatically. For manual setup:

# 1. Create Python virtual environment
python3 -m venv venv
source venv/bin/activate

# 2. Install Python dependencies
pip install -r requirements.txt

# 3. Run Django migrations
cd backend
python manage.py migrate
cd ..

# 4. Install frontend dependencies
cd frontend
npm install
cd ..

# 5. Start services in separate terminals
# Terminal 1: Django
cd backend && python manage.py runserver 8001

# Terminal 2: FastAPI
cd api && uvicorn main:app --reload --port 8000

# Terminal 3: Frontend
cd frontend && npm run dev

Development Features

  • Hot Reload: All services support automatic reload on file changes
    • Vite: Instant HMR for React components
    • FastAPI: Uvicorn's --reload flag
    • Django: Auto-reload on Python file changes

Adding New Features

  1. Backend Model Changes:

    • Update backend/core/models.py
    • Create migrations: python manage.py makemigrations
    • Apply migrations: python manage.py migrate
  2. API Endpoints:

    • Add routes and logic in api/main.py
    • Update Pydantic models for validation
    • Documentation auto-generates in Swagger
  3. Frontend Components:

    • Modify frontend/src/App.tsx for UI changes
    • Update frontend/src/types.ts for TypeScript interfaces
    • Add API calls in frontend/src/api.ts

Environment Variables

Create a .env file in the root directory for development:

# Django Settings
DEBUG=True
SECRET_KEY=your-secret-key-here
DJANGO_SETTINGS_MODULE=thoughtful.settings
ALLOWED_HOSTS=localhost,127.0.0.1

# Database (optional - defaults to SQLite)
DATABASE_URL=postgres://user:pass@localhost:5432/dbname

# Application Settings
CORS_ALLOWED_ORIGINS=http://localhost:5173,http://localhost:3000

For production, use .env.production (see .env.production.example).

Deployment

Docker Deployment (Recommended)

The project includes complete Docker support for easy deployment:

# Local Docker testing
docker compose up --build

# Access at:
# http://localhost        - Frontend (via Nginx)
# http://localhost/docs   - API documentation
# http://localhost/admin  - Django admin

Production Deployment

For detailed deployment instructions, see:

  • docs/DEPLOY_NOW.md - Quick deployment to production server
  • docs/DEPLOYMENT.md - Comprehensive deployment guide
  • docs/DEPLOYMENT_SUMMARY.md - Deployment overview

Quick Deploy to Server:

# Deploy to production server (configured for ajp-test-site.com)
./scripts/deploy-to-server.sh

# Setup SSL/HTTPS
./scripts/setup-ssl.sh

Production Stack

  • Nginx: Reverse proxy, static file serving, SSL termination
  • Gunicorn: Production WSGI server for Django
  • Uvicorn: ASGI server for FastAPI
  • PostgreSQL: Production database
  • Docker: Container orchestration

Troubleshooting

Common Issues

Ports Already in Use:

./scripts/stop.sh  # Kill existing processes
./scripts/start.sh # Restart

Frontend Not Loading:

# Check logs
tail -f frontend.log

# Rebuild frontend
cd frontend
rm -rf node_modules dist
npm install
npm run dev

API Errors:

# Check logs
tail -f fastapi.log

# Verify FastAPI is running
curl http://localhost:8000/

Django Issues:

# Check logs
tail -f django.log

# Reset database (development only)
rm backend/db.sqlite3
cd backend && python manage.py migrate

Database Connection Issues:

# Check PostgreSQL is running (if using PostgreSQL)
# Or verify SQLite database exists
ls -la backend/db.sqlite3

View All Logs

# Watch all logs simultaneously
tail -f *.log

# Or individually
tail -f django.log
tail -f fastapi.log
tail -f frontend.log

Service Status

# Check if all services are running
./scripts/status.sh

# Check specific ports
lsof -i :5173  # Frontend
lsof -i :8000  # FastAPI
lsof -i :8001  # Django

Documentation

Additional documentation is available in the docs/ directory:

Security Considerations

Development

  • Default DEBUG=True (automatically disabled in production)
  • SQLite database (no password needed)
  • CORS enabled for localhost origins
  • Admin credentials: admin/admin123 (change immediately)

Production

  • DEBUG=False (set via environment)
  • PostgreSQL with strong passwords
  • CORS restricted to specific domains
  • SECRET_KEY from environment variables
  • HTTPS with Let's Encrypt SSL certificates
  • Nginx security headers
  • No exposed database ports

Dependencies

Python (Backend)

Full list in requirements.txt:

  • Django 4.2+ - Web framework and ORM
  • djangorestframework 3.14+ - REST API toolkit
  • FastAPI 0.104+ - Modern async API framework
  • uvicorn[standard] 0.24+ - ASGI server
  • pydantic 2.4+ - Data validation
  • psycopg2-binary 2.9+ - PostgreSQL adapter
  • dj-database-url 2.1+ - Database URL parsing
  • django-cors-headers 4.3+ - CORS handling
  • python-decouple 3.8+ - Environment variables
  • pandas 2.0+ - Data analysis (future features)
  • openpyxl 3.1+ - Excel support (future features)
  • ortools 9.7+ - Optimization (future features)

JavaScript (Frontend)

Full list in frontend/package.json:

  • React 19 - UI library
  • TypeScript 5.9 - Type safety
  • Vite 7 - Build tool
  • Tailwind CSS 3 - Styling
  • Axios 1.12 - HTTP client
  • ESLint - Code linting

Performance

  • FastAPI: ~10,000+ requests/second (depending on hardware)
  • React: Optimized builds with code splitting
  • Vite: Lightning-fast HMR (<50ms)
  • PostgreSQL: Production-grade performance and reliability
  • Nginx: Efficient static file serving and caching

Contributing

Contributions are welcome! To contribute:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Please ensure:

  • Code follows existing style and conventions
  • All tests pass
  • Documentation is updated
  • Commit messages are clear and descriptive

License

MIT License - Feel free to use this project for your own purposes.

Support

For questions or issues:

  1. Check the documentation directory
  2. Review troubleshooting section
  3. Check service status: ./scripts/status.sh
  4. Review logs: tail -f *.log
  5. Open an issue on GitHub

Acknowledgments

Built with modern web technologies and best practices for production-ready applications.


Happy Sorting! 📦✨

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages