Skip to content

Implementation Notes

Version: 1.0.0 | Last Updated: 2025-01-06 | Status: Active

Overview

Implementation notes provide detailed documentation of how business logic is implemented in MBPanel. These notes complement the architecture and API documentation by explaining the "how" behind the code.

What Are Implementation Notes?

Implementation notes capture: - Business logic implementation details - Data flow and state management - Edge cases and error handling - Performance considerations - Integration patterns - Code-level design decisions

Structure

By Domain

Domain Implementations - Full DDD implementations with state machines, invariants, and orchestration.

By Module

Module Implementations - Lighter features without full DDD patterns.

Domain Implementations

Core Domains

Business Domains

  • Payments - Payment processing
  • Billing - Subscriptions and invoicing
  • Nodes - Server and node management

Module Implementations

Cross-Cutting Modules

  • Auth - Authentication and tokens
  • Users - User management
  • Teams - Team and membership
  • RBAC - Roles and permissions
  • Activity - Activity logging
  • Webhooks - Webhook management
  • SFTP - SFTP access

Implementation Note Template

# [Domain/Module Name] Implementation

**Version:** 1.0.0
**Last Updated:** YYYY-MM-DD
**Status:** Stable | Beta | Deprecated

## Overview
[Brief description of what this domain/module does]

## Architecture
[Mermaid diagram showing component structure]

## Business Logic

### Core Operations
[Description of main operations]

### State Machine
[If applicable, Mermaid state diagram]

### Invariants
[Business rules that must always be true]

## Data Model

### Entities
[Description of key entities]

### Relationships
[How entities relate to each other]

## API Endpoints

### Operations
[Table of endpoints with descriptions]

### Request/Response
[Example schemas]

## External Integrations

### Virtuozzo
[How Virtuozzo API is used]

### RabbitMQ
[Events published/consumed]

### Redis
[Caching strategies]

## Error Handling

### Error Scenarios
[What can go wrong and how it's handled]

### Retry Logic
[How transient failures are handled]

## Performance Considerations

### Optimization Strategies
[How performance is optimized]

### Bottlenecks
[Known performance limitations]

## Testing

### Unit Tests
[Test coverage and approach]

### Integration Tests
[How component interactions are tested]

## Security

### Authentication
[How auth is handled]

### Authorization
[Permission checks]

### Data Protection
[Sensitive data handling]

## Monitoring

### Metrics
[Key metrics emitted]

### Logging
[What is logged and why]

## References
- [Related ADR-XXX](../architecture/adr/xxx.md)
- [Related PRD-XXX](../prd/xxx.md)
- [API Reference](../api/reference/xxx.md)

Domains vs Modules

Domains (Full DDD)

Use when: - Complex business logic - Multiple states and transitions - Rich domain model - Complex invariants - orchestration of multiple operations

Characteristics: - State machines for lifecycle - Domain events for coordination - Rich domain models - Complex business rules - Example: environments, sites, backups

Modules (Lightweight)

Use when: - Simple CRUD operations - Minimal state transitions - Thin domain model - Simple business rules - Single-purpose functionality

Characteristics: - Direct data access - Simple validation - Thin service layer - Example: users, teams, activity

Common Patterns

Repository Pattern

All data access goes through repositories:

class SiteRepository:
    async def create(self, site: Site) -> Site:
        # Database logic
        pass

    async def get_by_id(self, site_id: int) -> Site | None:
        # Database logic
        pass

Service Layer

Business logic in domain services:

class SiteService:
    def __init__(
        self,
        repo: SiteRepository,
        virt_client: VirtuozzoClient,
        event_bus: EventBus
    ):
        self.repo = repo
        self.virt_client = virt_client
        self.event_bus = event_bus

    async def create_site(self, data: SiteCreate) -> Site:
        # Business logic
        # External calls
        # Event publishing
        pass

Domain Events

Async event-driven coordination:

# Publish event
await event_bus.publish(
    SiteCreatedEvent(site_id=site.id)
)

# Handle event
@event_handler(SiteCreatedEvent)
async def on_site_created(event: SiteCreatedEvent):
    # Send welcome email
    # Create initial backup
    pass

State Machines

Domains use state machines for lifecycle management:

stateDiagram-v2
    [*] --> Provisioning
    Provisioning --> Running: provision_success
    Provisioning --> Failed: provision_failed
    Running --> Stopped: stop
    Stopped --> Running: start
    Running --> Deleting: delete
    Deleting --> [*]: delete_complete

Invariants

Business rules that must always be true: - Site invariant: A site must have at least one environment - Environment invariant: An environment must belong to exactly one site - Backup invariant: A backup must reference a valid site snapshot

Error Handling Strategy

Validation Errors

if not domain_name:
    raise ValidationError(
        "Domain name is required",
        field="domain_name"
    )

Business Rule Violations

if site.status != SiteStatus.ACTIVE:
    raise BusinessRuleViolation(
        "Cannot create backup for inactive site",
        site_id=site.id,
        status=site.status
    )

External Service Failures

try:
    await virt_client.create_site(site_data)
except VirtuozzoError as e:
    logger.error("virtuozzo_create_failed", error=str(e))
    # Retry or fail based on error type

Performance Optimization

Database Optimization

  • Use indexes for common query patterns
  • Batch operations where possible
  • Use select_related/prefetch_related for joins

Caching Strategy

  • Cache frequently accessed data (Redis)
  • Invalidate cache on mutations
  • Use cache-aside pattern

Async Operations

  • Offload long-running tasks to Celery
  • Use async/await for I/O operations
  • Parallelize independent operations

Testing Strategy

Unit Tests

  • Test business logic in isolation
  • Mock external dependencies
  • Cover success and failure paths

Integration Tests

  • Test component interactions
  • Use test database
  • Verify side effects

E2E Tests

  • Test critical user journeys
  • Use full stack
  • Verify end-to-end workflows