This Django project implements an inventory reservation system as per the requirements in Final Take-Home Task.
No user authentication or session management was implemented because the requirements in Final Take-Home Task did not mention any authentication or session-related features. The system focuses solely on inventory management, reservations, and orders without user login.
SQLite was chosen as the database for simplicity and ease of setup, as no specific database requirements were mentioned in Final Take-Home Task.
Django 6 includes a built-in task management system, but I intentionally used Django 5.0 to leverage Celery Beat for periodic task scheduling, as required for cleaning up expired reservations.
Docker and Docker Compose are provided for easy deployment and environment consistency. Simply start the project using:
docker-compose up --build
Populate the project by using the API : http://127.0.0.1:8000/api/products/
- Product inventory with
total_stock,available_stock, andreserved_stock - Invariant:
available_stock + reserved_stock = total_stock - Reservations created via
POST /api/reservations/with 10-minute expiration - Concurrency-safe using
select_for_updateandtransaction.atomic - Expired reservations cleaned up via Celery Beat every 5 minutes
- Management command
cleanup_reservationsavailable as alternative
- State machine with allowed transitions:
- pending → confirmed → processing → shipped → delivered
- pending/confirmed → cancelled
- shipped/delivered are immutable (no further transitions)
- Validation prevents invalid transitions
- Transition map implemented as dictionary in code
- Script
scripts/chaos_test.pytests concurrency with 50 parallel reservation attempts on a product with 5 stock - Exactly 5 reservations succeed, demonstrating proper concurrency handling
- Output shows succeeded/failed counts and final stock numbers
GET /api/orders/supports filtering by date range, status, min/max total- Sorting by newest (created_at) and highest value (total)
- Cursor pagination for large datasets
- Indexes added:
Order(created_at)for date range filteringOrder(status)for status filteringOrder(total)for min/max total filtering- Composite
Order(created_at, total)for sorting
- Query optimization using
select_relatedfor user andprefetch_relatedfor order items - Query count: 2-3 queries per paginated request
- Records actor, action, object_type, object_id, old_value/new_value (JSON), timestamp
- Called explicitly from service layer
- Logs: reservation created/expired, order status changes, stock adjustments
In case of server crash, expired reservations can be cleaned up using the management command or Celery Beat. For immediate recovery, implement a background job to periodically clean up expired reservations every minute.
cleanup can be scheduled using Celery Beat every 5 minutes. For cron: */5 * * * * python manage.py cleanup_reservations. Currently this project is using beat schedule with 5 min intervals.
Using a Warehouse model means with many-to-many relationship to products. Stock levels per warehouse. Reservation locks specific warehouse stock.
Cache product stock levels in Redis with 5-minute TTL. Invalidate on stock changes. Use cache-aside pattern. It helps to avoid db calls, or background task dependancy saving resources. Its a solid design pattern, but this assignment did not require it.
User Request Reservation
↓
Validate Stock Availability
↓
Lock Product Row (select_for_update)
↓
Deduct from Available, Add to Reserved
↓
Create Reservation (10 min expiry)
↓
Audit Log: Reservation Created
↓
Return Success with request_id
-
Install dependencies:
pip install -r requirements.txt
-
Run migrations:
python manage.py makemigrations python manage.py migrate
-
Run the server:
python manage.py runserver
-
For background tasks (optional):
celery -A core.core worker --loglevel=info celery -A core.core beat --loglevel=info
Suggested-
docker-compose up --buildGET /- Health checkGET /populate/- Populate the database with sample dataPOST /api/reservations/- Create a reservationGET /api/products/- List productsGET /api/orders/- List orders with filters and sortingPOST /api/orders/{id}/confirm/- Confirm an orderPOST /api/orders/{id}/cancel/- Cancel an order
Every API response includes a request_id (UUID) for tracing in headers (via middleware), response body (via custom renderer), and logs (via logging configuration).
python manage.py cleanup_reservations- Clean up expired reservations (alternative to Celery Beat; Celery is the primary method used)
Run tests:
python manage.py testResult:
Run the chaos test script:
python scripts/chaos_test.pyResult:
Order(created_at)Order(status)Order(total)Order(created_at, total)

