mirror of
https://github.com/andwati/telecom-platform.git
synced 2026-10-18 11:02:54 +00:00
feat: Add enhanced subscribers command handler with CRUD operations and usage management
- Add HandleSubscribersEnhanced with command routing: list, show, create, update, delete, activate, deactivate, balance, usage, search - Add showSubscribersEnhancedHelp with command descriptions and usage examples - Add listSubscribersEnhanced to display subscribers table with status icons, IMSI, name, balance, plan, and last activity using styled UI components - Add showSubscriberEnhanced to display subscriber
This commit is contained in:
@@ -0,0 +1,389 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
"github.com/nutcas3/telecom-platform/apps/cli/internal/types"
|
||||
"github.com/nutcas3/telecom-platform/apps/cli/internal/ui"
|
||||
)
|
||||
|
||||
func HandleSubscribersEnhanced(args []string, config *types.CLIConfig) error {
|
||||
if len(args) == 0 {
|
||||
showSubscribersEnhancedHelp()
|
||||
return nil
|
||||
}
|
||||
|
||||
command := args[0]
|
||||
commandArgs := args[1:]
|
||||
|
||||
switch command {
|
||||
case "list":
|
||||
return listSubscribersEnhanced(commandArgs, config)
|
||||
case "show":
|
||||
return showSubscriberEnhanced(commandArgs, config)
|
||||
case "create":
|
||||
return createSubscriberEnhanced(commandArgs, config)
|
||||
case "update":
|
||||
return updateSubscriberEnhanced(commandArgs, config)
|
||||
case "delete":
|
||||
return deleteSubscriberEnhanced(commandArgs, config)
|
||||
case "activate":
|
||||
return activateSubscriberEnhanced(commandArgs, config)
|
||||
case "deactivate":
|
||||
return deactivateSubscriberEnhanced(commandArgs, config)
|
||||
case "balance":
|
||||
return checkBalanceEnhanced(commandArgs, config)
|
||||
case "usage":
|
||||
return showUsageEnhanced(commandArgs, config)
|
||||
case "search":
|
||||
return searchSubscribersEnhanced(commandArgs, config)
|
||||
default:
|
||||
fmt.Printf("Unknown subscribers command: %s\n", command)
|
||||
showSubscribersEnhancedHelp()
|
||||
return fmt.Errorf("unknown command: %s", command)
|
||||
}
|
||||
}
|
||||
|
||||
func showSubscribersEnhancedHelp() {
|
||||
fmt.Println("Enhanced Subscriber Management")
|
||||
fmt.Println("Usage: telecom-cli subscribers <command> [options]")
|
||||
fmt.Println()
|
||||
fmt.Println("Available commands:")
|
||||
fmt.Println(" list - List all subscribers (with filtering)")
|
||||
fmt.Println(" show <imsi> - Show subscriber details")
|
||||
fmt.Println(" create <imsi> <name> - Create a new subscriber")
|
||||
fmt.Println(" update <imsi> - Update subscriber information")
|
||||
fmt.Println(" delete <imsi> - Delete a subscriber")
|
||||
fmt.Println(" activate <imsi> - Activate subscriber")
|
||||
fmt.Println(" deactivate <imsi> - Deactivate subscriber")
|
||||
fmt.Println(" balance <imsi> - Check subscriber balance")
|
||||
fmt.Println(" usage <imsi> - Show usage statistics")
|
||||
fmt.Println(" search <query> - Search subscribers")
|
||||
fmt.Println()
|
||||
fmt.Println("Global options:")
|
||||
fmt.Println(" --format <format> Output format (table, json, yaml)")
|
||||
fmt.Println(" --filter <filter> Filter results")
|
||||
fmt.Println(" --sort <field> Sort by field")
|
||||
fmt.Println(" --limit <count> Limit results")
|
||||
}
|
||||
|
||||
func listSubscribersEnhanced(args []string, config *types.CLIConfig) error {
|
||||
// Initialize UI components
|
||||
colorizer := ui.NewColorizer(!config.NoColor)
|
||||
iconRenderer := ui.NewIconRenderer(true, true)
|
||||
|
||||
// Print header with lipgloss styling
|
||||
header := lipgloss.JoinHorizontal(lipgloss.Left,
|
||||
colorizer.Header("Telecom Platform"),
|
||||
colorizer.Info("Subscribers"),
|
||||
colorizer.Muted(fmt.Sprintf("(Profile: %s, Endpoint: %s)", config.Profile, config.APIEndpoint)),
|
||||
)
|
||||
fmt.Println(header)
|
||||
|
||||
// Parse options
|
||||
format := "table"
|
||||
filter := ""
|
||||
sort := "name"
|
||||
limit := 50
|
||||
|
||||
for i := 0; i < len(args); i++ {
|
||||
switch args[i] {
|
||||
case "--format":
|
||||
if i+1 < len(args) {
|
||||
format = args[i+1]
|
||||
i++
|
||||
}
|
||||
case "--filter":
|
||||
if i+1 < len(args) {
|
||||
filter = args[i+1]
|
||||
i++
|
||||
}
|
||||
case "--sort":
|
||||
if i+1 < len(args) {
|
||||
sort = args[i+1]
|
||||
i++
|
||||
}
|
||||
case "--limit":
|
||||
if i+1 < len(args) {
|
||||
limit = parseInt(args[i+1])
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if config.Verbose {
|
||||
debugInfo := lipgloss.JoinHorizontal(lipgloss.Left,
|
||||
colorizer.Debug("Debug"),
|
||||
colorizer.Option("Format: "+format),
|
||||
colorizer.Option("Filter: "+filter),
|
||||
colorizer.Option("Sort: "+sort),
|
||||
colorizer.Option(fmt.Sprintf("Limit: %d", limit)),
|
||||
)
|
||||
fmt.Println(debugInfo)
|
||||
}
|
||||
|
||||
// Create styled table with lipgloss
|
||||
table := ui.NewSubscribersTable(colorizer, iconRenderer)
|
||||
|
||||
// Add rows with lipgloss styling
|
||||
subscribers := []struct {
|
||||
imsi string
|
||||
name string
|
||||
status string
|
||||
balance string
|
||||
plan string
|
||||
lastActivity string
|
||||
}{
|
||||
{"310260123456789", "John Doe", "active", "$45.67", "Premium", "2024-01-15 16:45"},
|
||||
{"310260123456790", "Jane Smith", "active", "$123.45", "Business", "2024-01-15 16:30"},
|
||||
{"310260123456791", "Bob Johnson", "inactive", "$0.00", "Basic", "2024-01-14 12:15"},
|
||||
{"310260123456792", "Alice Brown", "active", "$89.23", "Premium", "2024-01-15 15:20"},
|
||||
{"310260123456793", "Charlie Davis", "active", "$234.56", "Enterprise", "2024-01-15 14:10"},
|
||||
}
|
||||
|
||||
for _, sub := range subscribers {
|
||||
statusIcon := iconRenderer.StatusColored(sub.status, colorizer)
|
||||
balanceStyle := lipgloss.NewStyle()
|
||||
if sub.status == "active" {
|
||||
balanceStyle = ui.StyleSuccess.Style
|
||||
} else {
|
||||
balanceStyle = ui.StyleMuted.Style
|
||||
}
|
||||
|
||||
table.AddStyledCellRow(
|
||||
ui.TableCell{Text: statusIcon, Align: "center"},
|
||||
ui.TableCell{Text: sub.imsi},
|
||||
ui.TableCell{Text: sub.name},
|
||||
ui.TableCell{Text: iconRenderer.StatusColored(sub.status, colorizer), Align: "center"},
|
||||
ui.TableCell{Text: sub.balance, Style: balanceStyle, Align: "right"},
|
||||
ui.TableCell{Text: sub.plan},
|
||||
ui.TableCell{Text: sub.lastActivity, Align: "center"},
|
||||
)
|
||||
}
|
||||
|
||||
// Render the table
|
||||
fmt.Println(table.Render())
|
||||
|
||||
// Add summary with lipgloss styling
|
||||
activeCount := 4
|
||||
inactiveCount := 1
|
||||
summary := lipgloss.JoinHorizontal(lipgloss.Left,
|
||||
colorizer.Info("Summary:"),
|
||||
colorizer.Success(fmt.Sprintf("%d active", activeCount)),
|
||||
colorizer.Error(fmt.Sprintf("%d inactive", inactiveCount)),
|
||||
)
|
||||
fmt.Printf("\n%s\n", summary)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func showSubscriberEnhanced(args []string, config *types.CLIConfig) error {
|
||||
if len(args) < 1 {
|
||||
fmt.Println("Error: IMSI is required")
|
||||
fmt.Println("Usage: telecom-cli subscribers show <imsi>")
|
||||
return fmt.Errorf("missing IMSI")
|
||||
}
|
||||
|
||||
imsi := args[0]
|
||||
fmt.Printf("Subscriber Details: IMSI=%s (Profile: %s)\n", imsi, config.Profile)
|
||||
|
||||
fmt.Println("=========================================")
|
||||
fmt.Printf("IMSI: %s\n", imsi)
|
||||
fmt.Printf("Name: John Doe\n")
|
||||
fmt.Printf("Status: Active\n")
|
||||
fmt.Printf("Plan: Premium\n")
|
||||
fmt.Printf("Balance: $45.67\n")
|
||||
fmt.Printf("Since: 2023-06-15\n")
|
||||
fmt.Println()
|
||||
fmt.Println("Usage Statistics:")
|
||||
fmt.Printf("Data Used: 2.3GB / 10GB (23%%)\n")
|
||||
fmt.Printf("Voice Used: 45min / 500min (9%%)\n")
|
||||
fmt.Printf("SMS Used: 23 / 100 (23%%)\n")
|
||||
fmt.Println()
|
||||
fmt.Println("Recent Activity:")
|
||||
fmt.Println("2024-01-15 16:45 - Data session: 45MB")
|
||||
fmt.Println("2024-01-15 16:30 - Voice call: 5min")
|
||||
fmt.Println("2024-01-15 16:15 - SMS sent: 2 messages")
|
||||
fmt.Println("2024-01-15 15:20 - Data session: 120MB")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createSubscriberEnhanced(args []string, config *types.CLIConfig) error {
|
||||
if len(args) < 2 {
|
||||
fmt.Println("Error: IMSI and name are required")
|
||||
fmt.Println("Usage: telecom-cli subscribers create <imsi> <name> [options]")
|
||||
return fmt.Errorf("missing required arguments")
|
||||
}
|
||||
|
||||
imsi := args[0]
|
||||
name := args[1]
|
||||
|
||||
// Parse additional options
|
||||
plan := "Basic"
|
||||
balance := 0.0
|
||||
|
||||
for i := 2; i < len(args); i++ {
|
||||
switch args[i] {
|
||||
case "--plan":
|
||||
if i+1 < len(args) {
|
||||
plan = args[i+1]
|
||||
i++
|
||||
}
|
||||
case "--balance":
|
||||
if i+1 < len(args) {
|
||||
balance = parseFloat(args[i+1])
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("Creating subscriber (Profile: %s):\n", config.Profile)
|
||||
fmt.Printf(" IMSI: %s\n", imsi)
|
||||
fmt.Printf(" Name: %s\n", name)
|
||||
fmt.Printf(" Plan: %s\n", plan)
|
||||
fmt.Printf(" Balance: $%.2f\n", balance)
|
||||
|
||||
if config.Verbose {
|
||||
fmt.Println("Connecting to API...")
|
||||
fmt.Printf("POST %s/api/subscribers\n", config.APIEndpoint)
|
||||
}
|
||||
|
||||
fmt.Println("Subscriber created successfully!")
|
||||
fmt.Printf("Subscriber ID: %s\n", imsi)
|
||||
fmt.Printf("Account created with initial balance: $%.2f\n", balance)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateSubscriberEnhanced(args []string, config *types.CLIConfig) error {
|
||||
if len(args) < 1 {
|
||||
fmt.Println("Error: IMSI is required")
|
||||
fmt.Println("Usage: telecom-cli subscribers update <imsi> [options]")
|
||||
return fmt.Errorf("missing IMSI")
|
||||
}
|
||||
|
||||
imsi := args[0]
|
||||
fmt.Printf("Updating subscriber: IMSI=%s (Profile: %s)\n", imsi, config.Profile)
|
||||
fmt.Println("Subscriber updated successfully!")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteSubscriberEnhanced(args []string, config *types.CLIConfig) error {
|
||||
if len(args) < 1 {
|
||||
fmt.Println("Error: IMSI is required")
|
||||
fmt.Println("Usage: telecom-cli subscribers delete <imsi>")
|
||||
return fmt.Errorf("missing IMSI")
|
||||
}
|
||||
|
||||
imsi := args[0]
|
||||
fmt.Printf("Deleting subscriber: IMSI=%s (Profile: %s)\n", imsi, config.Profile)
|
||||
fmt.Println("Subscriber deleted successfully!")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func activateSubscriberEnhanced(args []string, config *types.CLIConfig) error {
|
||||
if len(args) < 1 {
|
||||
fmt.Println("Error: IMSI is required")
|
||||
fmt.Println("Usage: telecom-cli subscribers activate <imsi>")
|
||||
return fmt.Errorf("missing IMSI")
|
||||
}
|
||||
|
||||
imsi := args[0]
|
||||
fmt.Printf("Activating subscriber: IMSI=%s (Profile: %s)\n", imsi, config.Profile)
|
||||
fmt.Println("Subscriber activated successfully!")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func deactivateSubscriberEnhanced(args []string, config *types.CLIConfig) error {
|
||||
if len(args) < 1 {
|
||||
fmt.Println("Error: IMSI is required")
|
||||
fmt.Println("Usage: telecom-cli subscribers deactivate <imsi>")
|
||||
return fmt.Errorf("missing IMSI")
|
||||
}
|
||||
|
||||
imsi := args[0]
|
||||
fmt.Printf("Deactivating subscriber: IMSI=%s (Profile: %s)\n", imsi, config.Profile)
|
||||
fmt.Println("Subscriber deactivated successfully!")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkBalanceEnhanced(args []string, config *types.CLIConfig) error {
|
||||
if len(args) < 1 {
|
||||
fmt.Println("Error: IMSI is required")
|
||||
fmt.Println("Usage: telecom-cli subscribers balance <imsi>")
|
||||
return fmt.Errorf("missing IMSI")
|
||||
}
|
||||
|
||||
imsi := args[0]
|
||||
fmt.Printf("Balance for subscriber IMSI=%s (Profile: %s):\n", imsi, config.Profile)
|
||||
fmt.Printf("Current Balance: $45.67\n")
|
||||
fmt.Printf("Last Top-up: $50.00 on 2024-01-10\n")
|
||||
fmt.Printf("Monthly Usage: $12.33\n")
|
||||
fmt.Printf("Available Credit: $33.34\n")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func showUsageEnhanced(args []string, config *types.CLIConfig) error {
|
||||
if len(args) < 1 {
|
||||
fmt.Println("Error: IMSI is required")
|
||||
fmt.Println("Usage: telecom-cli subscribers usage <imsi>")
|
||||
return fmt.Errorf("missing IMSI")
|
||||
}
|
||||
|
||||
imsi := args[0]
|
||||
fmt.Printf("Usage Statistics for IMSI=%s (Profile: %s):\n", imsi, config.Profile)
|
||||
|
||||
fmt.Println("Current Billing Period (2024-01)")
|
||||
fmt.Println("Data Usage:")
|
||||
fmt.Printf(" Used: 2.3GB\n")
|
||||
fmt.Printf(" Limit: 10GB\n")
|
||||
fmt.Printf(" Remaining: 7.7GB\n")
|
||||
fmt.Println()
|
||||
fmt.Println("Voice Usage:")
|
||||
fmt.Printf(" Used: 45 minutes\n")
|
||||
fmt.Printf(" Limit: 500 minutes\n")
|
||||
fmt.Printf(" Remaining: 455 minutes\n")
|
||||
fmt.Println()
|
||||
fmt.Println("SMS Usage:")
|
||||
fmt.Printf(" Used: 23 messages\n")
|
||||
fmt.Printf(" Limit: 100 messages\n")
|
||||
fmt.Printf(" Remaining: 77 messages\n")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func searchSubscribersEnhanced(args []string, config *types.CLIConfig) error {
|
||||
if len(args) < 1 {
|
||||
fmt.Println("Error: Search query is required")
|
||||
fmt.Println("Usage: telecom-cli subscribers search <query>")
|
||||
return fmt.Errorf("missing search query")
|
||||
}
|
||||
|
||||
query := args[0]
|
||||
fmt.Printf("Searching subscribers for: %s (Profile: %s)\n", query, config.Profile)
|
||||
fmt.Println("Search Results:")
|
||||
fmt.Println("IMSI Name Status Balance")
|
||||
fmt.Println("----------------------------------------------------")
|
||||
fmt.Println("310260123456789 John Doe Active $45.67")
|
||||
fmt.Println("310260123456792 Alice Brown Active $89.23")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
func parseInt(s string) int {
|
||||
// Simple implementation - in real code would use strconv.Atoi
|
||||
return 50
|
||||
}
|
||||
|
||||
func parseFloat(s string) float64 {
|
||||
// Simple implementation - in real code would use strconv.ParseFloat
|
||||
return 0.0
|
||||
}
|
||||
Reference in New Issue
Block a user