React / NextJS / TypeScript / MongoDB / NodeJS Portfolio

JOB API

This is a demo Job API, users are able to create jobs and user accounts. It is not completed yet, but I am adding features regularly!
A user is able to create a job post and tags for each job after he is authenticated. To achieve this i used Many-to-Many with Two-way Referencing Strategy, To speed up the response, I used compression dependency. The API has good security features implemented, like: CORS, request sanitazation against XSS attacks, CSURF, enforce HTTPS, JWT, logging, rate limiter against brute-force attack and etc.
Indexes have been strategically added to key fields in the database schemas to improve query performance and ensure data integrity, such as indexing job titles, locations, and employment types, as well as ensuring unique usernames and job-tag pairs.
Additionally, a histogram metric has been implemented to track API request durations, enabling performance monitoring and optimization.

Features:

  • CRUD module for jobs
  • Tags for jobs using Many-to-Many with Two-way Referencing Strategy
  • CRUD module for users
  • User registration and authentication
  • Security
  • Indexing
  • Monitoring - Prometheus and Grafana
Click here to read more about Essential Security Practices for a Secure Node.js Application

Click here to read How to optimize Mongo DB Query (Linear VS Exponential Change) to achieve higher performance

Click here to read about different stratigies for search items based on tags

Try-Catch Pollution: Understanding the Problem and How to Fix It!

Pros and Cons of Different Types of Database IDs

Main Technologies:

  • ExpressJS
  • TypeScript
  • Mongoose
  • MongoDB
  • JWT
Dependencies I used in the project:
  • class-transformer: class-transformer is a TypeScript library that transforms plain JavaScript objects into class instances and vice versa, enabling the use of class methods, validation, and custom transformations.
  • class-validator: class-validator is a TypeScript library that allows you to apply declarative validation rules to class properties using decorators, ensuring that incoming data conforms to the expected structure and constraints. It provides built-in validation decorators (e.g., @IsString, @IsNotEmpty) and supports custom validation logic, making it ideal for validating request bodies, DTOs, or any data objects in a clean and type-safe way.
  • reflect-metadata: reflect-metadata is a TypeScript library that allows you to add and retrieve metadata at runtime using decorators. It enables storing metadata on classes, methods, or properties and is often used in frameworks and libraries that rely on decorators, such as for validation, dependency injection, or serialization. By using reflect-metadata, you can attach extra information to your code and access it later during runtime, making it a powerful tool for building dynamic and flexible applications.
  • argon2: Argon2 is a password hashing algorithm that is widely recognized for its security and efficiency. It was chosen as the winner of the Password Hashing Competition in 2015, a contest aimed at identifying a new standard for hashing passwords securely.
  • compression: This is a middleware that compresses response bodies using various algorithms, such as gzip, deflate, or Brotli. When the client supports one of these compression methods, the server can compress the response before sending it to the client. This reduces the amount of data transferred over the network, which can improve load times and reduce bandwidth usage.
  • CSURF: One common and effective method to prevent CSRF attacks is using CSRF tokens. A CSRF token is a unique, secret, and unpredictable value that is generated by the server and included in requests that alter the state on the server.
  • snyk: Regularly updating your dependencies is crucial for mitigating vulnerabilities in your application. Tools like npm audit and Snyk can help you identify and fix security issues in your dependencies.
  • cors: (Cross-Origin Resource Sharing) is a security feature that allows web applications to control and restrict which external domains can access their resources by specifying allowed origins and HTTP methods.
  • dompurify: Is a JS library that sanitizes HTML and prevents XSS (cross-site scripting) attacks by cleaning and sanitizing user-generated content in web applications.
  • jsdom: Is a JS implementation of the DOM (Document Object Model) that enables server-side manipulation and parsing of HTML and XML documents in Node.js.
  • dotenv: Is a zero-dependency module that loads environment variables from a .env file into process.env, allowing you to manage sensitive configuration data separately from your codebase.
  • express-rate-limit: Is a middleware for ExpressJS that helps to limit repeated requests to public APIs and/or endpoints, protecting against brute-force attacks.
  • helmet: Is an ExpressJS middleware that helps secure your app by setting various HTTP headers to protect against common web vulnerabilities, such as cross-site scripting (XSS), clickjacking, content security policy, and other common attacks that can exploit web application security flaws.
  • enforce HTTPS: Use Helmet’s HSTS module to ensure that browsers only access your server over HTTPS, preventing SSL stripping attacks.
  • http-status-codes: Is a Node.js module that provides a comprehensive list of HTTP status codes and their associated messages for easy use in web applications.
  • jsonwebtoken: Is a library used for generating and verifying JSON Web Tokens (JWT) to securely transmit information between parties as a JSON object. Your JWT_SECRET should be a long and complex string. A strong secret typically includes a mix of uppercase and lowercase letters, numbers, and special characters. Consider using a shorter expiration time and implementing refresh tokens for maintaining user sessions.
  • log4js: Is a logging library for Node.js, inspired by Apache Log4j, that provides a flexible and powerful logging framework to capture, format, and manage log messages.
  • mongoose: Is an Object Data Modeling (ODM) library for MongoDB and Node.js that provides a schema-based solution to model your application data, including built-in type casting, validation, query building, and business logic hooks.
  • nodemon: Is a development tool that automatically restarts your Node.js application when it detects file changes, enhancing the development workflow.
  • Grafana: Is an open-source analytics and monitoring platform used to visualize and analyze data collected from various sources.
  • Prometheus: Is an open-source monitoring and alerting toolkit designed for reliability and scalability. It is primarily used for time-series data collection and analysis, especially in cloud-native and microservices environments.

