A production-ready Django-based approval workflow system with role-based access control, state management, and comprehensive audit logging.
Organizations need a secure, scalable system for managing approval workflows where:
- Users can submit requests
- Requests move through controlled states
- Authorized personnel can approve or reject requests
- Every action is traceable and auditable
- Backend: Django 5.0+ with Django REST Framework
- Database: PostgreSQL (UUID primary keys)
- Authentication: Session auth for admin, JWT for API
- Server: Gunicorn + Nginx
- Containerization: Docker & Docker Compose
approval_system/
├── apps/
│ ├── users/ # Custom user model with roles
│ ├── requests/ # Request models with state machine
│ ├── approvals/ # Business logic & API endpoints
│ ├── audit_logs/ # Append-only audit trail
│ └── notifications/ # (Future: Email/push notifications)
├── core/
│ ├── constants.py # System-wide constants
│ ├── permissions.py # Centralized permission classes
│ ├── exceptions.py # Custom exception handling
│ └── middleware.py # Custom middleware
└── config/
├── settings/ # Environment-specific configs
└── urls.py # URL routing
Three role levels:
- Admin: Full system access
- Manager: Can approve assigned requests
- User: Can create and view own requests
Valid transitions:
draft→submitted(by creator)submitted→approvedorrejected(by manager/admin)approved/rejectedare terminal states
Invalid transitions raise exceptions server-side.
Every meaningful action is logged:
- Actor (who)
- Action (what)
- Target object
- Timestamp
- IP address & user agent
- Metadata (context)
Logs are append-only and cannot be edited or deleted.
- UUID primary keys (security, scalability)
- Soft deletes (data preservation)
- Server-side permission enforcement
- CSRF protection enabled
- HTTP-only cookies for sessions
- Rate limiting on auth endpoints
- No secrets in code (environment variables)
- Restricted CORS in production
POST /api/v1/users/- Create user (admin only)GET /api/v1/users/me/- Get current user info
GET /api/v1/requests/- List requests (filtered by role)POST /api/v1/requests/- Create requestGET /api/v1/requests/{id}/- Get request detailsPUT /api/v1/requests/{id}/- Update request (draft only)DELETE /api/v1/requests/{id}/- Soft delete requestPOST /api/v1/requests/{id}/submit/- Submit for approvalPOST /api/v1/requests/{id}/approve/- Approve requestPOST /api/v1/requests/{id}/reject/- Reject request
GET /api/v1/audit-logs/- View audit logs (managers/admins)
- Python 3.11+
- PostgreSQL 15+
- Docker & Docker Compose (optional)
- Clone and setup:
cd approval_system
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt- Configure environment:
cp .env.example .env
# Edit .env with your settings- Run migrations:
python manage.py migrate- Create superuser:
python manage.py createsuperuser- Run development server:
python manage.py runserver- Access the application:
# Start all services
docker-compose up --build
# Run migrations
docker-compose exec web python manage.py migrate
# Create superuser
docker-compose exec web python manage.py createsuperuserRun the test suite:
# Run all tests
python manage.py test
# Run specific app tests
python manage.py test apps.users
python manage.py test apps.requests
# With coverage
coverage run --source='.' manage.py test
coverage reportusers
id(UUID, PK)username,email,passwordrole(admin/manager/user)is_deleted(soft delete)- Indexed: role, is_deleted
requests
id(UUID, PK)title,descriptionstatus(draft/submitted/approved/rejected)creator_id(FK to users)assigned_to_id(FK to users, nullable)reviewed_by_id(FK to users, nullable)reviewed_at,rejection_reasonis_deleted- Indexed: status, creator, assigned_to, is_deleted, created_at
audit_logs
id(UUID, PK)actor_id(FK to users)action(create/update/approve/reject/etc)content_type&object_id(GenericForeignKey)metadata(JSON)ip_address,user_agenttimestamp- Indexed: actor+timestamp, action+timestamp, content_type+object_id
Implemented:
- Environment-based configuration
- CSRF protection
- Secure cookies (HTTPS in prod)
- Rate limiting ready
- Soft deletes
- Audit logging
- Permission-based access control
Production Checklist:
- Set strong SECRET_KEY
- Configure ALLOWED_HOSTS
- Set DEBUG=False
- Enable HTTPS/SSL
- Configure proper CORS origins
- Set up database backups
- Configure email backend
- Set up monitoring/logging
- Review and test all permissions
- Email/push notifications
- Multi-tenant support
- Advanced search & filtering
- File attachments
- Request comments/discussion
- Bulk operations
- Workflow templates
- Analytics dashboard
- API rate limiting
- Celery for async tasks
- Clean separation of concerns
- Service layer pattern for business logic
- Centralized permission management
- Environment-specific settings
- Defense in depth approach
- Server-side validation & authorization
- Audit trail for accountability
- Soft deletes for data preservation
- UUID primary keys
- Database indexing strategy
- Stateless API design
- Docker containerization
- Type hints where beneficial
- Comprehensive docstrings
- Unit tests for critical paths
- PEP 8 compliant
This is a educational project. Use as you see fit.
For questions or feedback about this project, please open an issue.