All work
Full stack
Task manager
A full-stack task management application with Google authentication, priority-based organization, and a responsive, accessible UI. Built as a decoupled REST API (Django) + SPA (React) architecture, tested on both sides, and deployed across two platforms — Render for the API, Vercel for the frontend.
- TypeScript
- React 19
- Django 6
- Django REST Framework
- PostgreSQL
By the numbers
- API + SPA
- Architecture
- deployed independently
- 34
- Tests across both layers
- 11 APITestCase, 23 Vitest + RTL
- OAuth + JWT
- Authentication
- server-verified ID tokens
Key features
- Google Sign-In (OAuth 2.0)
- Users authenticate with their Google account; the backend verifies the ID token server-side against the app's client ID, then finds or creates the user from the token's subject claim and issues JWTs for session management.
- JWT-based auth
- Stateless authentication via djangorestframework-simplejwt, with 12-hour access tokens and a refresh token issued alongside. DRF is locked down globally: JWT is the only authentication class and every endpoint requires an authenticated user unless it opts out.
- Per-user task ownership
- The ViewSet's queryset is filtered to request.user and creation stamps the owner from the request, so the API only ever returns or mutates the authenticated user's own data — asserted from both directions in the tests.
- Priority levels
- Low, medium and high priorities with a custom priority selector UI, backed by five migrations including a data migration that remaps legacy priority values and one that introduced per-user ownership.
- Full CRUD
- A DRF ModelViewSet behind a router on the API side; on the client, all/active/completed filter tabs, paged four tasks at a time, with inline editing and delete confirmation modals.
- Responsive, accessible UI
- Ten shadcn-pattern components built on Base UI primitives — dialog, tabs, pagination, checkbox, field and the rest — with toasts through sonner.
Tech stack
Frontend
- React 19 + TypeScript, built with Vite
- Tailwind CSS 4 for styling, class-variance-authority + tailwind-merge for variant-driven component APIs
- shadcn/ui-pattern components on Base UI primitives: dialogs, tabs, pagination, checkboxes
- @react-oauth/google for Google Sign-In, sonner for toast notifications
Backend
- Django 6 + Django REST Framework, with ViewSets, serializers and a router-generated API
- PostgreSQL hosted on Neon, configured from a DATABASE_URL via dj-database-url
- djangorestframework-simplejwt for JWT issuance and verification, google-auth for verifying Google OAuth ID tokens
- django-cors-headers to allow the separately deployed SPA origin, WhiteNoise for compressed hashed static files, and Gunicorn as the production WSGI server
Testing
- Backend: Django/DRF APITestCase covering the Todo API's ownership rules from both sides and the Google login flow with mocked token verification (11 tests)
- Frontend: Vitest + React Testing Library + jsdom, with component-level tests for the task list, modals and priority selector (23 tests across 5 files)
Tooling and deployment
- Task automation via Taskfile.yml (Go Task) for one-command local setup
- Separate deploy pipelines: Render for the Django API, built by a build.sh that installs, collects static files and migrates; Vercel for the Vite static build
- TypeScript project references for split app and tooling type-checking
Skills demonstrated
Full-stack development, REST API design, OAuth and JWT authentication flows, relational data modelling and migrations, responsive UI engineering with a modern component system, automated testing across frontend and backend, and multi-service cloud deployment.