1445 lines
38 KiB
Markdown
1445 lines
38 KiB
Markdown
# Advanced Features - Extended Planning Session
|
|
|
|
This document captures additional features discussed after the initial planning phase. These enhance the platform with advanced capabilities for operations, customer experience, and business intelligence.
|
|
|
|
---
|
|
|
|
## 1. Task Automation & Scheduling
|
|
|
|
### Customer-Configurable Task Scheduler
|
|
**Decision: Full scheduler with customer control**
|
|
|
|
Customers can create automated tasks for their services:
|
|
|
|
#### Features
|
|
- **Scheduled Reboots**: Reboot VPS every Sunday at 3 AM
|
|
- **Snapshot Creation**: Auto-create snapshots weekly
|
|
- **Backup Scheduling**: Daily backups at custom times
|
|
- **Script Execution**: Run custom scripts on schedule (advanced users)
|
|
- **Maintenance Windows**: Define when automated tasks can run
|
|
|
|
#### Implementation
|
|
```sql
|
|
automated_tasks table:
|
|
├── id
|
|
├── service_id
|
|
├── user_id
|
|
├── task_type (reboot, snapshot, backup, custom_script)
|
|
├── schedule_cron (cron expression)
|
|
├── enabled (boolean)
|
|
├── last_run_at
|
|
├── next_run_at
|
|
├── script_content (for custom scripts - nullable)
|
|
├── notification_enabled (notify customer on completion)
|
|
├── max_retries
|
|
├── created_at, updated_at
|
|
|
|
task_executions table:
|
|
├── id
|
|
├── automated_task_id
|
|
├── status (pending, running, completed, failed)
|
|
├── started_at
|
|
├── completed_at
|
|
├── output (execution logs)
|
|
├── error_message (if failed)
|
|
```
|
|
|
|
---
|
|
|
|
## 2. Enterprise Clustering & High Availability
|
|
|
|
### Clustering for Enterprise Customers
|
|
**Decision: Enterprise feature (manual setup)**
|
|
|
|
#### Features
|
|
- Load balancer provisioning
|
|
- Multi-server clusters
|
|
- Auto-failover configuration
|
|
- Shared storage setup
|
|
- Custom architecture consultation
|
|
|
|
#### Implementation Approach
|
|
- Not automated - requires sales discussion
|
|
- Custom pricing per configuration
|
|
- Admin provisions infrastructure manually
|
|
- Documented in enterprise agreements
|
|
|
|
---
|
|
|
|
## 3. Resource Usage Forecasting
|
|
|
|
### AI-Powered Usage Predictions
|
|
**Decision: Yes, with proactive alerts**
|
|
|
|
#### Features
|
|
- Track resource usage trends (CPU, RAM, disk, bandwidth)
|
|
- Machine learning predictions (linear regression, time series)
|
|
- Alerts: "Based on current usage, you'll hit bandwidth cap in 5 days"
|
|
- Upgrade suggestions before hitting limits
|
|
|
|
#### Implementation
|
|
```php
|
|
// app/Services/Analytics/UsageForecastingService.php
|
|
|
|
class UsageForecastingService
|
|
{
|
|
public function predictBandwidthUsage(Service $service): array
|
|
{
|
|
// Get last 30 days of bandwidth usage
|
|
$usage = BandwidthUsage::where('service_id', $service->id)
|
|
->where('created_at', '>=', now()->subDays(30))
|
|
->orderBy('created_at')
|
|
->get();
|
|
|
|
// Simple linear regression
|
|
$trend = $this->calculateTrend($usage);
|
|
|
|
// Predict when quota will be exceeded
|
|
$quota = $service->plan->bandwidth_quota_gb * 1024 * 1024 * 1024;
|
|
$currentUsage = $usage->sum('total_bytes');
|
|
$daysUntilCap = ($quota - $currentUsage) / $trend['daily_increase'];
|
|
|
|
return [
|
|
'current_usage' => $currentUsage,
|
|
'quota' => $quota,
|
|
'trend' => $trend,
|
|
'days_until_cap' => max(0, $daysUntilCap),
|
|
'predicted_overage' => $this->predictOverage($trend, $daysUntilCap),
|
|
];
|
|
}
|
|
|
|
// Alert customer if hitting cap within 7 days
|
|
public function checkAndAlert(Service $service)
|
|
{
|
|
$forecast = $this->predictBandwidthUsage($service);
|
|
|
|
if ($forecast['days_until_cap'] <= 7) {
|
|
Mail::to($service->user)->send(
|
|
new BandwidthCapPredicted($service, $forecast)
|
|
);
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 4. Game Server Monitoring Integration
|
|
|
|
### BattleMetrics & GameTracker Integration
|
|
**Decision: Yes, integrate external monitoring**
|
|
|
|
#### Features
|
|
- Show real-time player count
|
|
- Display server rank/popularity
|
|
- Show uptime statistics from external sources
|
|
- Link to public server profiles
|
|
|
|
#### Implementation
|
|
```php
|
|
// app/Services/GameServerMonitoring/BattleMetricsService.php
|
|
|
|
class BattleMetricsService
|
|
{
|
|
public function getServerStats(string $gameServerIp): array
|
|
{
|
|
$response = Http::get("https://api.battlemetrics.com/servers", [
|
|
'filter[game]' => 'minecraft',
|
|
'filter[search]' => $gameServerIp,
|
|
]);
|
|
|
|
return [
|
|
'players_online' => $response['data'][0]['attributes']['players'],
|
|
'max_players' => $response['data'][0]['attributes']['maxPlayers'],
|
|
'rank' => $response['data'][0]['attributes']['rank'],
|
|
'uptime' => $response['data'][0]['attributes']['uptime'],
|
|
'profile_url' => "https://battlemetrics.com/servers/...",
|
|
];
|
|
}
|
|
}
|
|
```
|
|
|
|
```sql
|
|
game_server_stats table:
|
|
├── id
|
|
├── service_id
|
|
├── players_online
|
|
├── max_players
|
|
├── rank
|
|
├── uptime_percent
|
|
├── battlemetrics_id
|
|
├── gametracker_id
|
|
├── fetched_at
|
|
├── created_at
|
|
```
|
|
|
|
---
|
|
|
|
## 5. Notification Center & Unified Inbox
|
|
|
|
### In-App + Email Notifications
|
|
**Decision: Both email and inbox**
|
|
|
|
#### Features
|
|
- Bell icon with notification count
|
|
- Dropdown showing recent notifications
|
|
- Mark as read/unread
|
|
- Filter by type (billing, support, system, services)
|
|
- Notification preferences (which ones to receive)
|
|
|
|
#### Database Schema
|
|
```sql
|
|
notifications table (Laravel built-in):
|
|
├── id
|
|
├── type (class name of notification)
|
|
├── notifiable_type (User)
|
|
├── notifiable_id (user ID)
|
|
├── data (JSON - notification content)
|
|
├── read_at (nullable)
|
|
├── created_at, updated_at
|
|
|
|
notification_preferences table:
|
|
├── id
|
|
├── user_id
|
|
├── notification_type
|
|
├── email_enabled (boolean)
|
|
├── in_app_enabled (boolean)
|
|
├── discord_enabled (boolean - if customer has Discord connected)
|
|
├── created_at, updated_at
|
|
```
|
|
|
|
#### Vue Component
|
|
```vue
|
|
<!-- resources/js/Components/NotificationCenter.vue -->
|
|
<template>
|
|
<div class="notification-center">
|
|
<button @click="toggleDropdown" class="notification-bell">
|
|
<Icon name="bell" />
|
|
<span v-if="unreadCount > 0" class="badge">{{ unreadCount }}</span>
|
|
</button>
|
|
|
|
<div v-if="showDropdown" class="notification-dropdown">
|
|
<div class="header">
|
|
<h3>Notifications</h3>
|
|
<button @click="markAllRead">Mark all read</button>
|
|
</div>
|
|
|
|
<div class="notifications-list">
|
|
<div v-for="notification in notifications" :key="notification.id"
|
|
:class="{ 'unread': !notification.read_at }"
|
|
@click="markRead(notification)">
|
|
<Icon :name="getIcon(notification.type)" />
|
|
<div class="content">
|
|
<p class="title">{{ notification.data.title }}</p>
|
|
<p class="message">{{ notification.data.message }}</p>
|
|
<span class="time">{{ formatTime(notification.created_at) }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<router-link to="/notifications" class="view-all">View all</router-link>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
```
|
|
|
|
---
|
|
|
|
## 6. NPS Surveys & Customer Feedback
|
|
|
|
### Net Promoter Score System
|
|
**Decision: NPS surveys instead of reviews**
|
|
|
|
#### Features
|
|
- Quarterly NPS surveys via email
|
|
- "How likely are you to recommend EZSCALE? (0-10)"
|
|
- Follow-up question based on score:
|
|
- Promoters (9-10): "What do you love most?"
|
|
- Passives (7-8): "What could we improve?"
|
|
- Detractors (0-6): "What disappointed you?"
|
|
- Track NPS score over time
|
|
- Segment NPS by service type, plan tier
|
|
|
|
#### Database Schema
|
|
```sql
|
|
nps_surveys table:
|
|
├── id
|
|
├── user_id
|
|
├── score (0-10)
|
|
├── category (promoter, passive, detractor)
|
|
├── feedback (text response)
|
|
├── service_type (vps, dedicated, hosting, game, kasm)
|
|
├── sent_at
|
|
├── responded_at
|
|
├── created_at
|
|
|
|
nps_scores table (aggregated):
|
|
├── id
|
|
├── period (2026-Q1, 2026-Q2)
|
|
├── total_responses
|
|
├── promoters_count
|
|
├── passives_count
|
|
├── detractors_count
|
|
├── nps_score (calculated: % promoters - % detractors)
|
|
├── created_at
|
|
```
|
|
|
|
---
|
|
|
|
## 7. Bulk Email Campaigns
|
|
|
|
### Marketing Automation & Segmentation
|
|
**Decision: Full email campaign system**
|
|
|
|
#### Features
|
|
- Create email campaigns with rich editor
|
|
- Segment recipients:
|
|
- By service type
|
|
- By plan tier
|
|
- By tenure (new, loyal, at-risk)
|
|
- By usage patterns
|
|
- Custom tags
|
|
- Schedule send times
|
|
- A/B test subject lines
|
|
- Track opens, clicks, conversions
|
|
- Unsubscribe management
|
|
|
|
#### Database Schema
|
|
```sql
|
|
email_campaigns table:
|
|
├── id
|
|
├── name
|
|
├── subject_line
|
|
├── from_name
|
|
├── from_email
|
|
├── email_content (HTML)
|
|
├── segment_filter (JSON - filtering criteria)
|
|
├── status (draft, scheduled, sending, sent)
|
|
├── scheduled_at
|
|
├── sent_at
|
|
├── total_recipients
|
|
├── created_by_admin_id
|
|
├── created_at, updated_at
|
|
|
|
campaign_recipients table:
|
|
├── id
|
|
├── campaign_id
|
|
├── user_id
|
|
├── sent_at
|
|
├── opened_at
|
|
├── clicked_at
|
|
├── converted_at (if led to action)
|
|
├── unsubscribed_at
|
|
|
|
email_unsubscribes table:
|
|
├── id
|
|
├── user_id
|
|
├── category (marketing, product_updates, newsletters)
|
|
├── unsubscribed_at
|
|
```
|
|
|
|
---
|
|
|
|
## 8. Infrastructure Capacity Planning
|
|
|
|
### Hypervisor Resource Dashboard
|
|
**Decision: Full capacity view for admins**
|
|
|
|
#### Features
|
|
- Real-time resource utilization per hypervisor
|
|
- CPU, RAM, disk, network usage
|
|
- Services per hypervisor
|
|
- Capacity predictions ("NYC1 will be full in 30 days")
|
|
- Alert when capacity hits 80%
|
|
- Automated rebalancing suggestions
|
|
|
|
#### Database Schema
|
|
```sql
|
|
hypervisors table:
|
|
├── id
|
|
├── name (NYC1-HV01, LAX1-HV02)
|
|
├── datacenter_id
|
|
├── ip_address
|
|
├── total_vcpu
|
|
├── total_ram_mb
|
|
├── total_disk_gb
|
|
├── status (online, maintenance, offline)
|
|
├── created_at, updated_at
|
|
|
|
hypervisor_stats table:
|
|
├── id
|
|
├── hypervisor_id
|
|
├── used_vcpu
|
|
├── used_ram_mb
|
|
├── used_disk_gb
|
|
├── services_count
|
|
├── cpu_percent
|
|
├── ram_percent
|
|
├── disk_percent
|
|
├── network_mbps
|
|
├── recorded_at
|
|
|
|
capacity_alerts table:
|
|
├── id
|
|
├── hypervisor_id
|
|
├── alert_type (cpu_high, ram_high, disk_high, approaching_full)
|
|
├── threshold_percent
|
|
├── current_percent
|
|
├── message
|
|
├── acknowledged_at
|
|
├── acknowledged_by_admin_id
|
|
├── created_at
|
|
```
|
|
|
|
---
|
|
|
|
## 9. Audit Log Alerts for High-Risk Actions
|
|
|
|
### Security Monitoring & Admin Alerts
|
|
**Decision: Yes, alert on high-risk actions**
|
|
|
|
#### High-Risk Actions
|
|
- Service bulk termination (>5 services at once)
|
|
- Customer account deletion
|
|
- Pricing changes affecting >100 customers
|
|
- Database modifications
|
|
- Payment gateway settings changes
|
|
- Admin user creation/deletion
|
|
- Wholesale billing changes (for resellers)
|
|
|
|
#### Implementation
|
|
```php
|
|
// app/Services/Audit/HighRiskActionDetector.php
|
|
|
|
class HighRiskActionDetector
|
|
{
|
|
protected $highRiskActions = [
|
|
'service.bulk_terminate',
|
|
'user.delete',
|
|
'plan.price_update',
|
|
'admin.created',
|
|
'payment_gateway.settings_updated',
|
|
];
|
|
|
|
public function logAction(string $action, User $admin, array $changes)
|
|
{
|
|
$log = AuditLog::create([
|
|
'user_id' => $admin->id,
|
|
'action' => $action,
|
|
'changes' => $changes,
|
|
'ip_address' => request()->ip(),
|
|
]);
|
|
|
|
if (in_array($action, $this->highRiskActions)) {
|
|
$this->alertOwner($log);
|
|
|
|
if ($this->requiresDualApproval($action)) {
|
|
$this->requestSecondApproval($log);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function requestSecondApproval(AuditLog $log)
|
|
{
|
|
PendingApproval::create([
|
|
'audit_log_id' => $log->id,
|
|
'action' => $log->action,
|
|
'requested_by_admin_id' => $log->user_id,
|
|
'status' => 'pending',
|
|
]);
|
|
|
|
// Notify other admins
|
|
$otherAdmins = User::where('role', 'admin')
|
|
->where('id', '!=', $log->user_id)
|
|
->get();
|
|
|
|
foreach ($otherAdmins as $admin) {
|
|
Mail::to($admin)->send(new ApprovalRequested($log));
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
```sql
|
|
pending_approvals table:
|
|
├── id
|
|
├── audit_log_id
|
|
├── action
|
|
├── requested_by_admin_id
|
|
├── approved_by_admin_id (nullable)
|
|
├── status (pending, approved, rejected)
|
|
├── approved_at
|
|
├── rejection_reason (if rejected)
|
|
├── created_at, updated_at
|
|
```
|
|
|
|
---
|
|
|
|
## 10. Auto Top-Up for Account Credits
|
|
|
|
### Automatic Credit Replenishment
|
|
**Decision: Yes, configurable auto top-up**
|
|
|
|
#### Features
|
|
- Set low balance threshold ($10, $25, $50)
|
|
- Set top-up amount ($50, $100, $200)
|
|
- Charge customer's default payment method
|
|
- Email confirmation after top-up
|
|
- Daily check for low balances
|
|
|
|
#### Database Schema
|
|
```sql
|
|
auto_topup_settings table:
|
|
├── id
|
|
├── user_id
|
|
├── enabled (boolean)
|
|
├── threshold_amount (decimal - trigger when balance drops below)
|
|
├── topup_amount (decimal - how much to add)
|
|
├── payment_method_id (which card/PayPal to charge)
|
|
├── last_topup_at
|
|
├── created_at, updated_at
|
|
|
|
auto_topup_transactions table:
|
|
├── id
|
|
├── user_id
|
|
├── amount
|
|
├── payment_method_id
|
|
├── status (success, failed)
|
|
├── error_message (if failed)
|
|
├── created_at
|
|
```
|
|
|
|
---
|
|
|
|
## 11. Tiered Annual Subscription Discounts
|
|
|
|
### Multi-Tier Billing Periods
|
|
**Decision: Quarterly = 5%, Annual = 15%, Biennial = 20%**
|
|
|
|
#### Implementation in Plans Table
|
|
```sql
|
|
plans table additions:
|
|
├── price_monthly
|
|
├── price_quarterly (monthly * 3 * 0.95)
|
|
├── price_annual (monthly * 12 * 0.85)
|
|
├── price_biennial (monthly * 24 * 0.80)
|
|
```
|
|
|
|
#### Display in Pricing Page
|
|
```vue
|
|
<div class="pricing-toggle">
|
|
<button @click="billingCycle = 'monthly'">Monthly</button>
|
|
<button @click="billingCycle = 'quarterly'">
|
|
Quarterly <span class="badge">Save 5%</span>
|
|
</button>
|
|
<button @click="billingCycle = 'annual'">
|
|
Annual <span class="badge">Save 15%</span>
|
|
</button>
|
|
<button @click="billingCycle = 'biennial'">
|
|
2 Years <span class="badge">Save 20%</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="plan-price">
|
|
<span class="amount">${{ getPriceForCycle(plan, billingCycle) }}</span>
|
|
<span class="period">/ {{ getCyclePeriod(billingCycle) }}</span>
|
|
<span v-if="billingCycle !== 'monthly'" class="savings">
|
|
Save ${{ calculateSavings(plan, billingCycle) }}
|
|
</span>
|
|
</div>
|
|
```
|
|
|
|
---
|
|
|
|
## 12. SOC 2 Compliance Features
|
|
|
|
### Security & Compliance Infrastructure
|
|
**Decision: Full SOC 2 readiness**
|
|
|
|
#### Features Required for SOC 2
|
|
- Comprehensive audit logging (done)
|
|
- Access control matrices
|
|
- Data encryption at rest and in transit
|
|
- Incident response procedures
|
|
- Vendor management documentation
|
|
- Policy management system
|
|
- Employee security training tracking
|
|
- Penetration testing schedules
|
|
- Disaster recovery testing logs
|
|
|
|
#### Additional Tables
|
|
```sql
|
|
security_policies table:
|
|
├── id
|
|
├── policy_name
|
|
├── policy_document_url (PDF stored in S3)
|
|
├── version
|
|
├── effective_date
|
|
├── next_review_date
|
|
├── owner_admin_id
|
|
├── approved_at
|
|
├── approved_by_admin_id
|
|
├── created_at, updated_at
|
|
|
|
compliance_evidence table:
|
|
├── id
|
|
├── evidence_type (audit_log, policy, training, penetration_test)
|
|
├── description
|
|
├── file_url (stored evidence)
|
|
├── collected_at
|
|
├── reviewer_admin_id
|
|
├── reviewed_at
|
|
├── created_at
|
|
|
|
vendor_assessments table:
|
|
├── id
|
|
├── vendor_name (VirtFusion, Pterodactyl, Stripe, etc.)
|
|
├── service_provided
|
|
├── risk_level (low, medium, high)
|
|
├── contract_url
|
|
├── last_assessment_date
|
|
├── next_assessment_date
|
|
├── soc2_certified (boolean)
|
|
├── created_at, updated_at
|
|
```
|
|
|
|
---
|
|
|
|
## 13. Discord Community Integration
|
|
|
|
### Automated Discord Server Management
|
|
**Decision: Discord integration for community**
|
|
|
|
#### Features
|
|
- Automatic Discord invite upon signup
|
|
- Role assignment based on service tier:
|
|
- VPS Customer → VPS role
|
|
- Game Server Customer → Gaming role
|
|
- Premium tier → VIP role
|
|
- Sync Discord username to customer profile
|
|
- Discord-exclusive announcements
|
|
- Support channel integration with SupportPal
|
|
|
|
#### Implementation
|
|
```php
|
|
// app/Services/Discord/DiscordIntegrationService.php
|
|
|
|
class DiscordIntegrationService
|
|
{
|
|
public function inviteCustomer(User $user): string
|
|
{
|
|
// Create temporary Discord invite
|
|
$response = Http::withToken(config('services.discord.bot_token'))
|
|
->post("https://discord.com/api/channels/{$channelId}/invites", [
|
|
'max_age' => 86400, // 24 hours
|
|
'max_uses' => 1,
|
|
'unique' => true,
|
|
]);
|
|
|
|
return $response['url'];
|
|
}
|
|
|
|
public function assignRoles(User $user)
|
|
{
|
|
$roles = [];
|
|
|
|
// Assign roles based on services
|
|
if ($user->hasVpsService()) {
|
|
$roles[] = config('services.discord.roles.vps');
|
|
}
|
|
|
|
if ($user->hasGameServerService()) {
|
|
$roles[] = config('services.discord.roles.gaming');
|
|
}
|
|
|
|
// Add roles via Discord API
|
|
foreach ($roles as $roleId) {
|
|
Http::withToken(config('services.discord.bot_token'))
|
|
->put("https://discord.com/api/guilds/{$guildId}/members/{$user->discord_id}/roles/{$roleId}");
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 14. Free Tier for Developers
|
|
|
|
### Developer Testing Environment
|
|
**Decision: One free micro VPS per account**
|
|
|
|
#### Features
|
|
- 1 vCPU, 512MB RAM, 10GB disk, 500GB bandwidth
|
|
- Limited to one per account
|
|
- Must verify email and 2FA to unlock
|
|
- Watermarked as "Development" in dashboard
|
|
- Auto-terminate after 90 days of inactivity
|
|
- Cannot upgrade to paid (must create new service)
|
|
|
|
#### Database Schema
|
|
```sql
|
|
plans table addition:
|
|
├── is_free_tier (boolean)
|
|
├── free_tier_limit_per_account (integer)
|
|
├── free_tier_max_duration_days (90)
|
|
├── free_tier_requirements (JSON - email_verified, 2fa_enabled)
|
|
|
|
services table addition:
|
|
├── is_free_tier (boolean)
|
|
├── free_tier_expires_at (created_at + 90 days)
|
|
├── last_activity_at (updated when customer accesses)
|
|
```
|
|
|
|
---
|
|
|
|
## 15. Service Transfer Between Accounts
|
|
|
|
### Admin-Assisted Service Transfer
|
|
**Decision: Admin-assisted transfers**
|
|
|
|
#### Process
|
|
1. Customer requests transfer via ticket
|
|
2. Provides recipient's email/account ID
|
|
3. Admin verifies both parties
|
|
4. Admin transfers service ownership
|
|
5. Prorated billing adjustments
|
|
6. Email confirmations to both parties
|
|
|
|
#### Database Schema
|
|
```sql
|
|
service_transfers table:
|
|
├── id
|
|
├── service_id
|
|
├── from_user_id
|
|
├── to_user_id
|
|
├── requested_at
|
|
├── approved_by_admin_id
|
|
├── completed_at
|
|
├── reason
|
|
├── notes
|
|
├── status (requested, approved, completed, cancelled)
|
|
├── created_at, updated_at
|
|
```
|
|
|
|
---
|
|
|
|
## 16. Configurable Auto-Recovery
|
|
|
|
### Service Health Monitoring & Auto-Restart
|
|
**Decision: Customer configurable**
|
|
|
|
#### Features
|
|
- Monitor service health every 5 minutes (ping, HTTP check)
|
|
- If down, attempt auto-restart
|
|
- Max 3 auto-restart attempts per hour
|
|
- After 3 failures, alert customer and stop auto-restart
|
|
- Customer can enable/disable per service
|
|
- Customer can set custom health check URL
|
|
|
|
#### Database Schema
|
|
```sql
|
|
auto_recovery_settings table:
|
|
├── id
|
|
├── service_id
|
|
├── enabled (boolean)
|
|
├── check_type (ping, http, tcp)
|
|
├── check_url (for http checks)
|
|
├── check_port (for tcp checks)
|
|
├── max_retries_per_hour (default 3)
|
|
├── notify_on_failure (boolean)
|
|
├── created_at, updated_at
|
|
|
|
auto_recovery_attempts table:
|
|
├── id
|
|
├── service_id
|
|
├── check_failed_at
|
|
├── recovery_attempted_at
|
|
├── recovery_status (success, failed)
|
|
├── error_message
|
|
├── created_at
|
|
```
|
|
|
|
---
|
|
|
|
## 17. Projects & Service Grouping
|
|
|
|
### Organize Services into Projects
|
|
**Decision: Yes, full project feature**
|
|
|
|
#### Features
|
|
- Create projects (e.g., "Production", "Staging", "Client ABC")
|
|
- Assign multiple services to a project
|
|
- Project-level billing summary
|
|
- Project tags and notes
|
|
- Color-coded projects
|
|
- Filter dashboard by project
|
|
|
|
#### Database Schema
|
|
```sql
|
|
projects table:
|
|
├── id
|
|
├── user_id
|
|
├── name
|
|
├── description
|
|
├── color (hex color for UI)
|
|
├── icon (emoji or icon name)
|
|
├── created_at, updated_at
|
|
|
|
project_services table:
|
|
├── id
|
|
├── project_id
|
|
├── service_id
|
|
├── added_at
|
|
```
|
|
|
|
---
|
|
|
|
## 18. Scheduled Service Upgrades
|
|
|
|
### Future-Dated Plan Changes
|
|
**Decision: Yes, full scheduling**
|
|
|
|
#### Features
|
|
- Schedule upgrade for specific date/time
|
|
- Example: "Upgrade to VPS Pro on Dec 25 at midnight"
|
|
- Useful for planned traffic spikes (product launches, events)
|
|
- Customer can cancel scheduled change before it executes
|
|
- Email reminder 24 hours before scheduled change
|
|
|
|
#### Database Schema
|
|
```sql
|
|
scheduled_changes table:
|
|
├── id
|
|
├── service_id
|
|
├── change_type (upgrade, downgrade, addon)
|
|
├── from_plan_id
|
|
├── to_plan_id
|
|
├── scheduled_for (datetime)
|
|
├── status (pending, executed, cancelled)
|
|
├── executed_at
|
|
├── cancelled_at
|
|
├── cancellation_reason
|
|
├── created_at, updated_at
|
|
```
|
|
|
|
---
|
|
|
|
## 19. AI Cost Optimization Recommendations
|
|
|
|
### Machine Learning-Powered Suggestions
|
|
**Decision: Yes, AI recommendations**
|
|
|
|
#### Features
|
|
- Analyze resource usage patterns over 30 days
|
|
- Detect underutilized services: "VPS using 15% CPU avg, downgrade to save $8/month"
|
|
- Detect overutilized services: "Bandwidth at 95%, upgrade to prevent overages"
|
|
- Consolidation suggestions: "3 low-usage VPS could be combined into 1"
|
|
- Idle service detection: "Game server hasn't been accessed in 45 days"
|
|
|
|
#### Implementation
|
|
```php
|
|
// app/Services/AI/CostOptimizationService.php
|
|
|
|
class CostOptimizationService
|
|
{
|
|
public function analyzeService(Service $service): array
|
|
{
|
|
$recommendations = [];
|
|
|
|
// Check CPU usage
|
|
$avgCpu = $this->getAverageCpuUsage($service, 30);
|
|
if ($avgCpu < 20) {
|
|
$lowerPlan = $this->findLowerTierPlan($service->plan);
|
|
if ($lowerPlan) {
|
|
$savings = $service->plan->price - $lowerPlan->price;
|
|
$recommendations[] = [
|
|
'type' => 'downgrade',
|
|
'reason' => "Average CPU usage is only {$avgCpu}%",
|
|
'suggestion' => "Downgrade to {$lowerPlan->name}",
|
|
'monthly_savings' => $savings,
|
|
'confidence' => 'high',
|
|
];
|
|
}
|
|
}
|
|
|
|
// Check bandwidth approaching limit
|
|
$bandwidthPercent = $this->getBandwidthUsagePercent($service);
|
|
if ($bandwidthPercent > 80) {
|
|
$recommendations[] = [
|
|
'type' => 'upgrade',
|
|
'reason' => "Using {$bandwidthPercent}% of bandwidth quota",
|
|
'suggestion' => "Upgrade to avoid overage charges",
|
|
'potential_cost' => $this->estimateOverageCharges($service),
|
|
'confidence' => 'high',
|
|
];
|
|
}
|
|
|
|
// Check idle services
|
|
if ($service->last_accessed_at < now()->subDays(30)) {
|
|
$recommendations[] = [
|
|
'type' => 'terminate',
|
|
'reason' => "Service not accessed in 30+ days",
|
|
'suggestion' => "Consider terminating to save costs",
|
|
'monthly_savings' => $service->plan->price,
|
|
'confidence' => 'medium',
|
|
];
|
|
}
|
|
|
|
return $recommendations;
|
|
}
|
|
}
|
|
```
|
|
|
|
```sql
|
|
optimization_recommendations table:
|
|
├── id
|
|
├── service_id
|
|
├── recommendation_type (upgrade, downgrade, terminate, consolidate)
|
|
├── reason
|
|
├── suggestion
|
|
├── potential_savings
|
|
├── confidence_level (high, medium, low)
|
|
├── shown_at
|
|
├── acted_on_at (nullable)
|
|
├── dismissed_at (nullable)
|
|
├── created_at
|
|
```
|
|
|
|
---
|
|
|
|
## 20. Service Dependency Mapping
|
|
|
|
### Visual Dependency Graph
|
|
**Decision: Yes, full dependency graph**
|
|
|
|
#### Features
|
|
- Map dependencies between services
|
|
- Example: "Web Server depends on Database Server"
|
|
- Visual graph showing all relationships
|
|
- Warn before terminating service with dependents
|
|
- Cascade notifications (if Service A goes down, alert owners of dependent Service B)
|
|
|
|
#### Database Schema
|
|
```sql
|
|
service_dependencies table:
|
|
├── id
|
|
├── service_id (the dependent service)
|
|
├── depends_on_service_id (the dependency)
|
|
├── dependency_type (database, loadbalancer, storage, other)
|
|
├── critical (boolean - critical dependency vs nice-to-have)
|
|
├── notes
|
|
├── created_at, updated_at
|
|
```
|
|
|
|
#### Vue Component
|
|
```vue
|
|
<!-- Service dependency graph using D3.js or vis.js -->
|
|
<template>
|
|
<div class="dependency-graph">
|
|
<svg ref="graph" width="800" height="600"></svg>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
mounted() {
|
|
this.renderGraph()
|
|
},
|
|
methods: {
|
|
renderGraph() {
|
|
// Use D3.js force-directed graph
|
|
// Nodes = services
|
|
// Edges = dependencies
|
|
// Color code by status (green=healthy, red=down)
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
```
|
|
|
|
---
|
|
|
|
## 21. Budget Controls & Hard Limits
|
|
|
|
### Spending Caps & Auto-Suspension
|
|
**Decision: Yes, hard limits**
|
|
|
|
#### Features
|
|
- Set monthly budget cap ($100, $500, $1000)
|
|
- Soft alert at 50%, 75%, 90%
|
|
- Hard stop at 100% - suspend all services
|
|
- Budget resets monthly on billing cycle date
|
|
- Exclude/include specific services from budget
|
|
- Emergency override (customer can unlock with payment)
|
|
|
|
#### Database Schema
|
|
```sql
|
|
budget_settings table:
|
|
├── id
|
|
├── user_id
|
|
├── monthly_limit
|
|
├── current_month_spend (reset monthly)
|
|
├── alert_thresholds (JSON - [50, 75, 90])
|
|
├── auto_suspend_enabled (boolean)
|
|
├── excluded_service_ids (JSON array)
|
|
├── last_reset_at
|
|
├── created_at, updated_at
|
|
|
|
budget_alerts table:
|
|
├── id
|
|
├── user_id
|
|
├── threshold_percent
|
|
├── current_spend
|
|
├── alerted_at
|
|
├── created_at
|
|
```
|
|
|
|
---
|
|
|
|
## 22. Terraform Provider for IaC
|
|
|
|
### Infrastructure as Code Support
|
|
**Decision: Yes, official Terraform provider**
|
|
|
|
#### Features
|
|
- Terraform provider: `terraform-provider-ezscale`
|
|
- Manage all resources via Terraform
|
|
- Import existing resources
|
|
- State management
|
|
- Documentation + examples
|
|
|
|
#### Example Terraform Config
|
|
```hcl
|
|
# Configure the EZSCALE provider
|
|
provider "ezscale" {
|
|
api_token = var.ezscale_api_token
|
|
}
|
|
|
|
# Create a VPS
|
|
resource "ezscale_vps" "web_server" {
|
|
name = "production-web"
|
|
plan = "vps-pro"
|
|
datacenter = "nyc1"
|
|
os_template = "ubuntu-22.04"
|
|
|
|
ssh_keys = [ezscale_ssh_key.admin.id]
|
|
|
|
tags = ["production", "web"]
|
|
}
|
|
|
|
# Create Kasm Workspace
|
|
resource "ezscale_kasm_workspace" "dev_env" {
|
|
workspace_type = "developer_pro"
|
|
template = "ubuntu-vscode"
|
|
project = "staging"
|
|
}
|
|
|
|
# Output access details
|
|
output "vps_ip" {
|
|
value = ezscale_vps.web_server.ipv4_address
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 23. Dynamic Promotional Landing Pages
|
|
|
|
### Marketing Campaign Pages
|
|
**Decision: Yes, dynamic promo pages**
|
|
|
|
#### Features
|
|
- Create custom landing pages for campaigns
|
|
- Special pricing visible only on that page
|
|
- UTM tracking for conversions
|
|
- A/B test different offers
|
|
- Limited-time countdown timers
|
|
- Unique coupon codes auto-applied
|
|
|
|
#### Database Schema
|
|
```sql
|
|
promo_landing_pages table:
|
|
├── id
|
|
├── slug (black-friday-2026, partner-discount)
|
|
├── title
|
|
├── hero_image_url
|
|
├── pricing_override (JSON - custom pricing)
|
|
├── coupon_code (auto-applied)
|
|
├── starts_at
|
|
├── expires_at
|
|
├── max_conversions (nullable - limit signups)
|
|
├── current_conversions
|
|
├── status (draft, active, expired)
|
|
├── created_at, updated_at
|
|
|
|
promo_page_visits table:
|
|
├── id
|
|
├── promo_landing_page_id
|
|
├── visitor_ip
|
|
├── utm_source
|
|
├── utm_medium
|
|
├── utm_campaign
|
|
├── converted (boolean)
|
|
├── converted_user_id (nullable)
|
|
├── visited_at
|
|
```
|
|
|
|
---
|
|
|
|
## 24. AI-Powered Support Assistant
|
|
|
|
### First-Line Support Automation
|
|
**Decision: Yes, AI assistant before human**
|
|
|
|
#### Features
|
|
- ChatGPT/Claude-powered chatbot
|
|
- Trained on EZSCALE knowledge base
|
|
- Answers common questions (billing, technical, how-to)
|
|
- Escalates complex issues to SupportPal ticket
|
|
- Tracks resolution rate (% solved by AI vs escalated)
|
|
|
|
#### Implementation
|
|
```php
|
|
// app/Services/Support/AiSupportAssistant.php
|
|
|
|
class AiSupportAssistant
|
|
{
|
|
public function chat(string $message, User $user): array
|
|
{
|
|
// Build context
|
|
$context = $this->buildUserContext($user);
|
|
|
|
// Call Claude API
|
|
$response = Http::withToken(config('services.anthropic.api_key'))
|
|
->post('https://api.anthropic.com/v1/messages', [
|
|
'model' => 'claude-3-5-sonnet-20241022',
|
|
'max_tokens' => 1024,
|
|
'system' => $this->getSystemPrompt(),
|
|
'messages' => [
|
|
[
|
|
'role' => 'user',
|
|
'content' => "Customer context:\n{$context}\n\nQuestion: {$message}",
|
|
],
|
|
],
|
|
]);
|
|
|
|
$answer = $response['content'][0]['text'];
|
|
|
|
// Check if should escalate
|
|
if ($this->shouldEscalate($answer)) {
|
|
return [
|
|
'type' => 'escalate',
|
|
'message' => 'Let me create a support ticket for you...',
|
|
'ticket_id' => $this->createTicket($user, $message),
|
|
];
|
|
}
|
|
|
|
return [
|
|
'type' => 'answer',
|
|
'message' => $answer,
|
|
];
|
|
}
|
|
|
|
protected function buildUserContext(User $user): string
|
|
{
|
|
return "
|
|
Customer: {$user->name} ({$user->email})
|
|
Services: " . $user->services->pluck('service_type')->join(', ') . "
|
|
Account balance: ${$user->account_credits}
|
|
Overdue invoices: {$user->overdue_invoices_count}
|
|
";
|
|
}
|
|
|
|
protected function getSystemPrompt(): string
|
|
{
|
|
return "You are a helpful support assistant for EZSCALE Hosting.
|
|
You help customers with billing questions, technical issues, and how-to guides.
|
|
Be friendly, concise, and accurate. If you don't know something, say so and offer to escalate.
|
|
Never make up information about pricing or technical specs.";
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 25. Service Health Scores & Grades
|
|
|
|
### A-F Health Dashboard
|
|
**Decision: Yes, health grades**
|
|
|
|
#### Factors in Health Score
|
|
- Uptime percentage (weight: 40%)
|
|
- Performance metrics - avg response time (weight: 20%)
|
|
- Resource utilization - not maxed out (weight: 15%)
|
|
- Backup compliance - recent backups (weight: 10%)
|
|
- Security - patches up-to-date (weight: 10%)
|
|
- Incident count (weight: 5%)
|
|
|
|
#### Grading Scale
|
|
- A (90-100%): Excellent
|
|
- B (80-89%): Good
|
|
- C (70-79%): Fair
|
|
- D (60-69%): Poor
|
|
- F (<60%): Critical
|
|
|
|
#### Database Schema
|
|
```sql
|
|
service_health_scores table:
|
|
├── id
|
|
├── service_id
|
|
├── uptime_score (0-100)
|
|
├── performance_score (0-100)
|
|
├── utilization_score (0-100)
|
|
├── backup_score (0-100)
|
|
├── security_score (0-100)
|
|
├── incident_score (0-100)
|
|
├── overall_score (weighted average)
|
|
├── grade (A, B, C, D, F)
|
|
├── calculated_at
|
|
├── created_at
|
|
```
|
|
|
|
---
|
|
|
|
## 26. Competitive Analysis Automation
|
|
|
|
### Competitor Price Tracking
|
|
**Decision: Yes, auto-tracking**
|
|
|
|
#### Features
|
|
- Scrape competitor pricing weekly (Vultr, DigitalOcean, Linode, OVH)
|
|
- Compare similar plan specs
|
|
- Alert if competitors significantly undercut prices
|
|
- Display comparison charts in admin panel
|
|
- Track pricing history over time
|
|
|
|
#### Implementation
|
|
```php
|
|
// app/Console/Commands/ScrapeCompetitorPricing.php
|
|
|
|
class ScrapeCompetitorPricing extends Command
|
|
{
|
|
public function handle()
|
|
{
|
|
$competitors = [
|
|
'vultr' => 'https://www.vultr.com/pricing/',
|
|
'digitalocean' => 'https://www.digitalocean.com/pricing',
|
|
'linode' => 'https://www.linode.com/pricing/',
|
|
];
|
|
|
|
foreach ($competitors as $name => $url) {
|
|
$scraper = app("App\\Services\\Scrapers\\{$name}Scraper");
|
|
$pricing = $scraper->scrape($url);
|
|
|
|
foreach ($pricing as $plan) {
|
|
CompetitorPricing::create([
|
|
'competitor' => $name,
|
|
'plan_name' => $plan['name'],
|
|
'vcpu' => $plan['vcpu'],
|
|
'ram_gb' => $plan['ram'],
|
|
'disk_gb' => $plan['disk'],
|
|
'bandwidth_tb' => $plan['bandwidth'],
|
|
'price_monthly' => $plan['price'],
|
|
'scraped_at' => now(),
|
|
]);
|
|
}
|
|
}
|
|
|
|
$this->analyzeCompetitiveness();
|
|
}
|
|
|
|
protected function analyzeCompetitiveness()
|
|
{
|
|
$ourPlans = Plan::where('service_type', 'vps')->get();
|
|
|
|
foreach ($ourPlans as $plan) {
|
|
$similarCompetitorPlans = CompetitorPricing::where('vcpu', $plan->vcpu)
|
|
->where('ram_gb', '>=', $plan->ram_gb * 0.9)
|
|
->where('ram_gb', '<=', $plan->ram_gb * 1.1)
|
|
->latest('scraped_at')
|
|
->get();
|
|
|
|
$avgCompetitorPrice = $similarCompetitorPlans->avg('price_monthly');
|
|
|
|
if ($plan->price > $avgCompetitorPrice * 1.2) {
|
|
// We're 20% more expensive - alert
|
|
app(DiscordNotificationService::class)->sendAlert([
|
|
'title' => 'Pricing Alert',
|
|
'message' => "{$plan->name} is 20% above market average",
|
|
'our_price' => $plan->price,
|
|
'market_avg' => $avgCompetitorPrice,
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
```sql
|
|
competitor_pricing table:
|
|
├── id
|
|
├── competitor (vultr, digitalocean, linode)
|
|
├── plan_name
|
|
├── vcpu
|
|
├── ram_gb
|
|
├── disk_gb
|
|
├── bandwidth_tb
|
|
├── price_monthly
|
|
├── scraped_at
|
|
├── created_at
|
|
```
|
|
|
|
---
|
|
|
|
## 27. Advanced Win-Back Campaigns
|
|
|
|
### Smart Churn Prevention
|
|
**Decision: Yes, intelligent automation**
|
|
|
|
#### Features
|
|
- Segment by cancellation reason
|
|
- Different campaigns per segment:
|
|
- "Too expensive" → Offer 25% discount for 3 months
|
|
- "Switching to competitor" → Match competitor offer
|
|
- "Technical issues" → Offer migration assistance + credit
|
|
- "No longer need service" → Stay-in-touch newsletter
|
|
- Track campaign effectiveness
|
|
- A/B test email copy
|
|
|
|
#### Database Schema
|
|
```sql
|
|
winback_campaigns table:
|
|
├── id
|
|
├── name
|
|
├── cancellation_reason (matches exit survey reasons)
|
|
├── email_sequence (JSON - series of emails with delays)
|
|
├── offer_type (discount, credit, free_upgrade)
|
|
├── offer_value
|
|
├── status (active, paused, completed)
|
|
├── created_at, updated_at
|
|
|
|
winback_campaign_recipients table:
|
|
├── id
|
|
├── campaign_id
|
|
├── user_id
|
|
├── subscription_id (cancelled subscription)
|
|
├── current_email_index
|
|
├── last_email_sent_at
|
|
├── opened_count
|
|
├── clicked_count
|
|
├── reactivated (boolean)
|
|
├── reactivated_at
|
|
├── created_at
|
|
```
|
|
|
|
---
|
|
|
|
## 28. Cohort Analysis Dashboard
|
|
|
|
### Customer Segmentation & Retention Analysis
|
|
**Decision: Yes, full cohort tracking**
|
|
|
|
#### Features
|
|
- Group customers by signup month/quarter
|
|
- Track retention by cohort over time
|
|
- Revenue per cohort
|
|
- Compare acquisition channels (organic, paid, referral)
|
|
- Cohort LTV (Lifetime Value) predictions
|
|
- Churn analysis by cohort
|
|
|
|
#### Visualization Example
|
|
```
|
|
Cohort Retention Table:
|
|
|
|
Cohort Month 0 Month 1 Month 2 Month 3 Month 6 Month 12
|
|
2025-Q4 100% 92% 87% 83% 75% 68%
|
|
2026-Q1 100% 95% 91% 88% 80% --
|
|
2026-Q2 100% 96% 93% -- -- --
|
|
```
|
|
|
|
#### Implementation
|
|
```php
|
|
// app/Services/Analytics/CohortAnalysisService.php
|
|
|
|
class CohortAnalysisService
|
|
{
|
|
public function generateRetentionCohorts(): array
|
|
{
|
|
$cohorts = [];
|
|
|
|
// Get all signup cohorts (monthly)
|
|
$cohortData = User::selectRaw('
|
|
DATE_FORMAT(created_at, "%Y-%m") as cohort,
|
|
COUNT(*) as cohort_size
|
|
')
|
|
->groupBy('cohort')
|
|
->get();
|
|
|
|
foreach ($cohortData as $cohort) {
|
|
$cohortUsers = User::whereRaw('DATE_FORMAT(created_at, "%Y-%m") = ?', [$cohort->cohort])
|
|
->pluck('id');
|
|
|
|
$retention = [];
|
|
|
|
// Calculate retention for each month after signup
|
|
for ($month = 0; $month <= 12; $month++) {
|
|
$activeUsers = Subscription::whereIn('user_id', $cohortUsers)
|
|
->where('status', 'active')
|
|
->whereDate('created_at', '<=', now()->parse($cohort->cohort)->addMonths($month))
|
|
->count();
|
|
|
|
$retention[$month] = round(($activeUsers / $cohort->cohort_size) * 100, 1);
|
|
}
|
|
|
|
$cohorts[$cohort->cohort] = [
|
|
'size' => $cohort->cohort_size,
|
|
'retention' => $retention,
|
|
];
|
|
}
|
|
|
|
return $cohorts;
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Summary
|
|
|
|
These 28 advanced features significantly enhance the platform:
|
|
|
|
**Customer Experience**
|
|
- ✅ Task automation & scheduling
|
|
- ✅ Forecasting with AI recommendations
|
|
- ✅ Project organization
|
|
- ✅ Dependency mapping
|
|
- ✅ Budget controls
|
|
- ✅ Health dashboards
|
|
- ✅ Discord community
|
|
- ✅ AI support assistant
|
|
- ✅ Free dev tier
|
|
- ✅ Scheduled upgrades
|
|
|
|
**Business Intelligence**
|
|
- ✅ Cohort analysis
|
|
- ✅ Competitive tracking
|
|
- ✅ Smart win-back campaigns
|
|
- ✅ NPS surveys
|
|
- ✅ Capacity planning
|
|
|
|
**Operations & Admin**
|
|
- ✅ Bulk email campaigns
|
|
- ✅ Audit alerts & dual approval
|
|
- ✅ SOC 2 compliance
|
|
- ✅ Infrastructure monitoring
|
|
|
|
**Developer Tools**
|
|
- ✅ Terraform provider
|
|
- ✅ Full-control API
|
|
- ✅ Auto-recovery settings
|
|
|
|
**Marketing**
|
|
- ✅ Dynamic promo pages
|
|
- ✅ Tiered discounts
|
|
|
|
This brings the total feature count to **60+ features**, making this one of the most comprehensive hosting platform implementations ever planned!
|