> ## Documentation Index
> Fetch the complete documentation index at: https://docs.switchport.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Advanced Usage Examples

> Advanced patterns for A/B testing, metrics aggregation, and production use cases

## Overview

This guide covers advanced usage patterns:

* Deterministic A/B testing
* Metrics aggregation across versions
* Production-ready patterns
* Real-world use cases

## A/B Testing with Consistent Routing

The same context always gets the same version, ensuring consistent user experiences.

```go theme={null}
package main

import (
	"fmt"
	"log"

	"github.com/switchport-ai/switchport-go/switchport"
)

func demonstrateABTesting(client *switchport.Client) {
	// Show that same context gets same version
	users := []string{"user_001", "user_002", "user_003"}

	// First execution - assign versions
	fmt.Println("First execution:")
	userVersions := make(map[string]string)

	for _, userID := range users {
		response, err := client.Prompts.Execute(
			"product-pitch",
			map[string]interface{}{"user_id": userID},
			map[string]interface{}{"product": "Pro Plan"},
		)
		if err != nil {
			log.Printf("Error for %s: %v", userID, err)
			continue
		}
		userVersions[userID] = response.VersionName
		fmt.Printf("  %s: %s\n", userID, response.VersionName)
	}

	// Second execution - verify consistency
	fmt.Println("\nSecond execution (should be same):")

	for _, userID := range users {
		response, err := client.Prompts.Execute(
			"product-pitch",
			map[string]interface{}{"user_id": userID},
			map[string]interface{}{"product": "Pro Plan"},
		)
		if err != nil {
			log.Printf("Error for %s: %v", userID, err)
			continue
		}

		isSame := "✓"
		if response.VersionName != userVersions[userID] {
			isSame = "✗"
		}
		fmt.Printf("  %s: %s %s\n", userID, response.VersionName, isSame)
	}
}

func main() {
	client, err := switchport.NewClient("")
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}

	demonstrateABTesting(client)
}
```

## Metrics Aggregation Pattern

Record metrics with the same context to aggregate by version:

```go theme={null}
package main

import (
	"fmt"
	"log"

	"github.com/switchport-ai/switchport-go/switchport"
)

func userInteractionWorkflow(client *switchport.Client, userID string, userRating float64) error {
	// Execute prompt with context
	context := map[string]interface{}{
		"user_id": userID,
		"segment": "premium",
	}

	response, err := client.Prompts.Execute(
		"welcome-email",
		context,
		map[string]interface{}{"name": fmt.Sprintf("User %s", userID)},
	)
	if err != nil {
		return err
	}

	// In real app: send email, show content, etc.
	fmt.Printf("User %s saw version: %s\n", userID, response.VersionName)

	// Record metric with SAME context
	_, err = client.Metrics.Record(
		"satisfaction",
		userRating,
		context, // Same context!
		nil,
	)
	if err != nil {
		return err
	}

	fmt.Printf("Metric recorded for %s: %.1f\n", userID, userRating)
	return nil
}

func main() {
	client, err := switchport.NewClient("")
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}

	// Simulate multiple user interactions
	users := map[string]float64{
		"user_001": 4.5,
		"user_002": 5.0,
		"user_003": 4.0,
		"user_001": 4.8, // Same user, different session
	}

	for userID, rating := range users {
		if err := userInteractionWorkflow(client, userID, rating); err != nil {
			log.Printf("Error processing %s: %v", userID, err)
		}
	}

	fmt.Println("\nMetrics will be aggregated per version in the dashboard!")
}
```

## Email Campaign Example

Complete email campaign workflow with A/B testing:

