I built a production-style Django REST API for tracking job applications and client leads. My role was full-stack/backend owner: I designed the data model, authentication, admin workflow, API endpoints, validation rules, health checks, structured logging, tests, Docker runtime and CI gates.
- Django project setup and environment-driven settings.
JobApplicationmodel with owner isolation, status workflow and indexes.- Django Admin for internal operations.
- DRF CRUD API with token authentication.
- Search, ordering, filtering, pagination and owner-scoped stats.
- Audit trail for application creation and status changes.
- OpenAPI schema and Swagger docs.
- Health check endpoint for deploy monitoring.
- Request ID middleware for tracing and debugging production requests.
- Structured request logs for request ID, method, path, status and latency.
- Consistent API error envelope for auth, validation, not found and throttling cases.
- Configurable throttling and HTTPS/security settings for deploy hardening.
- Gunicorn + Whitenoise production container setup.
- pytest coverage for auth, CRUD, validation, ownership, stats, schema, logging and full token-auth workflow.
- I used Django Admin instead of building a custom internal dashboard first because it gives immediate operational control with less code.
- I used token auth because it is simple enough for this internal API while still showing production API authentication patterns.
- SQLite is available for local development, but the deployment target is PostgreSQL through
DATABASE_URL. - I kept ownership enforcement in the queryset layer so list and detail endpoints cannot leak another user's records.
- I added an application event table instead of relying only on logs because operators need a durable history of who changed a record and when.
- I kept static serving inside the container with Whitenoise because the project is small; for a larger app I would move static assets to object storage or a CDN.
/health/checks database connectivity.X-Request-IDis added to every response and preserves incoming request IDs.- API errors include
code,message,request_idand originaldetails. - DRF throttling protects the API from accidental abuse or runaway clients.
- Status changes create immutable audit events with actor and before/after state.
- Structured logs make every API response traceable by
X-Request-ID. - Tests cover user isolation and invalid states.
- An end-to-end API test covers token auth, create, filter, patch, events and stats in one workflow.
- OpenAPI docs make the API easier to integrate and verify.
- CI runs
check, migrations,collectstaticandpytest.
- Create a superuser.
- Request a token from
/api/token/. - Create applications through
/api/applications/. - Search with
?search=company. - View metrics at
/api/applications/stats/. - Change an application status and open
/api/applications/{id}/events/. - Open
/api/docs/to show the documented API.
The impact was turning a manual tracking workflow into a structured backend system with authentication, operational admin, documented endpoints, owner-scoped data access, auditability and tests that prove the core behavior.