Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Helium Project Structure Guide

This document describes the modular architecture and organization of the Helium VPN SaaS system.

Project Overview

Helium is a modern VPN SaaS system built with Rust, organized as a workspace with multiple modules. The system follows a modular architecture where each module represents a specific business domain.

Module Architecture

Each module follows a consistent internal structure with standardized components:

1. Entity Layer (entities/)

Purpose: Data models and database access patterns

Structure:

entities/
├── mod.rs                          # Module exports
├── db/                             # Database entity processors
│   ├── mod.rs
│   ├── user_account.rs             # User account queries/commands
│   └── ...
└── redis/                          # Redis entity processors
    ├── mod.rs
    ├── session.rs                  # Session cache operations
    └── ...

Key Patterns:

  • Implements Processor<Input, Result<Output, sqlx::Error>> for DatabaseProcessor
  • Contains all SQL queries and database operations
  • Separated by storage backend (db/ for PostgreSQL, redis/ for Redis)
  • No business logic - pure data access

2. Service Layer (services/)

Purpose: Business logic orchestration and workflows

Structure:

services/
├── mod.rs                          # Service exports
├── manage.rs                       # Management operations
├── user_profile.rs                 # User profile management
└── ...

Key Patterns:

  • Implements Processor<Input, Result<Output, Error>> for service operations
  • Orchestrates multiple entity operations
  • Handles validation, transformation, and business rules
  • No direct SQL - delegates to entity processors
  • Uses DatabaseProcessor for data access

Example:

#[derive(Clone)]
pub struct UserManageService {
    pub db: sqlx::PgPool,
}

impl Processor<ListUsersRequest, Result<ListUsersResponse, Error>> for UserManageService {
    async fn process(&self, input: ListUsersRequest) -> Result<ListUsersResponse, Error> {
        let db = DatabaseProcessor::from_pool(self.db.clone());
        let users = db.process(ListUsers { ... }).await?;
        Ok(ListUsersResponse { users })
    }
}

3. gRPC Layer (rpc/)

Purpose: gRPC service implementations and external API

Structure:

rpc/
├── mod.rs                          # RPC exports
├── auth_service.rs                 # Authentication gRPC service
├── manage_service.rs               # Management gRPC service
├── middleware.rs                   # gRPC middleware
└── ...

Key Patterns:

  • Implements generated gRPC trait definitions
  • Converts protobuf messages to service DTOs
  • Delegates to service layer via Processor::process
  • Handles authentication and authorization

4. Hook System (hooks/)

Purpose: Event-driven side effects and integrations

Structure:

hooks/
├── mod.rs                          # Hook exports
├── billing.rs                      # Billing event hooks
├── register.rs                     # Registration hooks
└── ...

Key Patterns:

  • Responds to domain events
  • Handles cross-module integrations
  • Implements side effects (notifications, external API calls)
  • Decoupled from main business flows

5. Event System (events/)

Purpose: Domain event definitions and publishing

Structure:

events/
├── mod.rs                          # Event exports
├── user.rs                         # User-related events
├── order.rs                        # Order events
└── ...

Key Patterns:

  • Defines domain events using message queue integration
  • Publishes events for cross-module communication
  • Enables audit trails and analytics
  • Supports eventual consistency patterns

6. API Layer (api/)

Purpose: REST API endpoints and HTTP handlers

Structure:

api/
├── mod.rs                          # API exports
├── subscribe.rs                    # Subscription endpoints
└── xrayr/                          # XrayR integration APIs
    ├── mod.rs
    └── ...

Key Patterns:

  • Implements REST endpoints using Axum
  • Handles HTTP-specific concerns (parsing, serialization)
  • Delegates to service layer
  • Provides alternative to gRPC for specific use cases

7. Cron Jobs (cron.rs)

Purpose: Scheduled tasks and background jobs

Key Patterns:

  • Implements periodic maintenance tasks
  • Handles cleanup operations
  • Manages recurring billing cycles
  • Executes system health checks

8. Testing (tests/)

Purpose: Integration and unit tests

Structure:

tests/
├── common/                         # Test utilities
│   └── mod.rs                      # Common test setup
├── service_name_test.rs            # Service integration tests
└── ...

Key Patterns:

  • Integration tests for complete workflows
  • Uses testcontainers for database testing
  • Isolated test environments
  • Comprehensive service testing

Module Configuration

Dependencies (Cargo.toml)

Each module declares:

  • Workspace dependencies (shared versions)
  • Inter-module dependencies
  • Module-specific dependencies
  • Dev dependencies for testing
  • Build dependencies (typically tonic-prost-build for gRPC)

Build Configuration (build.rs)

Most modules include build scripts for:

  • gRPC code generation from proto files
  • Custom compilation steps
  • Environment-specific builds

Module Entry Point (lib.rs)

Standard module structure:

#![forbid(clippy::unwrap_used)]
#![forbid(unsafe_code)]
#![deny(clippy::expect_used)]
#![deny(clippy::panic)]

pub mod config;
pub mod cron;
pub mod entities;
pub mod events;
pub mod hooks;      // Optional
pub mod api;        // Optional
pub mod rpc;
pub mod services;

Protocol Buffers (proto/)

Organization: Organized by module with consistent naming:

proto/
├── auth/
│   ├── auth.proto                  # Core auth services
│   ├── account.proto               # Account management
│   └── manage.proto                # Admin operations
├── telecom/
│   ├── telecom.proto               # VPN services
│   └── manage.proto                # Telecom management
└── ...

Patterns:

  • Service definitions mirror module structure
  • Consistent message naming conventions
  • Shared types in common proto files

Key Architectural Principles

1. Processor Pattern

All APIs use the kanau::processor::Processor trait for consistent interfaces and composability.

2. Separation of Concerns

  • Entities: Data access only
  • Services: Business logic only
  • RPC/API: Protocol handling only
  • Events/Hooks: Side effects only

3. Database Abstraction

Services never contain raw SQL - all database access goes through entity processors.

4. Event-Driven Architecture

Modules communicate via events to maintain loose coupling.

5. RBAC and Audit

Administrative operations implement consistent role-based access control and audit logging.

Development Guidelines

Adding a New Module

  1. Create module directory under modules/
  2. Add basic Cargo.toml with workspace dependencies
  3. Create src/lib.rs with standard module structure
  4. Add module to workspace Cargo.toml
  5. Create proto definitions if gRPC services needed
  6. Implement entities → services → rpc layers in order

Testing Strategy

  1. Unit tests for complex business logic in services
  2. Integration tests in tests/ directory
  3. Use testcontainer-helium-modules for database tests
  4. Mock external dependencies
  5. Test error handling paths

Documentation Standards

  • Document all public APIs
  • Include examples for complex workflows
  • Maintain this guide as modules evolve
  • Document breaking changes in module changelogs

This modular architecture enables independent development, testing, and deployment of features while maintaining system coherence through standardized patterns and interfaces.