Backend

Building a Skill-Based System with NestJS

An in-depth look at the architecture of a skill-based system built with NestJS, Prisma, and a powerful Workflow Engine.

January 8, 2024
4 min read
Building a Skill-Based System with NestJS

Introduction

In this article, we’ll explore the architecture of a skill-based system built with NestJS. This system allows you to create, manage, and execute skills, which are essentially workflows with a specific purpose. We’ll delve into the core components of the system, including the Skills module, the Workflow Engine, and the database schema.

Core Technologies

This skill-based system is built on a modern and robust technology stack:

  • NestJS: A progressive Node.js framework for building efficient, reliable and scalable server-side applications.
  • Prisma: A next-generation ORM for Node.js and TypeScript. It helps developers build faster and make fewer errors.
  • Workflow Engine: A powerful engine for executing complex workflows.
  • TypeScript: A typed superset of JavaScript that compiles to plain JavaScript.

Architecture Overview

The system is designed with a modular architecture, with the Skills module at its core. This module is responsible for managing the lifecycle of a skill, from creation to execution.

graph TB
    subgraph "Client Applications"
        Web[Web Client]
        Mobile[Mobile Client]
        API_Client[API Client]
    end
    
    subgraph "Skills Module"
        SkillsController[Skills Controller]
        ChannelsController[Channels Controller]
        Executor[Skill Executor]
    end
    
    subgraph "Workflow Engine"
        WorkflowRunner[Workflow Runner]
        NodeProcessor[Node Processor]
    end
    
    subgraph "Data Layer"
        DB[(PostgreSQL)]
    end
    
    Web --> SkillsController
    Mobile --> SkillsController
    API_Client --> SkillsController
    
    SkillsController --> Executor
    ChannelsController --> Executor
    Executor --> WorkflowRunner
    WorkflowRunner --> NodeProcessor
    
    SkillsController --> DB
    ChannelsController --> DB
    WorkflowRunner --> DB

Modules

The application is divided into several modules, each with a specific responsibility:

  • Skills: Manages the creation, execution, and versioning of skills.
  • Channels: Represents the different channels through which a skill can be executed (e.g., web, mobile, API).
  • Workflows: The underlying engine that powers the execution of skills.
  • API: Exposes a RESTful API for interacting with the skill-based system.

The Skill Lifecycle

The system manages the entire lifecycle of a skill, from creation to execution.

  1. Creation: A new skill is created with a name, description, and configuration.
  2. Versioning: The skill can be versioned, allowing for changes to be made without affecting the production version.
  3. Publishing: A specific version of the skill can be published, making it available for execution.
  4. Execution: The skill is executed through a specific channel, using the powerful Workflow Engine.
  5. Sharing: Skills can be shared with other companies or users.
stateDiagram-v2
    [*] --> Created: Create Skill
    Created --> Configured: Configure Settings
    Configured --> Versioned: Save Version
    Versioned --> Published: Publish to Channel
    Published --> Active: Activate
    Active --> Executing: Execute via Channel
    Executing --> Completed: Success
    Executing --> Failed: Error
    Completed --> Active
    Failed --> Active
    Active --> Shared: Share with Others
    Shared --> Active
    Active --> Versioned: Create New Version
    Versioned --> Configured: Edit Configuration

Database Schema

The database schema is designed to be flexible and scalable. It uses a relational data model to store information about skills, channels, and their relationships.

erDiagram
    SKILLS ||--o{ SKILL_VERSIONS : has
    SKILLS ||--o{ SKILL_CHANNELS : published_to
    SKILLS ||--o{ SHARED_SKILLS : shares
    CHANNELS ||--o{ SKILL_CHANNELS : contains
    
    SKILLS {
        uuid id PK
        string name
        string description
        uuid company_id FK
        timestamp created_at
        timestamp updated_at
    }
    
    SKILL_VERSIONS {
        uuid id PK
        uuid skill_id FK
        int version_number
        json configuration
        uuid workflow_id FK
        boolean published
        timestamp created_at
    }
    
    CHANNELS {
        uuid id PK
        string name
        string type
        json settings
    }
    
    SKILL_CHANNELS {
        uuid id PK
        uuid skill_id FK
        uuid channel_id FK
        uuid version_id FK
        boolean active
    }
    
    SHARED_SKILLS {
        uuid id PK
        uuid skill_id FK
        uuid shared_with_company_id FK
        string permissions
        timestamp shared_at
    }

API Design

The API is designed to be RESTful and easy to use. It provides endpoints for managing skills, channels, and their versions. The API is secured using an API key, and it uses Swagger for documentation.

Conclusion

This skill-based system is a powerful and flexible solution for building applications that require a high degree of customization and automation. Its modular architecture, robust technology stack, and well-designed API make it a great choice for a wide range of applications.

Tags

#NestJS #Prisma #Workflow Engine #Skills #Architecture
Rommel

Written by Rommel Saquicela

Senior Tech Lead & Solutions Architect

View Profile