What is a Module?
Introduction
Modules are the foundation of PUQcloud's extensible billing system architecture. They are self-contained, professionally developed components that seamlessly extend the platform's functionality. Each module can add new service types, integrate with external APIs, implement payment gateways, or provide communication channels - all while maintaining consistent performance, security, and user experience standards.
Think of modules as professional plugins that transform PUQcloud from a basic billing system into a comprehensive service management platform capable of handling any business model.
Core Architecture Concept
A module in PUQcloud is a PHP class that inherits from one of four specialized base classes and implements specific business logic. The modular framework provides:
- đ Standardized lifecycle management (installation, activation, updates, deactivation)
- đ Built-in security and permission systems with granular access control
- ⥠Asynchronous task processing for scalable operations
- đ Comprehensive logging and monitoring capabilities
- đ Multi-language support with Laravel's localization
- đ¨ Template and view management with Blade templating
- đž Database integration with migrations and models
- đ External API integration patterns and best practices
Module System Architecture
Hierarchical Inheritance Structure
PUQcloud's module system follows a clean inheritance hierarchy:
App\Modules\Module (Base Class)
âââ Product â Full service lifecycle management
âââ Plugin â System functionality extensions
âââ Payment â Payment gateway integrations
âââ Notification â Communication channel implementations
Class Responsibilities and APIs
A module is an object-oriented PHP class that inherits from App\Modules\Module
and shares a common contract:
- Lifecycle:
activate()
,update()
,deactivate()
- Rendering:
view(string $template, array $data = [])
- Configuration:
config(string $key): mixed
- Asynchronous jobs: queue tasks with
Task::add('ModuleJob', 'Module', $data, $tags)
- Logging:
logInfo()
,logError()
,logDebug()
- Security: built-in permission checks in admin routes/controllers
Derived Module Types and Typical Methods
Product (Service Management)
- Product config:
getProductData()
,saveProductData()
,getProductPage()
- Service config:
getServiceData()
,saveServiceData()
,getServicePage()
- Lifecycle:
create()
âcreateJob()
,suspend()
âsuspendJob()
,unsuspend()
âunsuspendJob()
,termination()
âterminationJob()
,change_package()
âchange_packageJob()
- Client area:
getClientAreaMenuConfig()
,variables_{tab}()
,controllerClient_{tab}{Method}()
- Admin area:
adminPermissions()
,adminSidebar()
,adminWebRoutes()
,adminApiRoutes()
- Status: update provisioning with
Service::setProvisionStatus()
Plugin (System Extensions)
- Lifecycle: initialize resources in
activate()
, clean up indeactivate()
, evolve inupdate()
- Admin area: expose UI via
adminSidebar()
,adminWebRoutes()
,adminApiRoutes()
- Background work: schedule/execute periodic tasks via the queue (
Task::add()
) and event hooks (seehooks.php
) - Note: typically no client-area UI
- Data: define plugin-specific tables/models as needed
Payment (Payment Processing)
- Gateway config:
getModuleData()
, per-gateway settings page viagetSettingsPage()
- Checkout UI: render payment form/session with
getClientAreaHtml()
- Redirects: provide
getReturnUrl()
andgetCancelUrl()
- Webhooks: handle gateway callbacks (e.g.,
apiWebhookPost()
/apiWebhookGet()
) - Transactions: log, reconcile, and handle refunds/chargebacks
Notification (Communication Channels)
- Channel config:
getModuleData()
(server, credentials, encryption, etc.) - Delivery:
send(array $data)
with validation, retries, and logging - Templating: render content using Blade templates and per-channel variables
- Reliability: implement rate limiting and retry/backoff policies
Standard Module Structure
Every module follows this professional directory structure:
modules/{Type}/{ModuleName}/
âââ {ModuleName}.php # Main module class (required)
âââ config.php # Module metadata and settings (required)
âââ hooks.php # Event hooks and listeners (optional)
âââ Controllers/ # HTTP request handlers
â âââ {ModuleName}Controller.php
âââ Services/ # External API clients and business logic
â âââ {ExternalService}Client.php
âââ Models/ # Database models and data validation
â âââ {ModuleName}.php
â âââ {ModuleName}Server.php
âââ views/ # User interface templates
â âââ admin_area/ # Admin panel interface
â â âââ product.blade.php
â â âââ service.blade.php
â â âââ configuration.blade.php
â âââ client_area/ # Client panel interface
â â âââ general.blade.php
â â âââ statistics.blade.php
â â âââ management.blade.php
â âââ assets/ # Static resources
â âââ css/
â âââ js/
â âââ img/
âââ lang/ # Internationalization files
âââ en.php
âââ pl.php
âââ {language}.php
Component Breakdown
Component | Purpose | Required | Description |
Main Class | Core business logic and lifecycle management | â Required | Implements module functionality |
Configuration | Module metadata, version, and settings | â Required | Defines module properties |
Controllers | Handle HTTP requests and API endpoints | â ī¸ Conditional | Required for admin/client interfaces |
Models | Database interactions and data validation | â ī¸ Conditional | Required for data persistence |
Views | User interface templates and forms | â ī¸ Conditional | Required for user interaction |
Services | External API clients and business logic | â Optional | For third-party integrations |
Language Files | Multi-language support and localization | â Optional | For internationalization |
Module Types Deep Dive
1. Product Modules đĄī¸ (Service Management)
Purpose: Complete service lifecycle management with customer billing integration
Real-World Examples:
- puqNextcloud: Cloud storage and collaboration platform
- VPS Services: Virtual private server management
Key Capabilities:
- â Full service lifecycle (create, suspend, unsuspend, terminate, upgrade)
- â Client area integration with custom tabs and interfaces
- â Automated billing and invoicing integration
- â Resource provisioning through external APIs
- â Asynchronous task processing for scalable operations
- â Service status monitoring and health checks
Architecture Example (based on real puqNextcloud implementation):
<?php
use App\Models\Service;
use App\Models\Task;
use App\Modules\Product;
class NextcloudService extends Product
{
// Product configuration for admin
public function getProductData(array $data = []): array
{
$this->product_data = [
'group_uuid' => $data['group_uuid'] ?? '',
'username_prefix' => $data['username_prefix'] ?? 'nc_',
'username_suffix' => $data['username_suffix'] ?? '',
'quota' => $data['quota'] ?? '1GB',
];
return $this->product_data;
}
// Service instance creation
public function create(): array
{
$data = [
'module' => $this,
'method' => 'createJob',
'tries' => 1,
'backoff' => 60,
'timeout' => 600,
'maxExceptions' => 1,
];
$service = Service::find($this->service_uuid);
$service->setProvisionStatus('processing');
Task::add('ModuleJob', 'Module', $data, ['create']);
return ['status' => 'success'];
}
// Asynchronous provisioning logic
public function createJob(): array
{
try {
$service = Service::find($this->service_uuid);
// Generate unique credentials
$this->service_data['username'] = $this->product_data['username_prefix'] .
random_int(100000, 999999) .
$this->product_data['username_suffix'];
$this->service_data['password'] = generateStrongPassword(10);
// Provision through external API
$apiClient = new NextcloudAPIClient($this->getServerConfig());
$result = $apiClient->createUser($this->service_data);
if ($result['status'] === 'success') {
$service->setProvisionStatus('completed');
return ['status' => 'success'];
} else {
$service->setProvisionStatus('failed');
return ['status' => 'error', 'message' => $result['error']];
}
} catch (Exception $e) {
$service->setProvisionStatus('failed');
$this->logError('createJob', 'Provisioning failed', $e->getMessage());
return ['status' => 'error'];
}
}
// Client area interface configuration
public function getClientAreaMenuConfig(): array
{
return [
'general' => [
'name' => 'Overview',
'template' => 'client_area.general',
],
'files' => [
'name' => 'File Manager',
'template' => 'client_area.files',
],
'statistics' => [
'name' => 'Usage Statistics',
'template' => 'client_area.statistics',
],
];
}
}
2. Plugin Modules đ§ (System Extensions)
Purpose: Extend system functionality without managing individual services
Real-World Examples:
- Server Monitoring: Infrastructure health monitoring and alerting
- Advanced Analytics: Custom reporting and business intelligence
- Integration Plugins: Synchronization with CRM, accounting systems
- Workflow Automation: Custom business process automation
- Security Scanners: Vulnerability assessment and monitoring
Key Capabilities:
- â System-wide functionality enhancement
- â Admin interface integration with custom pages
- â Event-driven operations and hooks
- â Background task scheduling and execution
- â Custom data collection and processing
- â Integration with external services and APIs
Architecture Example:
<?php
use App\Modules\Plugin;
use Illuminate\Support\Facades\Schema;
class ServerMonitoringPlugin extends Plugin
{
public function activate(): string
{
try {
// Create monitoring infrastructure
Schema::create('server_monitoring_checks', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('type'); // ping, http, port, ssl
$table->string('target'); // IP/URL to monitor
$table->json('config'); // Check-specific configuration
$table->integer('interval')->default(300); // Check interval in seconds
$table->boolean('active')->default(true);
$table->timestamps();
});
Schema::create('server_monitoring_results', function (Blueprint $table) {
$table->id();
$table->foreignId('check_id')->constrained('server_monitoring_checks');
$table->boolean('status'); // up/down
$table->integer('response_time')->nullable(); // milliseconds
$table->string('error_message')->nullable();
$table->timestamp('checked_at');
$table->timestamps();
});
$this->logInfo('activate', 'Monitoring plugin activated successfully');
return 'success';
} catch (Exception $e) {
$this->logError('activate', 'Activation failed: ' . $e->getMessage());
return 'Error: ' . $e->getMessage();
}
}
public function adminWebRoutes(): array
{
return [
[
'method' => 'get',
'uri' => 'dashboard',
'permission' => 'monitoring-dashboard',
'name' => 'dashboard',
'controller' => 'ServerMonitoringController@dashboard',
],
[
'method' => 'get',
'uri' => 'checks',
'permission' => 'monitoring-checks',
'name' => 'checks',
'controller' => 'ServerMonitoringController@checks',
],
];
}
}
3. Payment Modules đŗ (Payment Processing)
Purpose: Secure payment processing through various payment gateways
Real-World Examples:
- puqStripe: Credit card processing through Stripe
- puqPayPal: PayPal payment integration
- puqPrzelewy24: Polish payment system integration
- puqBankTransfer: Bank transfer instructions and tracking
- Cryptocurrency Payments: Bitcoin, Ethereum, etc.
Key Capabilities:
- â Secure payment form generation and processing
- â Multiple currency support and conversion
- â Refund and chargeback handling
- â Transaction logging and audit trails
- â PCI compliance support and security
- â Webhook handling for payment confirmations
Architecture Example (based on real puqStripe implementation):
<?php
use App\Modules\Payment;
class StripePaymentGateway extends Payment
{
public function getModuleData(array $data = []): array
{
return [
'publishable_key' => $data['publishable_key'] ?? '',
'secret_key' => $data['secret_key'] ?? '',
'webhook_secret' => $data['webhook_secret'] ?? '',
'sandbox' => $data['sandbox'] ?? false,
];
}
public function getClientAreaHtml(array $data = []): string
{
$invoice = $data['invoice'];
$amount = $invoice->getDueAmountAttribute();
$currency = $invoice->client->currency->code;
$stripe = new StripeClient($this->module_data);
$session = $stripe->createSession(
referenceId: $invoice->uuid,
invoiceId: $invoice->number,
description: 'Invoice #' . $invoice->number,
amount: $amount,
currency: $currency,
return_url: $this->getReturnUrl(),
cancel_url: $this->getCancelUrl(),
);
return $this->view('client_area', ['session' => $session]);
}
public function getSettingsPage(array $data = []): string
{
$data['webhook_url'] = route('static.module.post', [
'type' => 'Payment',
'name' => 'puqStripe',
'method' => 'apiWebhookPost',
'uuid' => $this->payment_gateway_uuid
]);
return $this->view('configuration', $data);
}
}
4. Notification Modules đ§ (Communication Channels)
Purpose: Send notifications through various communication channels
Real-World Examples:
- puqSMTP: Professional SMTP email delivery
- puqPHPmail: Basic PHP mail functionality
- puqBell: Push notification system
- SMS Gateways: Twilio, Nexmo, local SMS providers
- Slack/Discord: Team communication integration
Key Capabilities:
- â Multi-channel message delivery
- â Template management and personalization
- â Delivery tracking and status reporting
- â Retry mechanisms for failed deliveries
- â Rate limiting and quota management
- â Rich content support (HTML, attachments, etc.)
Architecture Example (based on real puqSMTP implementation):
<?php
use App\Modules\Notification;
use Illuminate\Support\Facades\Mail;
class SMTPNotificationService extends Notification
{
public function getModuleData(array $data = []): array
{
return [
'email' => $data['email'] ?? '',
'server' => $data['server'] ?? '',
'sender_name' => $data['sender_name'] ?? '',
'port' => $data['port'] ?? 587,
'encryption' => $data['encryption'] ?? 'tls',
'username' => $data['username'] ?? '',
'password' => $data['password'] ?? '',
];
}
public function send(array $data = []): array
{
try {
$validator = Validator::make($data, [
'to' => 'required|email',
'subject' => 'required|string|max:255',
'message' => 'required|string',
]);
if ($validator->fails()) {
return [
'status' => 'error',
'message' => $validator->errors(),
'code' => 422,
];
}
$mailConfig = $this->buildMailerConfiguration();
Mail::mailer($mailConfig)->send(new NotificationMail(
$data['to'],
$data['subject'],
$data['message'],
$data['attachments'] ?? []
));
$this->logInfo('send', 'Email sent successfully', [
'to' => $data['to'],
'subject' => $data['subject']
]);
return ['status' => 'success'];
} catch (Exception $e) {
$this->logError('send', 'Email sending failed', $e->getMessage());
return ['status' => 'error', 'message' => 'Failed to send email'];
}
}
}
How Modules Integrate with PUQcloud
Lifecycle Management
Every module follows a standardized lifecycle:
- đĻ Installation: Module files are uploaded to the correct directory structure
- đ Discovery: System automatically detects and registers the module
- âī¸ Activation:
activate()
method creates databases, configures settings - đ Operation: Module handles requests and performs designated functions
- đ Updates:
update()
method handles version migrations and schema changes - âšī¸ Deactivation:
deactivate()
method cleans up resources and data
Integration Points
Admin Interface Integration
// Navigation menu configuration
public function adminSidebar(): array
{
return [
[
'title' => 'Server Management',
'link' => 'servers',
'active_links' => ['servers', 'server-groups'],
'permission' => 'manage-servers'
]
];
}
// Route definitions with permissions
public function adminWebRoutes(): array
{
return [
[
'method' => 'get',
'uri' => 'servers',
'permission' => 'view-servers',
'name' => 'servers',
'controller' => 'ServerController@index'
]
];
}
Client Area Integration
// Multi-tab client interface
public function getClientAreaMenuConfig(): array
{
return [
'overview' => [
'name' => 'Service Overview',
'template' => 'client_area.overview'
],
'management' => [
'name' => 'Account Management',
'template' => 'client_area.management'
],
'statistics' => [
'name' => 'Usage Statistics',
'template' => 'client_area.statistics'
]
];
}
Â
Â
No Comments