portfolio-api
Production NestJS REST API powering cativo.dev. 43 releases, 94% line coverage, JWT + API keys, 3-tier rate limiting.
- ▸35+ releases with 94% line coverage — production patterns demonstrated end-to-end
- ▸JWT auth + HMAC-SHA256 hashed API keys (rotating secret invalidates all keys)
- ▸Three throttling tiers: default 100/min, public 10/min, strict 5/min for auth
- ▸Standardized response envelopes with request IDs, path aliases, full Swagger schema
NestJS REST API powering my portfolio
The backend you're talking to right now. A production-ready NestJS REST API for managing portfolio projects, contacts, and authentication — with rate limiting, API keys, JWT, comprehensive testing (94% lines, 91% functions), Swagger docs, and a CI/CD pipeline that's gone through 35+ releases.
Why I built it
I wanted my portfolio's data to live in a real API I could query from anywhere — the website, a future mobile app, a Raycast extension — instead of hard-coding projects in Markdown. I also wanted a place to demonstrate enterprise-grade backend patterns end-to-end: standardized error responses, request IDs, path aliases, configurable throttling tiers, structured Swagger, and a release workflow that's actually maintainable. This repo is also my reference implementation when I bootstrap new NestJS services.
What it does
- Auth — JWT-based login/register/profile with bcrypt password hashing.
- API Keys — HMAC-SHA256 hashed before storage, with rotation invalidating all existing keys when the secret rotates.
- Projects CRUD — pagination, search,
is_featuredfilter, status enum (Completed / In Progress / Maintained). - Contacts — public POST endpoint (rate-limited) for the contact form, admin-only GET/PATCH/DELETE for triage.
- Three throttling tiers — default (100/min), public (10/min), strict for auth (5/min) — all configurable via env.
- Health check at
/healthfor uptime monitors. - Swagger UI at
/docswith full schema coverage. - Path aliases (
@core/*,@auth/*,@projects/*, ...) for clean imports. - Standardized response envelopes —
{ status, data, request_id }and{ status, error: { code, message, ... } }. - 94% line coverage (statements, branches, functions tracked separately, badges in README).
- GitFlow + auto-release — release branches trigger CHANGELOG-driven releases.
Stack
NestJS 11, TypeScript, TypeORM, MySQL 8, Redis (cache), Docker, Yarn Berry, Jest, Swagger.
Status
35+ releases. Powers cativo.dev. Active.