```go theme={null}
package main

import (
	"fmt"
	"log"
	"time"

	"github.com/switchport-ai/switchport-go/switchport"
)

type User struct {
	ID        string
	Name      string
	Email     string
	Segment   string
	CreatedAt time.Time
}

func runEmailCampaign(client *switchport.Client, users []User) {
	for _, user := range users {
		if err := sendMarketingEmail(client, user); err != nil {
			log.Printf("Failed to send email to %s: %v", user.ID, err)
		}
	}
}

func sendMarketingEmail(client *switchport.Client, user User) error {
	context := map[string]interface{}{
		"user_id":  user.ID,
		"segment":  user.Segment,
		"campaign": "summer_sale_2025",
	}

	// Execute prompt to generate email content
	response, err := client.Prompts.Execute(
		"marketing-email",
		context,
		map[string]interface{}{
			"name":         user.Name,
			"signup_date":  user.CreatedAt.Format("January 2, 2006"),
			"product":      "Summer Sale",
			"discount":     "30%",
		},
	)
	if err != nil {
		return fmt.Errorf("failed to generate email: %w", err)
	}

	// Send email (simulated)
	fmt.Printf("📧 Sending email to %s (%s)\n", user.Name, user.Email)
	fmt.Printf("   Version: %s\n", response.VersionName)
	fmt.Printf("   Preview: %s...\n\n", response.Text[:100])

	// Track email sent
	go trackEmailMetric(client, "email_sent", true, context)

	return nil
}

func trackEmailOpened(client *switchport.Client, userID, segment, campaign string) {
	context := map[string]interface{}{
		"user_id":  userID,
		"segment":  segment,
		"campaign": campaign,
	}
	trackEmailMetric(client, "email_opened", true, context)
}

func trackEmailClicked(client *switchport.Client, userID, segment, campaign string) {
	context := map[string]interface{}{
		"user_id":  userID,
		"segment":  segment,
		"campaign": campaign,
	}
	trackEmailMetric(client, "email_clicked", true, context)
}

func trackConversion(client *switchport.Client, userID, segment, campaign string) {
	context := map[string]interface{}{
		"user_id":  userID,
		"segment":  segment,
		"campaign": campaign,
	}
	trackEmailMetric(client, "conversion", true, context)
}

func trackEmailMetric(client *switchport.Client, metricKey string, value bool, context map[string]interface{}) {
	_, err := client.Metrics.Record(metricKey, value, context, nil)
	if err != nil {
		log.Printf("Failed to record %s: %v", metricKey, err)
	}
}

func main() {
	client, err := switchport.NewClient("")
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}

	users := []User{
		{ID: "user_001", Name: "Alice", Email: "alice@example.com", Segment: "premium", CreatedAt: time.Now().AddDate(0, -3, 0)},
		{ID: "user_002", Name: "Bob", Email: "bob@example.com", Segment: "basic", CreatedAt: time.Now().AddDate(0, -6, 0)},
		{ID: "user_003", Name: "Carol", Email: "carol@example.com", Segment: "premium", CreatedAt: time.Now().AddDate(0, -1, 0)},
	}

	runEmailCampaign(client, users)

	// Simulate user interactions
	time.Sleep(1 * time.Second)
	trackEmailOpened(client, "user_001", "premium", "summer_sale_2025")
	trackEmailClicked(client, "user_001", "premium", "summer_sale_2025")
	trackConversion(client, "user_001", "premium", "summer_sale_2025")

	fmt.Println("✓ Campaign complete! Check dashboard for A/B test results.")
}
```

## Chatbot Example

Customer support chatbot with context tracking:

```go theme={null}
package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"strings"

	"github.com/switchport-ai/switchport-go/switchport"
)

type Conversation struct {
	UserID  string
	History []Message
}

type Message struct {
	Role    string // "user" or "assistant"
	Content string
}

func (c *Conversation) AddMessage(role, content string) {
	c.History = append(c.History, Message{Role: role, Content: content})
}

func (c *Conversation) GetHistory() string {
	var sb strings.Builder
	for _, msg := range c.History {
		sb.WriteString(fmt.Sprintf("%s: %s\n", msg.Role, msg.Content))
	}
	return sb.String()
}

func getBotResponse(client *switchport.Client, conv *Conversation, userMessage string) (string, error) {
	conv.AddMessage("user", userMessage)

	response, err := client.Prompts.Execute(
		"support-bot",
		map[string]interface{}{
			"user_id":    conv.UserID,
			"session_id": "session_123",
		},
		map[string]interface{}{
			"user_message": userMessage,
			"history":      conv.GetHistory(),
		},
	)
	if err != nil {
		return "", err
	}

	conv.AddMessage("assistant", response.Text)
	return response.Text, nil
}

func rateConversation(client *switchport.Client, userID string, rating float64, resolved bool) {
	context := map[string]interface{}{
		"user_id":    userID,
		"session_id": "session_123",
	}

	// Record satisfaction
	client.Metrics.Record("satisfaction", rating, context, nil)

	// Record resolution
	client.Metrics.Record("resolved", resolved, context, nil)
}

func main() {
	client, err := switchport.NewClient("")
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}

	conv := &Conversation{UserID: "user_123"}

	fmt.Println("Support Chatbot (type 'exit' to quit)")
	fmt.Println("==========================================")

	scanner := bufio.NewScanner(os.Stdin)
	for {
		fmt.Print("\nYou: ")
		if !scanner.Scan() {
			break
		}

		userInput := scanner.Text()
		if strings.ToLower(userInput) == "exit" {
			break
		}

		botResponse, err := getBotResponse(client, conv, userInput)
		if err != nil {
			fmt.Printf("Error: %v\n", err)
			continue
		}

		fmt.Printf("Bot: %s\n", botResponse)
	}

	// Get feedback
	fmt.Print("\nRate this conversation (1-5): ")
	var rating float64
	fmt.Scanf("%f", &rating)

	fmt.Print("Was your issue resolved? (y/n): ")
	var resolvedStr string
	fmt.Scanf("%s", &resolvedStr)
	resolved := strings.ToLower(resolvedStr) == "y"

	rateConversation(client, conv.UserID, rating, resolved)
	fmt.Println("\nThank you for your feedback!")
}
```

