Skip to content

yukiotime/backend-shelby-template

Repository files navigation

Nest.js monolite template | Production ready

Technical StackFeaturesDocumentationQuick startRequirementsDocker helpE2E testsMiscellaneous

Technical Stack

  • Nest.js
  • Prisma + Postgresql
  • Redis (based on ioredis)
  • Elasticsearch
  • Winston + Logstash
  • Passport.js, JWT, express-session + connect-redis
  • Nest-access-control (attribute-based access control)
  • Archiver (creating .zip archives)
  • Pdfkit
  • Nodemailer
  • Zod / Class-validator
  • Swagger
  • Eslint & Prettier
  • Docker

Features

  • Following to clean (onion) architecture
  • UML diagram class (auth)
  • Account system based on JWT tokens (with Passport.js):
    • Signup (with email confirmation), Login, RefreshJwt, CreateRtSession, Logout
    • Mantaining of multi sessions for one user (based on refresh tokens) + self cleaning of expired sessions (cron job)
    • Several user roles with appropriate permissions (ABAC)
  • Account system based on sessions (with Passport.js):
    • Login, Logout
    • Redis as storage for keeping active sessions
    • Manual decorators for login and accessing protected endpoints (based on Passport.js)
  • Operations for Certificate report (generate .pdf, get (as .pdf / .zip))
  • Winston logging:
    • Based on logstash transport implementation (ELK)
    • Based on file transport implementation
    • Based on only log-level transport implementation
  • End-to-end logging (via Async Local Storage and traceId)
  • Dto validation/transformation + Swagger:
    • Based on Zod
    • Based on Class-validator
  • Save environment variables
  • Customizable bootstrapping of application (app.module.ts)
  • Intergration tests:
    • For Redis, context, promise modules
  • E2E tests:
    • For auth usecases (jwt, sessions)
    • For certificate usecases
    • For cache module
  • Redis based cache system (cache wrapper module, cache bucket + invalidating, manual auto-caching decorator)
  • Custom reliable Eslint & Prettier configs
  • Seed, creating and restoring backup scripts for database
  • Dockerization of the application
  • Gathering metrics & analytics (Clickhouse(?), Prometheus, Grafana)
  • Stress testing RPS/TRPS (with Ddosify)
  • CI/CD gitlab

Documentation

  • docs/explanation-architecture.md - explanation of clean architecture (a version of which we follow in this application).

  • docs/elk/* - ELK explanation + guide how to watch logs.

  • docs/references/* - Clean and hexagonal architecture schemas.

  • docs/abstract-sertificate.simplified-class-diagram.png - simplified class diagram for abstract sertificate usecase (in accord to clean architecture).

  • docs/auth.class-diagram.pdf - class diagram for auth (login usecase).

Quick start

  1. Clone this repository:
git clone [email protected]:js/architecture-patterns/backend-nestjs-update.git
  1. Install dependencies:
cd backend-nestjs-update && pnpm i
  1. Run docker containers:
docker-compose -f docker-compose.local.yml up

Requirements

  1. It requires Node.js >= 18.0.0.

    In order to check current Node.js version:

    node -v

    In order to change Node.js version use nvm:

    nvm install 18 && nvm use 18
  2. It requires pnpm package manager.

    In order to install it use:

    npm install -g pnpm

Docker help

Run all containers:

npm run docker:start

Stop all containers:

npm run docker:stop

Restart all containers:

npm run docker:restart

Rebuild application (our API) image + container (f.e after changing node_modules / .env files):

npm run docker:rebuild-app

Remove all containers (for our project):

npm run docker:clean:containers

Remove all images which aren't used by any existing container (dangling):

npm run docker:clean:dangling-images

Remove all volumes which aren't used by any existing container (dangling):

npm run docker:clean:dangling-volumes

Remove all dangling images & volumes, containers (for our project) and application docker image (our API):

npm run docker:clean:full

E2E tests

Usually you run application (with entire infrastructure) via:

npm run docker:start

Then, in order to switch from dev database to test one and restart application container with testing env variables (without running Nest.js server itself):

npm run app:restart-in-test-mode

In order to make previous step and run e2e tests:

npm run test:e2e:restart

In order to re-run E2E tests (being inside testing infrastructure):

npm run test:e2e

Then, in order to come back to dev mode and continue developement:

npm run app:restart-in-dev-mode

or

npm run docker:restart

Miscellaneous

  • Since we use a lot of types in DI (instead of real attaching of implemenation) it can be extremely inconvenient to look for real implementation of injected interface in constructor (being within a class itself). In order to solve this problem:
    1. Select the desired method which depends on type (f.e this.authJwtRepository.findUserByEmail(email), where authJwtRepository is IAuthJwtRepository<PrismaClient>).
    2. Click Go to implementation (CTRL + F12).