- Overview
- Tech Stack
- Features
- Project Structure
- Getting Started
- Deployment
- Key Design Decisions
- Challenges
- Future Improvements
- Motivation
A full-stack personal portfolio built to showcase projects, track LeetCode progress, and experiment with modern web architecture.
This project started as a simple way to visualise LeetCode solve data and evolved into a fully featured portfolio platform. It integrates authentication, backend APIs, database persistence, and dynamic content from external sources.
The goal was to build something production-grade to refine skills I use in my current job.
- Next.js (App Router)
- TypeScript
- Mantine UI
- React Query
- Orval (API client generation)
- NestJS
- TypeScript
- REST API (OpenAPI/Swagger)
- PostgreSQL
- Prisma ORM
- better-auth
- GitHub OAuth
- Railway (backend, frontend, database)
- PNPM monorepo
- Full-stack architecture (frontend + backend + database)
- Type-safe API layer with generated clients
- Authentication with session handling
- Protected endpoints and role-based access
- Dynamic project display (from GitHub repos tagged portfolio)
- Structured experience timeline
- Responsive UI with consistent design system
- Store solve data in PostgreSQL
- Scatter plot visualisation of solves
- Auth-protected submission system
- Real-time updates via API
- Monorepo setup with shared packages
- Prisma schema + migrations
- Generated API hooks via Orval
- Environment-based configuration (local vs production)
apps/
web/ # Next.js frontend
api/ # NestJS backend
packages/
db/ # Prisma + database client
auth/ # Authentication configuration
pnpm install
Create .env and .env.local files where needed.
NEXT_PUBLIC_API_URL=http://localhost:3001
NEXT_PUBLIC_URL=http://localhost:3000
Example (api)
DATABASE_URL=postgresql://...
BETTER_AUTH_SECRET=...
BETTER_AUTH_URL=http://localhost:3000
GITHUB_CLIENT_ID=...
GITHUB_CLIENT_SECRET=...
from root:
pnpm -r build
pnpm --filter api run dev and pnpm --filter web run start:dev
pnpm --filter @portfolio/db exec prisma migrate dev
Everything is deployed on Railway.
Monorepo
- Shared types and logic across frontend/backend
- Easier dependency management Generated API Client
- Eliminates manual fetch logic
- Ensures type safety across layers Separation of Concerns
- Backend handles all business logic
- Frontend remains a thin client
- Handling environment differences between local and production
- Authentication across domains (cookies, CORS, origins)
- Prisma client resolution in monorepo builds
- API generation timing during builds (Orval + backend availability)
- Mantine Timeline display strange behaviour on light mode
- Improve LeetCode visualisation UX
- Enhance project filtering/sorting
- Add CI/CD pipeline with automated checks
- Add education section
- Fix Mantine Timeline component issue
This project was built to:
- Go beyond a static portfolio
- Improve full-stack engineering ability
- Explore production concerns (auth, deployment, infra)
- Build something genuinely useful