Full-stack · Security · Team project
TaxAlly
An AI-assisted tax management platform that helps individuals, sole traders and small businesses through UK Self Assessment. Built by a team of five in my final year. I owned authentication, account registration and privacy consent, and the financial Insights dashboard.
- Next.js
- React
- TypeScript
- Django REST Framework
- PostgreSQL
- JWT
- Docker
- Jenkins







7 screenshots: use the arrows or scroll sideways.
Overview
TaxAlly brings a user's income, transactions and tax position into one place. Users record transactions, see their Income Tax, National Insurance and dividend tax calculated against the UK bands with reliefs applied, explore what-if scenarios, get alerts, and ask an AI tax assistant built on Claude with retrieval over embedded guidance (Voyage AI embeddings in PostgreSQL with pgvector).
The Next.js front end talks to a Django REST Framework API. Everything runs in Docker containers (PostgreSQL, Django, Next.js), and a Jenkins pipeline tests, lints, security-scans and deploys it.
My role & team
We were a team of five, working from issue-linked feature branches with merge requests into a shared development branch. I made over 70 commits and owned these areas end to end:
- Authentication: the login and registration API and front end, JWTs held in HttpOnly cookies, CSRF protection, a cookie-based token refresh so sessions survive a page reload, and protected routes across the app.
- Registration & privacy: the sign-up flow with client- and server-side validation, a per-user privacy and preferences model, consent-gated account creation, and the privacy policy page.
- Financial Insights: the Insights API and dashboard: income broken down by tax year starting on 6 April, annualised Income Tax and National Insurance, and charts plotting tax alongside transaction data.
- Testing & setup: backend unit tests and API end-to-end tests with pytest for login, registration and Insights, plus the starter repository and the project README.
Security
- Tokens out of JavaScript's reach: access and refresh JWTs live in HttpOnly, SameSite cookies rather than browser storage, with a 60-minute access token and 7-day refresh token.
- CSRF protection on login, registration and logout, using Django's CSRF token alongside the cookie-based session.
- Validation and sanitisation on both sides: the browser and the API each check every field. Emails are normalised and pattern-checked, inputs are trimmed and length-limited, new passwords need upper case, lower case and a number, and the server rejects sign-ups without the required consents. Errors come back as clear messages, not raw failures.
- Strong password hashing with Argon2, using a raised cost of 100 MB memory and four iterations.
- Team-wide: TOTP multi-factor authentication, and a pipeline stage running Safety and Bandit on the Python code and
npm auditon the front end.
What I'd improve next
- Make the Safety and Bandit stages fail the build on high-severity findings; at the moment they report without blocking.
- Move rate limiting to a shared cache such as Redis, so limits hold across multiple server workers.
- Add unit tests for the Insights calculations at tax-year boundaries and with missing data, which is where we found and fixed null annualised values late on.
TaxAlly's code is in a private university repository. I'm happy to walk through it in an interview.