# Phase 7: Background Tasks with Celery - COMPLETE ✅

**Completion Date:** November 8, 2025  
**Status:** Successfully Implemented

## Overview

Phase 7 implements a comprehensive background task processing system using Celery with Redis as the message broker. This phase adds asynchronous processing capabilities for long-running operations, scheduled tasks, and email notifications.

## What Was Implemented

### 1. Celery Infrastructure ✅
- **Celery App Configuration** (`config/celery.py`)
  - Auto-discovery of tasks from all apps
  - Signal handlers for task failure/success logging
  - Integration with Sentry for error tracking
  
- **Django Integration** (`config/__init__.py`)
  - Celery app loaded on Django startup
  - Shared task decorators available throughout the project

### 2. Email System ✅
- **Email Templates** (`templates/emails/`)
  - `base.html` - Base template with ThrillWiki branding
  - `welcome.html` - Welcome email for new users
  - `password_reset.html` - Password reset instructions
  - `moderation_approved.html` - Submission approved notification
  - `moderation_rejected.html` - Submission rejection notification

- **Email Configuration**
  - Development: Console backend (emails print to console)
  - Production: SMTP/SendGrid (configurable via environment variables)

### 3. Background Tasks ✅

#### Media Tasks (`apps/media/tasks.py`)
- `process_uploaded_image(photo_id)` - Post-upload image processing
- `cleanup_rejected_photos(days_old=30)` - Remove old rejected photos
- `generate_photo_thumbnails(photo_id)` - On-demand thumbnail generation
- `cleanup_orphaned_cloudflare_images()` - Remove orphaned images
- `update_photo_statistics()` - Update photo-related statistics

#### Moderation Tasks (`apps/moderation/tasks.py`)
- `send_moderation_notification(submission_id, status)` - Email notifications
- `cleanup_expired_locks()` - Remove stale moderation locks
- `send_batch_moderation_summary(moderator_id)` - Daily moderator summaries
- `update_moderation_statistics()` - Update moderation statistics
- `auto_unlock_stale_reviews(hours=1)` - Auto-unlock stale submissions
- `notify_moderators_of_queue_size()` - Alert on queue threshold

#### User Tasks (`apps/users/tasks.py`)
- `send_welcome_email(user_id)` - Welcome new users
- `send_password_reset_email(user_id, token, reset_url)` - Password resets
- `cleanup_expired_tokens()` - Remove expired JWT tokens
- `send_account_notification(user_id, type, data)` - Generic notifications
- `cleanup_inactive_users(days_inactive=365)` - Flag inactive accounts
- `update_user_statistics()` - Update user statistics
- `send_bulk_notification(user_ids, subject, message)` - Bulk emails
- `send_email_verification_reminder(user_id)` - Verification reminders

#### Entity Tasks (`apps/entities/tasks.py`)
- `update_entity_statistics(entity_type, entity_id)` - Update entity stats
- `update_all_statistics()` - Bulk statistics update
- `generate_entity_report(entity_type, entity_id)` - Generate reports
- `cleanup_duplicate_entities()` - Detect duplicates
- `calculate_global_statistics()` - Global statistics
- `validate_entity_data(entity_type, entity_id)` - Data validation

### 4. Scheduled Tasks (Celery Beat) ✅

Configured in `config/settings/base.py`:

| Task | Schedule | Purpose |
|------|----------|---------|
| `cleanup-expired-locks` | Every 5 minutes | Remove expired moderation locks |
| `cleanup-expired-tokens` | Daily at 2 AM | Clean up expired JWT tokens |
| `update-all-statistics` | Every 6 hours | Update entity statistics |
| `cleanup-rejected-photos` | Weekly Mon 3 AM | Remove old rejected photos |
| `auto-unlock-stale-reviews` | Every 30 minutes | Auto-unlock stale reviews |
| `check-moderation-queue` | Every hour | Check queue size threshold |
| `update-photo-statistics` | Daily at 1 AM | Update photo statistics |
| `update-moderation-statistics` | Daily at 1:30 AM | Update moderation statistics |
| `update-user-statistics` | Daily at 4 AM | Update user statistics |
| `calculate-global-statistics` | Every 12 hours | Calculate global statistics |

### 5. Service Integration ✅
- **PhotoService** - Triggers `process_uploaded_image` on photo creation
- **ModerationService** - Sends email notifications on approval/rejection
- Error handling ensures service operations don't fail if tasks fail to queue

### 6. Monitoring ✅
- **Flower** - Web-based Celery monitoring (production only)
- **Task Logging** - Success/failure logging for all tasks
- **Sentry Integration** - Error tracking for failed tasks

## Setup Instructions

### Development Setup

1. **Install Redis** (if not using eager mode):
   ```bash
   # macOS with Homebrew
   brew install redis
   brew services start redis
   
   # Or using Docker
   docker run -d -p 6379:6379 redis:latest
   ```

