38 KiB
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
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
// 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
// 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/...",
];
}
}
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
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
<!-- 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
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
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
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
// 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));
}
}
}
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
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
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
<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
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
// 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
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
- Customer requests transfer via ticket
- Provides recipient's email/account ID
- Admin verifies both parties
- Admin transfers service ownership
- Prorated billing adjustments
- Email confirmations to both parties
Database Schema
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
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
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
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
// 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;
}
}
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
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
<!-- 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
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
# 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
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
// 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
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
// 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,
]);
}
}
}
}
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
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
// 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!