# Django Cronjob Utils

A robust cronjob handling package for Django that provides execution tracking, duplicate prevention, stakeholder notifications, configurable retry, and comprehensive database logging.

## Features

- ✅ **Execution Tracking**: Record all cronjob executions with start/end times, success/failure status
- ✅ **Duplicate Prevention**: Database-level locking prevents concurrent execution
- ✅ **Stakeholder Notification**: Alert stakeholders when cronjobs fail (Email, Slack, Telegram)
- ✅ **Configurable Retry**: Automatic retry on failure (configurable per task)
- ✅ **Database Logging**: All executions logged to database for monitoring and audit trail
- ✅ **Django Admin Integration**: Built-in admin interface for monitoring executions
- ✅ **Multiple Execution Patterns**: Standard, Always, Rerun-on-Failure, Rate-Limited
- ✅ **Hook System**: Inject custom logic before/after execution (dependency checks, validation, etc.)

## Installation

```bash
pip install django-cronjob-utils
```

## Quick Start

### 1. Add to Django Settings

```python
# settings.py
INSTALLED_APPS = [
    # ...
    'django_cronjob_utils',
]
```

### 2. Run Migrations

```bash
python manage.py migrate django_cronjob_utils
```

### 3. Create Your First Task

```python
# myapp/tasks.py
from django_cronjob_utils import CronTask, register_task
from datetime import date

@register_task('calc-commission', 'A001')
class CalcCommissionTask(CronTask):
    def execute(self, date: date) -> dict:
        # Your business logic here
        return {'error': False, 'message': 'Success'}
```

### 4. Set Up Crontab

```bash
# Edit crontab
crontab -e

# Add entry (runs daily at 1 AM)
0 1 * * * cd /path/to/project && /path/to/venv/bin/python manage.py run_cron_task calc-commission $(date +\%Y-\%m-\%d)
```

## Configuration

### Notification Settings

```python
# settings.py
CRONJOB_UTILS = {
    'NOTIFICATIONS': {
        'on_failure': ['email', 'slack', 'telegram'],
        'email': {
            'recipients': ['admin@example.com'],
            'from_email': 'noreply@example.com',
        },
        'slack': {
            'webhook_url': 'https://hooks.slack.com/services/...',
            'channel': '#cronjobs',
        },
        'telegram': {
            'bot_token': 'your-bot-token',
            'chat_id': 'your-chat-id',
        },
    },
}
```

## Usage Examples

### Standard Task (Run Once Per Day)

```python
@register_task('daily-report', 'A001')
class DailyReportTask(CronTask):
    def execute(self, date: date) -> dict:
        # Generate report
        return {'error': False, 'message': 'Report generated'}
```

### Task with Retry on Failure

```python
from django_cronjob_utils import ExecutionPattern

@register_task('sync-api', 'A002',
               execution_pattern=ExecutionPattern.RERUN_ON_FAILURE,
               retry_on_failure=True,
               max_retries=3,
               retry_delay=300)
class SyncAPITask(CronTask):
    def execute(self, date: date) -> dict:
        # Sync logic
        return {'error': False, 'message': 'Sync completed'}
```

### Always Execute Task

```python
@register_task('update-cache', 'A003',
               execution_pattern=ExecutionPattern.ALWAYS)
class UpdateCacheTask(CronTask):
    def execute(self, date: date) -> dict:
        # Cache update logic
        return {'error': False, 'message': 'Cache updated'}
```

## Documentation

For detailed documentation, see:
- [Architecture Documentation](docs/architecture.md)
- [Usage Guide](docs/usage.md)
- [Hook System Guide](docs/hooks.md) - Add custom logic before/after execution
- [Testing Guide](docs/testing.md) - How to install dependencies and run tests
- [Quick Start Testing](TESTING_QUICKSTART.md) - TL;DR version for running tests

## License

MIT License

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.