2. **Configure Environment** (`.env`):
   ```env
   # Redis Configuration
   REDIS_URL=redis://localhost:6379/0
   CELERY_BROKER_URL=redis://localhost:6379/0
   CELERY_RESULT_BACKEND=redis://localhost:6379/1
   
   # Email Configuration (Development)
   EMAIL_BACKEND=django.core.mail.backends.console.EmailBackend
   DEFAULT_FROM_EMAIL=noreply@thrillwiki.com
   SITE_URL=http://localhost:8000
   ```

3. **Run Celery Worker** (in separate terminal):
   ```bash
   cd django
   celery -A config worker --loglevel=info
   ```

4. **Run Celery Beat** (in separate terminal):
   ```bash
   cd django
   celery -A config beat --loglevel=info
   ```

5. **Development Mode** (No Redis Required):
   - Tasks run synchronously when `CELERY_TASK_ALWAYS_EAGER = True` (default in `local.py`)
   - Useful for debugging and testing without Redis

### Production Setup

1. **Configure Environment**:
   ```env
   # Redis Configuration
   REDIS_URL=redis://your-redis-host:6379/0
   CELERY_BROKER_URL=redis://your-redis-host:6379/0
   CELERY_RESULT_BACKEND=redis://your-redis-host:6379/1
   
   # Email Configuration (Production)
   EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend
   EMAIL_HOST=smtp.sendgrid.net
   EMAIL_PORT=587
   EMAIL_USE_TLS=True
   EMAIL_HOST_USER=apikey
   EMAIL_HOST_PASSWORD=your-sendgrid-api-key
   DEFAULT_FROM_EMAIL=noreply@thrillwiki.com
   SITE_URL=https://thrillwiki.com
   
   # Flower Monitoring (Optional)
   FLOWER_ENABLED=True
   FLOWER_BASIC_AUTH=username:password
   ```

2. **Run Celery Worker** (systemd service):
   ```ini
   [Unit]
   Description=ThrillWiki Celery Worker
   After=network.target redis.target
   
   [Service]
   Type=forking
   User=www-data
   Group=www-data
   WorkingDirectory=/var/www/thrillwiki/django
   Environment="PATH=/var/www/thrillwiki/venv/bin"
   ExecStart=/var/www/thrillwiki/venv/bin/celery -A config worker \
             --loglevel=info \
             --logfile=/var/log/celery/worker.log \
             --pidfile=/var/run/celery/worker.pid
   
   [Install]
   WantedBy=multi-user.target
   ```

3. **Run Celery Beat** (systemd service):
   ```ini
   [Unit]
   Description=ThrillWiki Celery Beat
   After=network.target redis.target
   
   [Service]
   Type=forking
   User=www-data
   Group=www-data
   WorkingDirectory=/var/www/thrillwiki/django
   Environment="PATH=/var/www/thrillwiki/venv/bin"
   ExecStart=/var/www/thrillwiki/venv/bin/celery -A config beat \
             --loglevel=info \
             --logfile=/var/log/celery/beat.log \
             --pidfile=/var/run/celery/beat.pid \
             --schedule=/var/run/celery/celerybeat-schedule
   
   [Install]
   WantedBy=multi-user.target
   ```

4. **Run Flower** (optional):
   ```bash
   celery -A config flower --port=5555 --basic_auth=$FLOWER_BASIC_AUTH
   ```
   Access at: `https://your-domain.com/flower/`

## Testing

### Manual Testing

1. **Test Photo Upload Task**:
   ```python
   from apps.media.tasks import process_uploaded_image
   result = process_uploaded_image.delay(photo_id)
   print(result.get())  # Wait for result
   ```

2. **Test Email Notification**:
   ```python
   from apps.moderation.tasks import send_moderation_notification
   result = send_moderation_notification.delay(str(submission_id), 'approved')
   # Check console output for email
   ```

3. **Test Scheduled Task**:
   ```python
   from apps.moderation.tasks import cleanup_expired_locks
   result = cleanup_expired_locks.delay()
   print(result.get())
   ```

### Integration Testing

Test that services properly queue tasks:

```python
# Test PhotoService integration
from apps.media.services import PhotoService
service = PhotoService()
photo = service.create_photo(file, user)
# Task should be queued automatically

# Test ModerationService integration
from apps.moderation.services import ModerationService
ModerationService.approve_submission(submission_id, reviewer)
# Email notification should be queued
```

## Task Catalog

### Task Retry Configuration

All tasks implement retry logic:
- **Max Retries:** 2-3 (task-dependent)
- **Retry Delay:** 60 seconds base (exponential backoff)
- **Failure Handling:** Logged to Sentry and application logs

### Task Priority

Tasks are executed in the order they're queued. For priority queuing, configure Celery with multiple queues:

```python
# config/celery.py (future enhancement)
CELERY_TASK_ROUTES = {
    'apps.media.tasks.process_uploaded_image': {'queue': 'media'},
    'apps.moderation.tasks.send_moderation_notification': {'queue': 'notifications'},
}
```

## Monitoring & Debugging

### View Task Status

```python
from celery.result import AsyncResult

result = AsyncResult('task-id-here')
print(result.state)  # PENDING, STARTED, SUCCESS, FAILURE
print(result.info)   # Result or error details
```

### Flower Dashboard

Access Flower at `/flower/` (production only) to:
- View active tasks
- Monitor worker status
- View task history
- Inspect failed tasks
- Retry failed tasks

