Full-stack task manager built for the Aetheris AI Round 1 assessment.
- Backend: Django + Django REST Framework, JWT auth (SimpleJWT), PostgreSQL (SQLite fallback for zero-setup local runs)
- Frontend: React (Vite) + Tailwind CSS + React Router
- Auth: JWT access/refresh tokens, auto-refresh on expiry, secure password validation
- Features: Register/Login/Logout, full task CRUD, mark complete, search, filter by status/priority, pagination, responsive UI, loading states
taskmanager/
├── backend/ Django REST API
└── frontend/ React (Vite) SPA
cd backend
python -m venv venv
venv\Scripts\activate # Windows PowerShell: .\venv\Scripts\Activate.ps1
# source venv/bin/activate # macOS/Linux
pip install -r requirements.txt
copy .env.example .env # Windows: copy | macOS/Linux: cp .env.example .env
python manage.py migrate
python manage.py createsuperuser # optional, for /admin
python manage.py runserverAPI runs at http://127.0.0.1:8000/api.
cd frontend
npm install
copy .env.example .env.development # Windows: copy | macOS/Linux: cp
npm run devApp runs at http://127.0.0.1:5173.
Edit backend/.env and set:
DATABASE_URL=postgres://<user>:<password>@localhost:5432/<db_name>
Then re-run python manage.py migrate.
User (custom accounts.User, extends Django's AbstractUser)
| Field | Type | Notes |
|---|---|---|
| id | BigAutoField | PK |
| username | CharField | unique |
| EmailField | unique, required | |
| password | CharField | hashed |
Task (tasks.Task)
| Field | Type | Notes |
|---|---|---|
| id | BigAutoField | PK |
| owner | ForeignKey | -> User, cascade delete |
| title | CharField | required |
| description | TextField | optional |
| due_date | DateField | optional |
| priority | CharField | High / Medium / Low |
| status | CharField | Pending / Completed |
| created_at | DateTimeField | auto |
| updated_at | DateTimeField | auto |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/register |
No | Create account, returns JWT pair |
| POST | /api/login |
No | Login with email + password |
| POST | /api/logout |
Yes | Blacklist refresh token |
| POST | /api/token/refresh |
No | Exchange refresh token for new access |
| GET | /api/me |
Yes | Current user info |
| GET | /api/tasks/ |
Yes | List own tasks (?status=&priority=&search=&page=) |
| POST | /api/tasks/ |
Yes | Create a task |
| GET | /api/tasks/:id/ |
Yes | Retrieve a task |
| PUT | /api/tasks/:id/ |
Yes | Full update |
| PATCH | /api/tasks/:id/ |
Yes | Partial update (e.g. toggle status) |
| DELETE | /api/tasks/:id/ |
Yes | Delete a task |
Send Authorization: Bearer <access_token> on all authenticated requests.
See backend/README.md and frontend/README.md for platform-specific deploy steps (Render/Railway for the API, Vercel/Netlify for the SPA).
- Title required on tasks
- Email must be unique
- Username must be unique
- Password minimum length: 6 characters (Django's built-in validators also apply)