Full-Stack Developer Portfolio
A production-oriented portfolio with a public resume, authenticated CMS, GitHub-powered case studies, and a recruiter contact workflow.
Table of contents
- Overview
- Key features
- Architecture
- Technology
- Repository structure
- Quick start
- Environment variables
- API overview
- Quality checks
- Deployment
- Roadmap
β¨ Overview
This monorepo powers an English-language portfolio for a Full-Stack Developer Intern. Content is stored as structured JSON rather than raw HTML, so the public resume, live editor preview, print view, and version history all share the same validated data model.
The project is deliberately split into a Next.js frontend and a NestJS API. Supabase provides authentication and PostgreSQL; Prisma owns database access. Public project case studies are loaded server-side from configured public GitHub repositories, which prevents browser CORS issues and keeps GitHub retrieval isolated from the UI.
π Key features
- Public portfolio and resume β responsive home page, printable resume, and public resume URLs by slug.
- Authenticated resume CMS β Supabase Bearer-token authentication with an
ADMIN_EMAILSallowlist; create, duplicate, edit, publish, select primary, and delete resume profiles. - Versioned publishing β every publish creates a
ResumeVersionsnapshot; an admin can inspect history and roll back safely. - Structured content β React Hook Form and Zod validate resume JSON before it is rendered by the frontend.
- GitHub-backed project case studies β multi-repository selection; server-side GitHub API lookup with raw-content fallbacks for
main,master, andHEADREADME files. - Safe Markdown rendering β GitHub Flavored Markdown, syntax highlighting, Mermaid diagrams, responsive images, inline badges, and repository-relative asset URLs.
- Contact and JD intake β a visitor can send an email, a message, a JD URL, or a JD file; the API validates input, applies anti-spam protections, and persists the request.
- Production deployment β frontend on Vercel; NestJS API on Render with a health check and Prisma migration at startup.
ποΈ Architecture
Case-study request flow
The case-study feature follows a small Clean Architecture boundary: the application service depends on repository and README-client interfaces, while Prisma and GitHub HTTP implementations live in infrastructure. This makes the selection logic straightforward to unit test without a database or network request.
π§° Technology
| Area | Technologies |
|---|---|
| Frontend | Next.js 16, React 19, TypeScript, Tailwind CSS |
| Forms and validation | React Hook Form, Zod |
| Markdown and diagrams | react-markdown, remark-gfm, rehype-highlight, Mermaid |
| Backend | NestJS 11, TypeScript, REST |
| Data | Supabase PostgreSQL, Prisma 7 |
| Authentication | Supabase Auth and a NestJS guard |
| Tooling | pnpm workspace, ESLint, Prettier, Jest |
| Hosting | Vercel, Render, Supabase |
π Repository structure
portfolio/
βββ frontend/ # Next.js App Router application
β βββ src/
β βββ app/ # Public, resume, project, and admin routes
β βββ features/
β β βββ home/ # Landing-page contact workflow
β β βββ projects/ # GitHub README case-study renderer
β β βββ resume/ # Public resume and editor UI
β βββ lib/ # Supabase, image URL, and UI helpers
βββ backend/ # NestJS API
β βββ prisma/ # Database schema and migrations
β βββ src/
β βββ auth/ # Supabase guard and authenticated request type
β βββ contact/ # Contact/JD endpoint
β βββ prisma/ # Prisma service and module
β βββ resume/
β βββ application/ # Project case-study use case + tests
β βββ domain/ # Dependency ports and contracts
β βββ infrastructure/ # Prisma repository and GitHub README client
β βββ dto/ # Request validation DTOs
βββ render.yaml # Render API deployment definition
βββ start-dev.bat # Windows development helper
βββ pnpm-workspace.yaml # Workspace packages
π Quick start
Prerequisites
- Node.js
22.14+ - pnpm
11.13+ - A Supabase project with PostgreSQL and Auth enabled
Install and configure
git clone <your-repository-url>
cd portfolio
pnpm install
# Create these files from the examples in the repository.
cp backend/.env.example backend/.env
cp frontend/.env.example frontend/.env.local
Set the required values, generate Prisma Client, then start both applications:
pnpm --filter backend db:generate
pnpm dev
The frontend runs at http://localhost:3000; the API health endpoint is http://localhost:3001/api/health.
On Windows, start-dev.bat runs the same workspace development command.
π Environment variables
Backend β backend/.env
| Variable | Purpose |
|---|---|
DATABASE_URL | Supabase PostgreSQL pooled connection URL used at runtime |
DIRECT_URL | Direct PostgreSQL URL used by Prisma migrations |
CORS_ORIGIN | Allowed frontend origin, for example http://localhost:3000 |
SUPABASE_URL | Supabase project URL |
SUPABASE_PUBLISHABLE_KEY | Supabase publishable/anon key used to validate sessions |
PORTFOLIO_OWNER_ID | Supabase Auth UID that exclusively owns the public portfolio CV |
ADMIN_EMAILS | Comma-separated email allowlist for CMS access |
Frontend β frontend/.env.local
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_API_URL | API base URL; defaults to http://localhost:3001/api |
NEXT_PUBLIC_SUPABASE_URL | Supabase project URL available to the browser client |
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY | Browser-safe Supabase publishable/anon key |
Never commit real credentials, service-role keys, or production database URLs.
π API overview
Public routes
| Method | Route | Purpose |
|---|---|---|
GET | /api/health | API health status |
GET | /api/resume | Primary published resume |
GET | /api/resume/:slug | Published resume by slug |
GET | /api/projects/:slug/case-study?repo=<index-or-label> | Markdown-backed project case study |
POST | /api/contact | Contact message and optional JD submission |
Admin routes
These routes require a valid Supabase Bearer token and an email in ADMIN_EMAILS.
| Method | Route | Purpose |
|---|---|---|
GET / POST | /api/admin/resumes | List or create/duplicate profiles |
GET / PUT / DELETE | /api/admin/resumes/:id | Read, save, or delete a profile |
PUT | /api/admin/resumes/:id/meta | Update title and slug |
POST | /api/admin/resumes/:id/publish | Publish and create a version snapshot |
POST | /api/admin/resumes/:id/set-primary | Set the primary profile |
GET | /api/admin/resumes/:id/versions | View version history |
POST | /api/admin/resumes/:id/rollback/:versionId | Restore a version |
Backward-compatible primary-resume endpoints remain under /api/admin/resume.
β Quality checks
# Backend
pnpm --filter backend exec eslint "src/**/*.ts"
pnpm --filter backend exec jest --runInBand
pnpm --filter backend run build
# Frontend
pnpm --filter frontend run lint
pnpm --filter frontend run build
βοΈ Deployment
- Vercel: deploy the
frontendworkspace and set the threeNEXT_PUBLIC_*variables. - Render: use render.yaml. Its build generates Prisma Client and builds the backend; startup runs
prisma migrate deploybefore launching NestJS. - Supabase: provide the PostgreSQL URLs, configure Auth, and add the production Vercel URL to
CORS_ORIGIN.
πΊοΈ Roadmap
- Additional resume templates and managed project content
- Accessibility, SEO, sitemap, and dark/light mode polish
- Independent CI workflow for lint, test, and build
- Blog/newsletter and portfolio search
- RAG assistant, Telegram handoff, and live chat via SSE
Inspired by the clear product-first documentation style of SafeNews AI Crawler Engine and SafeNews Mobile App.