### Logs

```bash
# View worker logs
tail -f /var/log/celery/worker.log

# View beat logs
tail -f /var/log/celery/beat.log

# View Django logs (includes task execution)
tail -f django/logs/django.log
```

## Troubleshooting

### Common Issues

1. **Tasks not executing**
   - Check Redis connection: `redis-cli ping`
   - Verify Celery worker is running: `ps aux | grep celery`
   - Check for errors in worker logs

2. **Emails not sending**
   - Verify EMAIL_BACKEND configuration
   - Check SMTP credentials
   - Review email logs in console (development)

3. **Scheduled tasks not running**
   - Ensure Celery Beat is running
   - Check Beat logs for scheduling errors
   - Verify CELERY_BEAT_SCHEDULE configuration

4. **Task failures**
   - Check Sentry for error reports
   - Review worker logs
   - Test task in Django shell

### Performance Tuning

```python
# Increase worker concurrency
celery -A config worker --concurrency=4

# Use different pool implementation
celery -A config worker --pool=gevent

# Set task time limits
CELERY_TASK_TIME_LIMIT = 30 * 60  # 30 minutes (already configured)
```

## Configuration Options

### Environment Variables

| Variable | Required | Default | Description |
|----------|----------|---------|-------------|
| `REDIS_URL` | Yes* | `redis://localhost:6379/0` | Redis connection URL |
| `CELERY_BROKER_URL` | Yes* | Same as REDIS_URL | Celery message broker |
| `CELERY_RESULT_BACKEND` | Yes* | `redis://localhost:6379/1` | Task result storage |
| `EMAIL_BACKEND` | No | Console (dev) / SMTP (prod) | Email backend |
| `EMAIL_HOST` | Yes** | - | SMTP host |
| `EMAIL_PORT` | Yes** | 587 | SMTP port |
| `EMAIL_HOST_USER` | Yes** | - | SMTP username |
| `EMAIL_HOST_PASSWORD` | Yes** | - | SMTP password |
| `DEFAULT_FROM_EMAIL` | Yes | `noreply@thrillwiki.com` | From email address |
| `SITE_URL` | Yes | `http://localhost:8000` | Site URL for emails |
| `FLOWER_ENABLED` | No | False | Enable Flower monitoring |
| `FLOWER_BASIC_AUTH` | No** | - | Flower authentication |

\* Not required if using eager mode in development  
\*\* Required for production email sending

## Next Steps

### Future Enhancements

1. **Task Prioritization**
   - Implement multiple queues for different priority levels
   - Critical tasks (password reset) in high-priority queue
   - Bulk operations in low-priority queue

2. **Advanced Monitoring**
   - Set up Prometheus metrics
   - Configure Grafana dashboards
   - Add task duration tracking

3. **Email Improvements**
   - Add plain text email versions
   - Implement email templates for all notification types
   - Add email preference management

4. **Scalability**
   - Configure multiple Celery workers
   - Implement auto-scaling based on queue size
   - Add Redis Sentinel for high availability

5. **Additional Tasks**
   - Backup generation tasks
   - Data export tasks
   - Analytics report generation

## Success Criteria ✅

All success criteria for Phase 7 have been met:

- ✅ Celery workers running successfully
- ✅ Tasks executing asynchronously
- ✅ Email notifications working (console backend configured)
- ✅ Scheduled tasks configured and ready
- ✅ Flower monitoring configured for production
- ✅ Error handling and retries implemented
- ✅ Integration with existing services complete
- ✅ Comprehensive documentation created

## Files Created

- `config/celery.py` - Celery app configuration
- `config/__init__.py` - Updated to load Celery
- `templates/emails/base.html` - Base email template
- `templates/emails/welcome.html` - Welcome email
- `templates/emails/password_reset.html` - Password reset email
- `templates/emails/moderation_approved.html` - Approval notification
- `templates/emails/moderation_rejected.html` - Rejection notification
- `apps/media/tasks.py` - Media processing tasks
- `apps/moderation/tasks.py` - Moderation workflow tasks
- `apps/users/tasks.py` - User management tasks
- `apps/entities/tasks.py` - Entity statistics tasks
- `PHASE_7_CELERY_COMPLETE.md` - This documentation

## Files Modified

- `config/settings/base.py` - Added Celery Beat schedule, SITE_URL, DEFAULT_FROM_EMAIL
- `config/urls.py` - Added Flower URL routing
- `apps/media/services.py` - Integrated photo processing task
- `apps/moderation/services.py` - Integrated email notification tasks

## Dependencies

All dependencies were already included in `requirements/base.txt`:
- `celery[redis]==5.3.4`
- `django-celery-beat==2.5.0`
- `django-celery-results==2.5.1`
- `flower==2.0.1`

## Summary

Phase 7 successfully implements a complete background task processing system with Celery. The system handles:
- Asynchronous image processing
- Email notifications for moderation workflow
- Scheduled maintenance tasks
- Statistics updates
- Token cleanup

The implementation is production-ready with proper error handling, retry logic, monitoring, and documentation.

**Phase 7: COMPLETE** ✅
