nestjs_pg_be is a learning-focused, production‑style backend built with NestJS, PostgreSQL, and Prisma.
The goal of this project is to practice NestJS while deliberately covering core backend concepts:
- Authentication & authorization (JWT access tokens, refresh tokens, guards, strategies)
- Modular architecture (separate
authandusersdomains) - Database layer with Prisma and PostgreSQL
- Validation & DTOs with
class-validator/class-transformer - Environment‑based configuration (
.env,JWT_SECRET,DATABASE_URL)
This is not a full product, but a production‑grade learning playground where features are implemented in a realistic way.
- Runtime: Node.js
- Framework:
NestJS(TypeScript) - Database: PostgreSQL
- ORM: Prisma
- Auth:
@nestjs/jwt,passport-jwt, HTTP‑only refresh token cookie - Validation:
class-validator,class-transformer
-
User model
- Basic fields:
id,full_name,username,email,password,role, timestamps - Email verification fields:
emailVerificationToken,emailVerificationExpires - Persistent
refreshTokenhash stored per user
- Basic fields:
-
Auth module (
/api/auth)- POST
/api/auth/register- Creates a user, hashes password with bcrypt
- Generates access & refresh tokens
- Stores hashed refresh token in DB
- Sends a verification link via
EmailService(currently logs to console) - Sets
refreshTokenas an HTTP‑only cookie
- POST
/api/auth/login- Login with
emailorusername+ password - Rejects unverified emails
- Issues new access & refresh tokens
- Sets
refreshTokencookie
- Login with
- POST
/api/auth/refresh- Reads
refreshTokencookie - Verifies JWT, checks DB hash, rotates refresh token
- Returns a new access token and updates the
refreshTokencookie
- Reads
- POST
/api/auth/logout- Clears stored refresh token in DB and removes cookie
- POST
-
Users module (
/api/users)- GET
/api/users/profile- Protected by
JwtGuard/JwtStrategy - Returns the authenticated user’s profile from the database
- Protected by
- GET
-
JWT strategy & typing
JwtStrategyusespassport-jwtwith bearer tokensJwtPayloadandJwtUserinterfaces model the raw JWT payload and the user attached toreq.user
src/main.ts– app bootstrap, global prefixapi, validation pipe, cookie parsersrc/app.module.ts– root module wiringAuthModule,UsersModule,PrismaModulesrc/auth– authentication & authorizationauth.controller.ts,auth.service.tsdto/register & login DTOsstrategies/jwt.strategy.tsguards/jwt.guard.tsinterfaces/jwt-payload.interface.tsutils/token.util.tsfor email verification tokens
src/users– user‑facing domain (currently profile)users.controller.ts,users.service.ts
src/prisma– Prisma module & serviceprisma/schema.prisma– data model (User + Role enum)
- Node.js and npm installed
- PostgreSQL instance running and reachable
npm installCreate an .env file in the project root (already .gitignored). Example:
DATABASE_URL="postgresql://user:password@localhost:5432/db_name"
PORT=4000
JWT_SECRET="replace_with_a_long_random_secret"You can generate a strong secret with:
openssl rand -base64 32Run Prisma migrations (once your schema and DATABASE_URL are correct):
npx prisma migrate devYou can also inspect the DB with:
npx prisma studio# development
npm run start
# watch mode
npm run start:dev
# production build + run
npm run build
npm run start:prodThe API will be available at http://localhost:4000/api.
-
Auth
- POST
http://localhost:4000/api/auth/register - POST
http://localhost:4000/api/auth/login - POST
http://localhost:4000/api/auth/refresh - POST
http://localhost:4000/api/auth/logout
- POST
-
Users (protected)
- GET
http://localhost:4000/api/users/profile- Requires
Authorization: Bearer <access_token>
- Requires
- GET
This project is intentionally structured to practice backend fundamentals while learning NestJS:
- Clean module separation (
authvsusers) - DTOs and validation for input safety
- JWT auth with short‑lived access tokens and long‑lived refresh tokens
- Guards and strategies (
JwtGuard,JwtStrategy) for protecting routes - Persistent sessions via hashed refresh tokens in the database
- Prisma data access layer and migrations
- Environment‑driven configuration for secrets and DB URLs
As you extend this project, you can add more concepts (RBAC/roles, pagination, file uploads, background jobs, etc.) while staying within this production‑style structure.