TaskHub is a deliberately small Django application for learning how a modular monolith can combine Django Templates, HTMX, PostgreSQL, Supabase Storage, and Django Ninja. It is a technology test project, not a production-ready task manager.
- Django models, forms, views, templates, ORM, admin, and tests
- HTMX partial responses for create, complete, delete, filtering, and search
- PostgreSQL configuration compatible with local PostgreSQL or Supabase PostgreSQL
- Optional file uploads to Supabase Storage
- A small validated Django Ninja API
- GitHub Actions checks and tests
python -m venv venv
.\venv\Scripts\Activate.ps1
pip install -r requirements.txt
Copy-Item .env.example .envSet DJANGO_SECRET_KEY and a Supabase PostgreSQL connection in .env. You can use one connection string:
DATABASE_URL=postgresql://postgres:your-password@db.your-project.supabase.co:5432/postgres
Or use the individual DB_NAME, DB_USER, DB_PASSWORD, DB_HOST, and DB_PORT variables. The individual DB_* variables take priority when both configurations exist. When neither PostgreSQL configuration is present, the application uses SQLite as a local development fallback.
For Vercel, configure DATABASE_URL or the PostgreSQL variables as project environment variables so task data is persistent across deployments and serverless instances:
DB_NAME=taskhub
DB_USER=postgres
DB_PASSWORD=your-database-password
DB_HOST=your-postgres-host
DB_PORT=5432
Create a bucket such as task-attachments, then set these variables in .env:
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your-server-side-key
SUPABASE_BUCKET=task-attachments
SUPABASE_PUBLIC_URL=https://your-project.supabase.co/storage/v1/object/public/task-attachments
When these variables are missing, attachments are saved to local media/attachments/ storage so the feature still works with SQLite. When they are present, uploads go to Supabase Storage. Never commit .env, Supabase keys, or local media files.
python manage.py migrate
python manage.py createsuperuser # optional
python manage.py runserverOpen http://127.0.0.1:8000/ for the introduction page, then choose Enter TaskHub to open the working task board at /app/. The API is available at /api/tasks and /api/tasks/{id}.
python manage.py check
python manage.py makemigrations --check --dry-run
python manage.py testThe GitHub Actions workflow runs these checks on pushes and pull requests. It uses Django's default SQLite test database so CI does not need secrets or a hosted database.
- Create:
POST /tasks/create/returns one task-card partial;hx-target="#task-list"andhx-swap="afterbegin"insert it. - Complete:
POST /tasks/{id}/toggle/returns the updated card;hx-target="closest article"andhx-swap="outerHTML"replace it. - Delete:
DELETE /tasks/{id}/delete/returns an empty response; the same target/swap removes the card. - Filter/search:
GET /tasks/partial/returns all matching cards;hx-target="#task-list"andhx-swap="innerHTML"replace the list contents.
git init
git add .
git commit -m "Build TaskHub technology test"
git branch -M main
git remote add origin https://github.com/YOUR-USER/YOUR-REPO.git
git push -u origin mainReview .gitignore before pushing. Credentials, .env, and local SQLite files are excluded.