🔒 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