## Product Description Generator

Generate product descriptions with A/B testing:

```go theme={null}
package main

import (
	"fmt"
	"log"
	"strings"

	"github.com/switchport-ai/switchport-go/switchport"
)

type Product struct {
	ID          string
	Name        string
	Features    []string
	Price       float64
	Category    string
}

func generateProductDescription(client *switchport.Client, product Product, userSegment string) (string, error) {
	response, err := client.Prompts.Execute(
		"product-description",
		map[string]interface{}{
			"product_id": product.ID,
			"segment":    userSegment,
		},
		map[string]interface{}{
			"product_name": product.Name,
			"features":     strings.Join(product.Features, ", "),
			"price":        fmt.Sprintf("$%.2f", product.Price),
			"category":     product.Category,
		},
	)
	if err != nil {
		return "", err
	}

	fmt.Printf("Generated description (Version: %s)\n", response.VersionName)
	return response.Text, nil
}

func trackProductView(client *switchport.Client, productID, userSegment string, timeOnPage int) {
	context := map[string]interface{}{
		"product_id": productID,
		"segment":    userSegment,
	}

	// Track page view time
	client.Metrics.Record("time_on_page_seconds", timeOnPage, context, nil)
}

func trackAddToCart(client *switchport.Client, productID, userSegment string) {
	context := map[string]interface{}{
		"product_id": productID,
		"segment":    userSegment,
	}

	client.Metrics.Record("added_to_cart", true, context, nil)
}

func trackPurchase(client *switchport.Client, productID, userSegment string) {
	context := map[string]interface{}{
		"product_id": productID,
		"segment":    userSegment,
	}

	client.Metrics.Record("purchased", true, context, nil)
}

func main() {
	client, err := switchport.NewClient("")
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}

	product := Product{
		ID:       "prod_123",
		Name:     "Smart Wireless Earbuds",
		Features: []string{"Active Noise Cancellation", "40-hour battery", "Wireless charging"},
		Price:    149.99,
		Category: "Electronics",
	}

	// Generate descriptions for different segments
	segments := []string{"budget", "premium", "tech_enthusiast"}

	for _, segment := range segments {
		desc, err := generateProductDescription(client, product, segment)
		if err != nil {
			log.Printf("Error for %s segment: %v", segment, err)
			continue
		}

		fmt.Printf("\n%s Segment Description:\n%s\n", segment, desc)
	}

	// Simulate user interactions
	trackProductView(client, product.ID, "premium", 45)
	trackAddToCart(client, product.ID, "premium")
	trackPurchase(client, product.ID, "premium")

	fmt.Println("\n✓ Check dashboard to compare conversion rates across versions!")
}
```

## Gradual Rollout Pattern

Safely roll out new prompt versions:

```go theme={null}
package main

import (
	"fmt"
	"log"

	"github.com/switchport-ai/switchport-go/switchport"
)

func gradualRolloutExample(client *switchport.Client) {
	fmt.Println("Gradual Rollout Example")
	fmt.Println("========================")
	fmt.Println("Day 1: 10% on v2, 90% on v1")
	fmt.Println("Day 3: 50% on v2, 50% on v1")
	fmt.Println("Day 5: 100% on v2")
	fmt.Println()

	// Simulate 100 users
	for i := 1; i <= 100; i++ {
		userID := fmt.Sprintf("user_%03d", i)

		response, err := client.Prompts.Execute(
			"welcome-message",
			map[string]interface{}{"user_id": userID},
			map[string]interface{}{"name": fmt.Sprintf("User %d", i)},
		)
		if err != nil {
			log.Printf("Error for %s: %v", userID, err)
			continue
		}

		fmt.Printf("User %s: Version %s\n", userID, response.VersionName)
	}
}

func main() {
	client, err := switchport.NewClient("")
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}

	gradualRolloutExample(client)
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Use goroutines for async metrics">
    Record metrics asynchronously to avoid blocking your main application flow.
  </Accordion>

  <Accordion title="Implement proper error handling">
    Always handle errors gracefully with fallbacks and logging.
  </Accordion>

  <Accordion title="Use context consistently">
    Always use the same context structure across prompt executions and metric recordings.
  </Accordion>

  <Accordion title="Monitor version distribution">
    Regularly check the dashboard to ensure traffic is distributed as expected.
  </Accordion>

  <Accordion title="Define success metrics upfront">
    Know what metrics matter before running A/B tests.
  </Accordion>
</AccordionGroup>

## Next Steps

<Columns cols={2}>
  <Card title="Error Handling" icon="shield" href="/sdk/go/examples/error-handling">
    Learn production-ready error handling patterns
  </Card>

  <Card title="API Reference" icon="code" href="/sdk/go/reference/client">
    Explore the complete API reference
  </Card>
</Columns>
