🔒 Acceso Protegido

Esta documentación requiere autenticación

Skip to content

Modules

GitBook has a powerful block-based editor that allows you to seamlessly create, update, and enhance your content.

Writing content

GitBook offers a range of block types for you to add to your content inline — from simple text and tables, to code blocks and more. These elements will make your pages more useful to readers, and offer extra information and context.

Either start typing below, or press / to see a list of the blocks you can insert into your page.

Add a new block

1. Open the insert block menu

Press / on your keyboard to open the insert block menu.

2. Search for the block you need

Try searching for "Stepper", for example, to insert the stepper block.

3. Insert and edit your block

Click or press Enter to insert your block. From here, you'll be able to edit it as needed.

🏦 Bank Accounts

Bank account management associated with user accounts.

Documentation:

🗄️ Database

Database services and utilities.

Documentation:

📧 Email

Email sending and management system.

Documentation:

⚙️ Environment

Environment configuration and variable management.

🗄️ Database

Database services and utilities for database management.

Components:

📧 Email

Email sending and management system.

Components:

🌍 Environment

Environment configuration and variable management.

Components:

Utility Modules

🛡️ Auth

Authentication and authorization system with JWT and role-based guards.

Documentation:

🗄️ Database

Database configuration and connection management.

Documentation:

📧 Email

Email service for notifications and communications.

Documentation:

🎫 Freshdesk

Integration with Freshdesk for customer support and ticketing.

Documentation:

Public Interfaces

🌐 API Public

Public API endpoints accessible without authentication.

Documentation:


Module Architecture

The OnSpot backend is built with a modular architecture based on NestJS, where each module encapsulates specific business functionalities. This structure enables scalable, maintainable, and testable development.

Module Structure

🎫 Freshdesk

Integration with the Freshdesk ticket system.

Components:

🏢 Sub Accounts

Sub-account management associated with main accounts.

Components:

👥 Users

Complete user management system.

Components:

💰 Withdrawals

Withdrawal and financial transaction system.

Components:

🔄 Inter-Module Communication

Modules are designed to be independent but can communicate with each other through:

  • Shared services: Services that can be injected into other modules
  • Events: Event system for asynchronous communication
  • Common DTOs: Shared data transfer objects
  • Interfaces: Well-defined contracts between modules

📋 Conventions

All modules follow the same conventions:

  1. Naming: Descriptive names in English
  2. Structure: Consistent folder structure
  3. Documentation: Complete documentation of endpoints and methods
  4. Testing: Unit and integration tests
  5. Security: Implementation of guards and validations

Note: This documentation is based on the current backend structure and is regularly updated to reflect code changes.

Overview

The OnSpot backend is built with a modular architecture based on NestJS, where each module encapsulates specific business functionalities. This structure enables scalable, maintainable, and testable development.

Module Structure

🏗️ Modular Architecture

mermaid
graph TB
    A[App Module] --> B[Auth Module]
    A --> C[Users Module]
    A --> D[Accounts Module]
    A --> E[Subaccounts Module]
    A --> F[Accreditations Module]
    A --> G[Withdrawals Module]
    A --> H[Analytics Module]
    A --> I[Common Module]
    
    B --> J[JWT Strategy]
    B --> K[Local Strategy]
    B --> L[Auth Guards]
    
    C --> M[User Service]
    C --> N[User Controller]
    C --> O[User Entity]
    
    D --> P[Account Service]
    D --> Q[Account Controller]
    D --> R[Account Entity]

Main Modules

1. Auth Module (src/auth/)

Responsibilities:

  • User authentication
  • Role-based authorization
  • JWT token management
  • Passport strategies

Components:

typescript
@Module({
  imports: [
    UsersModule,
    PassportModule,
    JwtModule.registerAsync({
      useFactory: (configService: ConfigService) => ({
        secret: configService.get('JWT_SECRET'),
        signOptions: { expiresIn: '15m' },
      }),
      inject: [ConfigService],
    }),
  ],
  providers: [
    AuthService,
    LocalStrategy,
    JwtStrategy,
    JwtAuthGuard,
    RolesGuard,
  ],
  controllers: [AuthController],
  exports: [AuthService, JwtAuthGuard],
})
export class AuthModule {}

2. Users Module (src/users/)

Responsibilities:

  • System user management
  • User profiles and configurations
  • Relationships with accounts and sub-accounts

Structure:

src/users/
├── dto/
│   ├── create-user.dto.ts
│   ├── update-user.dto.ts
│   └── user-response.dto.ts
├── entities/
│   └── user.entity.ts
├── users.controller.ts
├── users.service.ts
└── users.module.ts

3. Accounts Module (src/accounts/)

Responsibilities:

  • Main account management
  • Account configurations
  • Relationships with sub-accounts