BOOK API

The bookAPI is a RESTful API built with Fastify, a high-performance web framework for Node.js, designed to manage and interact with a collection of books. The API allows users to create, read, and manage books, along with their associated tags and categories. Additionally, the API supports role-based access control for users (using Keyclock), ensuring secure and efficient handling of different operations based on user roles.

Features:

  • CRUD operations for books, tags, and categories. (not completed)
  • Keyclock - Role-based user management, where different users have different access levels (e.g., admin, editor). (not completed)
  • PostgreSQL database integration using typeORM to manage and interact with relational data. (not completed)
  • TRY-CATCH logic handled globally with global error handler using a fastify hook
    The pattern allows you to handle all errors globally, and in production, it hides sensitive information while logging the details for debugging.

    Advantages:

    • Centralized error handling: You avoid repetitive try-catch blocks in every route handler.
    • Consistency: All errors are logged, and appropriate responses are sent back to the client.
    • Flexible error responses: You can choose to show different error messages based on the environment (e.g., hiding sensitive data in production).
  • OOP Oriented using custom decorators

    Advantages:

    • Code Reusability: Decorators allow for reusable logic to be applied to methods or classes, reducing code duplication.
    • Separation of Concerns: By using decorators, you can keep your core business logic clean and separate from cross-cutting concerns like validation, logging, or authorization.
    • Enhanced Readability: Custom decorators make code more expressive and readable by abstracting common patterns or behaviors into meaningful annotations.
    • Extensibility: You can easily extend or modify the behavior of classes and methods without altering the original code, making it adaptable to changes.
    • DRY Principle: Decorators help in applying the same behavior across multiple methods or classes, adhering to the "Don't Repeat Yourself" principle.

Main Technologies:

  • Fastify - A fast and low-overhead web framework for building APIs. It is designed to provide high performance and developer-friendly features.
  • TypeScript - A typed superset of JavaScript that ensures better code quality and maintainability with static type checking.
  • Tsyringe - A lightweight dependency injection library for TypeScript that allows for clean and modular code. It helps manage dependencies in a simple, efficient way, particularly useful when managing services like repositories and controllers.
  • Nodemon - A utility that monitors for any changes in your source code and automatically restarts the server, boosting development efficiency by eliminating the need for manual restarts.
  • PostgreSQL - A powerful, open-source relational database system that provides robust data storage and management. The database stores information about books, categories, tags, and user roles.
  • typeORM - An Object-Relational Mapping (ORM) library used to interact with the PostgreSQL database. It simplifies database management by allowing developers to interact with the database using TypeScript entities and repositories, reducing the complexity of raw SQL queries.
  • Pino - is a high-performance logging library for Node.js that provides fast, structured, and efficient logging. It is used because it minimizes the overhead in applications, especially for logging high volumes of data, and outputs logs in JSON format, making them easy to integrate with log management systems.
  • Keycloak - An open-source identity and access management solution for modern applications and services. Keycloak provides features like single sign-on (SSO), identity brokering, and social login, along with fine-grained access control. It is used in this project to manage authentication and role-based access control for the user section, ensuring secure and scalable user management.
In this project i have not focused on security and other things which are done in the above project

VOTING API

The Voting App is a real-time application that allows users to vote on topics or polls, enabling interactive participation and immediate feedback. Built with NestJS for the backend,Redis for fast data storage (using Docker), TypeScript for type safety, and Socket.io for live updates, the app also leverages JWT for secure user authentication.

This project explores advanced features of NestJS and Socket.io integration, including creating APIs, handling connections, and implementing real-time updates with Redis as the data store. The application is designed with modularity, scalability, and security in mind.

Features:

  • Core API and Controllers: Creating RESTful APIs and WebSocket Gateways with NestJS. Setting up dynamic modules to manage Redis and RedisJSON.
  • Authentication and Authorization: JWT-based authentication module for secure access tokens. Implementing role-based access control with admin-only handlers.
  • Real-Time Features: Setting up Socket.io gateways to manage connections and events. Adding participants to polls and managing WebSocket rooms. Handling nomination events and vote submission in real time.
  • Validation and Error Handling: Implementing advanced validation with NestJS decorators. Configuring exception filters for detailed error responses.
  • Create Poll: Start a new ranked-choice poll.
  • Join Poll: Allow participants to join active polls.
  • Rejoin Poll: Enable reconnections for participants who were disconnected.
  • Nominate Options: Add nominations for participants to vote on.
  • Submit Votes: Collect and securely tally participant votes.
  • Close Polls: End polls and calculate final rankings.

System Design - VOTING API