Main Entity:

typescript
@Entity('accounts')
export class Account {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column({ unique: true })
  accountNumber: string;

  @Column()
  name: string;

  @Column({ type: 'decimal', precision: 15, scale: 2, default: 0 })
  balance: number;

  @Column({ default: true })
  isActive: boolean;

  @ManyToOne(() => User, user => user.accounts)
  owner: User;

  @OneToMany(() => Subaccount, subaccount => subaccount.account)
  subaccounts: Subaccount[];
}

4. Subaccounts Module (src/subaccounts/)

Responsibilities:

  • Sub-account management
  • Financial operations
  • Transaction tracking

Characteristics:

  • Complete CRUD for sub-accounts
  • Business validations
  • Change auditing
  • Payment system integration

5. Accreditations Module (src/accreditations/)

Responsibilities:

  • Accreditation processing
  • Fund validation
  • Transaction status management

Accreditation States:

typescript
export enum AccreditationStatus {
  PENDING = 'pending',
  PROCESSING = 'processing',
  COMPLETED = 'completed',
  FAILED = 'failed',
  CANCELLED = 'cancelled'
}

6. Withdrawals Module (src/withdrawals/)

Responsibilities:

  • Withdrawal processing
  • Balance validations
  • Payment provider integration

Withdrawal Flow:

mermaid
sequenceDiagram
    participant U as User
    participant W as Withdrawals Service
    participant A as Accounts Service
    participant P as Payment Provider
    
    U->>W: Request withdrawal
    W->>A: Validate balance
    A-->>W: Balance confirmed
    W->>P: Process payment
    P-->>W: Confirmation
    W->>A: Update balance
    W-->>U: Withdrawal completed

7. Analytics Module (src/analytics/)

Responsibilities:

  • Business metrics
  • Financial reports
  • Administration dashboard

8. Common Module (src/common/)

Responsibilities:

  • Shared utilities
  • Custom decorators
  • Global pipes and filters
  • Shared configurations

Module Configuration

Registration in App Module

typescript
@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      envFilePath: `.env.${process.env.NODE_ENV}`,
    }),
    TypeOrmModule.forRootAsync({
      useFactory: (configService: ConfigService) => ({
        type: 'postgres',
        host: configService.get('DB_HOST'),
        port: configService.get('DB_PORT'),
        username: configService.get('DB_USERNAME'),
        password: configService.get('DB_PASSWORD'),
        database: configService.get('DB_NAME'),
        entities: [__dirname + '/**/*.entity{.ts,.js}'],
        synchronize: configService.get('NODE_ENV') === 'development',
      }),
      inject: [ConfigService],
    }),
    AuthModule,
    UsersModule,
    AccountsModule,
    SubaccountsModule,
    AccreditationsModule,
    WithdrawalsModule,
    AnalyticsModule,
    CommonModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

Module Communication

Dependency Injection

typescript
// In AccountsService
@Injectable()
export class AccountsService {
  constructor(
    @InjectRepository(Account)
    private accountsRepository: Repository<Account>,
    private usersService: UsersService, // Injection from another module
  ) {}
}

Events and Listeners

typescript
// Event emission
@Injectable()
export class WithdrawalsService {
  constructor(private eventEmitter: EventEmitter2) {}

  async processWithdrawal(withdrawalId: string) {
    // Process withdrawal
    this.eventEmitter.emit('withdrawal.processed', { withdrawalId });
  }
}

// Event listening
@Injectable()
export class AnalyticsService {
  @OnEvent('withdrawal.processed')
  handleWithdrawalProcessed(payload: { withdrawalId: string }) {
    // Update metrics
  }
}

Best Practices

1. Separation of Responsibilities

  • Each module has a specific responsibility
  • Avoid circular dependencies
  • Use interfaces for contracts between modules

2. Modular Configuration

typescript
@Module({
  imports: [
    TypeOrmModule.forFeature([User]),
    forwardRef(() => AccountsModule), // For circular dependencies
  ],
  providers: [UsersService],
  controllers: [UsersController],
  exports: [UsersService], // Export for other modules
})
export class UsersModule {}

3. Modular Testing

typescript
describe('UsersModule', () => {
  let module: TestingModule;

  beforeEach(async () => {
    module = await Test.createTestingModule({
      imports: [UsersModule],
    })
    .overrideProvider(UsersService)
    .useValue(mockUsersService)
    .compile();
  });
});

Development Tools

Module Generation

bash
# Create new module
nest generate module payments

# Create module with service and controller
nest generate resource payments --no-spec

Dependency Analysis

bash
# Visualize dependencies between modules
npm run build
npx madge --image graph.svg dist/

Next Steps

Additional Resources

OnspotIntl Documentation