# Feature 9: Ad Manager (Variants & A/B Testing)

## Laravel Implementation Prompt

### Goal
Create an Ad variant manager UI and storage system that enables brands to create, manage, and test multiple ad variants with A/B testing capabilities.

### Database Schema Requirements

#### Tables to Create

1. **ads** table
   - `id` (primary key)
   - `brand_id` (foreign key to brands)
   - `campaign_id` (foreign key to campaigns, nullable)
   - `product_name` (string)
   - `target_audience` (text/json)
   - `base_cta` (string)
   - `status` (enum: draft, active, archived)
   - `created_by` (foreign key to users)
   - `approved_by` (foreign key to users, nullable)
   - `approved_at` (timestamp, nullable)
   - `archived_at` (timestamp, nullable)
   - `timestamps`
   - `soft_deletes`

2. **ad_variants** table
   - `id` (primary key)
   - `ad_id` (foreign key to ads)
   - `variant_name` (string, e.g., "Variant A", "Variant B")
   - `headline` (string)
   - `body` (text)
   - `cta_text` (string)
   - `image_url` (string, nullable)
   - `video_url` (string, nullable)
   - `status` (enum: draft, active, paused, archived)
   - `is_control` (boolean, default false)
   - `ai_generated` (boolean, default false)
   - `ai_job_id` (string, nullable)
   - `predicted_ctr` (decimal, nullable)
   - `predicted_engagement` (decimal, nullable)
   - `timestamps`
   - `soft_deletes`

3. **ad_performance_metrics** table
   - `id` (primary key)
   - `ad_variant_id` (foreign key to ad_variants)
   - `platform` (string: facebook, instagram, twitter, etc.)
   - `impressions` (integer, default 0)
   - `clicks` (integer, default 0)
   - `conversions` (integer, default 0)
   - `spend` (decimal, default 0)
   - `ctr` (decimal, calculated)
   - `conversion_rate` (decimal, calculated)
   - `cost_per_click` (decimal, calculated)
   - `cost_per_conversion` (decimal, calculated)
   - `engagement_rate` (decimal)
   - `recorded_at` (timestamp)
   - `timestamps`

4. **ab_tests** table
   - `id` (primary key)
   - `ad_id` (foreign key to ads)
   - `test_name` (string)
   - `test_type` (enum: headline, body, cta, creative, full)
   - `status` (enum: scheduled, running, completed, cancelled)
   - `start_date` (timestamp)
   - `end_date` (timestamp)
   - `traffic_split` (json, e.g., {"variant_a": 50, "variant_b": 50})
   - `winner_variant_id` (foreign key to ad_variants, nullable)
   - `confidence_level` (decimal, nullable)
   - `statistical_significance` (boolean, default false)
   - `results_summary` (json, nullable)
   - `timestamps`

### Models to Create

1. **Ad Model** (`app/Models/Ad.php`)
   - Relationships:
     - `belongsTo(Brand::class)`
     - `belongsTo(Campaign::class)`
     - `hasMany(AdVariant::class)`
     - `hasMany(AbTest::class)`
     - `belongsTo(User::class, 'created_by')`
     - `belongsTo(User::class, 'approved_by')`
   - Scopes:
     - `scopeActive($query)`
     - `scopeDraft($query)`
     - `scopeArchived($query)`
     - `scopeForBrand($query, $brandId)`
   - Methods:
     - `archive()` - Archive ad and all variants
     - `needsApproval()` - Check if approval workflow required
     - `approve(User $user)` - Approve ad for regulated industries

2. **AdVariant Model** (`app/Models/AdVariant.php`)
   - Relationships:
     - `belongsTo(Ad::class)`
     - `hasMany(AdPerformanceMetric::class)`
   - Scopes:
     - `scopeActive($query)`
     - `scopeControl($query)`
   - Methods:
     - `calculatePerformance()` - Aggregate metrics
     - `getLatestMetrics()` - Get most recent performance data
     - `pause()` - Pause variant
     - `activate()` - Activate variant

3. **AdPerformanceMetric Model** (`app/Models/AdPerformanceMetric.php`)
   - Relationships:
     - `belongsTo(AdVariant::class)`
   - Accessors:
     - `getCtrAttribute()` - Calculate CTR
     - `getConversionRateAttribute()` - Calculate conversion rate
     - `getCostPerClickAttribute()` - Calculate CPC
     - `getCostPerConversionAttribute()` - Calculate cost per conversion

4. **AbTest Model** (`app/Models/AbTest.php`)
   - Relationships:
     - `belongsTo(Ad::class)`
     - `belongsTo(AdVariant::class, 'winner_variant_id')`
   - Scopes:
     - `scopeRunning($query)`
     - `scopeCompleted($query)`
   - Methods:
     - `start()` - Start test
     - `complete()` - Complete test and determine winner
     - `calculateStatisticalSignificance()` - Calculate significance

### Controllers to Create

1. **AdManagerController** (`app/Http/Controllers/Brand/AdManagerController.php`)
   
   **Routes:**
   ```
   GET    /brand/ads                    - index()
   GET    /brand/ads/create             - create()
   POST   /brand/ads                    - store()
   GET    /brand/ads/{ad}               - show()
   GET    /brand/ads/{ad}/edit          - edit()
   PUT    /brand/ads/{ad}               - update()
   DELETE /brand/ads/{ad}               - destroy()
   POST   /brand/ads/{ad}/archive       - archive()
   POST   /brand/ads/{ad}/approve       - approve()
   ```

   **Methods:**
   - `index()` - List all ads with filters (status, campaign, date range)
   - `create()` - Show ad creation form
   - `store(Request $request)` - Create new ad with base info
   - `show(Ad $ad)` - Display ad details with all variants and performance
   - `edit(Ad $ad)` - Show edit form
   - `update(Request $request, Ad $ad)` - Update ad base info
   - `destroy(Ad $ad)` - Soft delete ad
   - `archive(Ad $ad)` - Archive ad and variants
   - `approve(Request $request, Ad $ad)` - Approve ad (for regulated industries)

2. **AdVariantController** (`app/Http/Controllers/Brand/AdVariantController.php`)
   
   **Routes:**
   ```
   GET    /brand/ads/{ad}/variants                    - index()
   GET    /brand/ads/{ad}/variants/create             - create()
   POST   /brand/ads/{ad}/variants                    - store()
   GET    /brand/ads/{ad}/variants/{variant}          - show()
   PUT    /brand/ads/{ad}/variants/{variant}          - update()
   DELETE /brand/ads/{ad}/variants/{variant}          - destroy()
   POST   /brand/ads/{ad}/variants/generate           - generateWithAI()
   POST   /brand/ads/{ad}/variants/{variant}/pause    - pause()
   POST   /brand/ads/{ad}/variants/{variant}/activate - activate()
   ```

   **Methods:**
   - `index(Ad $ad)` - List all variants for an ad
   - `create(Ad $ad)` - Show variant creation form
   - `store(Request $request, Ad $ad)` - Create new variant manually
   - `show(Ad $ad, AdVariant $variant)` - Display variant details with performance
   - `update(Request $request, Ad $ad, AdVariant $variant)` - Update variant
   - `destroy(Ad $ad, AdVariant $variant)` - Delete variant
   - `generateWithAI(Request $request, Ad $ad)` - Request AI-generated variants
   - `pause(Ad $ad, AdVariant $variant)` - Pause variant
   - `activate(Ad $ad, AdVariant $variant)` - Activate variant

3. **AbTestController** (`app/Http/Controllers/Brand/AbTestController.php`)
   
   **Routes:**
   ```
   GET    /brand/ads/{ad}/ab-tests                - index()
   POST   /brand/ads/{ad}/ab-tests                - store()
   GET    /brand/ads/{ad}/ab-tests/{test}         - show()
   POST   /brand/ads/{ad}/ab-tests/{test}/start   - start()
   POST   /brand/ads/{ad}/ab-tests/{test}/stop    - stop()
   GET    /brand/ads/{ad}/ab-tests/{test}/results - results()
   ```

   **Methods:**
   - `index(Ad $ad)` - List all A/B tests for an ad
   - `store(Request $request, Ad $ad)` - Create and schedule new A/B test
   - `show(Ad $ad, AbTest $test)` - Display test details and progress
   - `start(Ad $ad, AbTest $test)` - Start scheduled test
   - `stop(Ad $ad, AbTest $test)` - Stop running test early
   - `results(Ad $ad, AbTest $test)` - Display detailed test results

### Request Validation Classes

1. **StoreAdRequest** (`app/Http/Requests/StoreAdRequest.php`)
   ```
   Rules:
   - product_name: required|string|max:255
   - target_audience: required|array
   - base_cta: required|string|max:100
   - campaign_id: nullable|exists:campaigns,id
   ```

2. **StoreAdVariantRequest** (`app/Http/Requests/StoreAdVariantRequest.php`)
   ```
   Rules:
   - variant_name: required|string|max:100
   - headline: required|string|max:150
   - body: required|string|max:500
   - cta_text: required|string|max:50
   - image_url: nullable|url
   - video_url: nullable|url
   - is_control: boolean
   ```

3. **GenerateVariantsRequest** (`app/Http/Requests/GenerateVariantsRequest.php`)
   ```
   Rules:
   - num_variants: required|integer|min:2|max:10
   - tone: required|string|in:professional,casual,urgent,friendly
   - focus: required|string|in:awareness,consideration,conversion
   ```

4. **StoreAbTestRequest** (`app/Http/Requests/StoreAbTestRequest.php`)
   ```
   Rules:
   - test_name: required|string|max:255
   - test_type: required|in:headline,body,cta,creative,full
   - variant_ids: required|array|min:2
   - variant_ids.*: exists:ad_variants,id
   - start_date: required|date|after:now
   - end_date: required|date|after:start_date
   - traffic_split: required|array
   ```

### Views to Create

1. **ads/index.blade.php** - Ad listing page
   - Filters: status, campaign, date range
   - Table columns: product, campaign, variants count, status, performance summary
   - Actions: view, edit, archive, create A/B test

2. **ads/create.blade.php** - Ad creation form
   - Fields: product name, target audience (tags/json), base CTA, campaign selection
   - Option to create first variant immediately

3. **ads/show.blade.php** - Ad detail page
   - Ad base information
   - Variants list with performance metrics
   - A/B tests section
   - Performance comparison chart
   - Actions: add variant, create A/B test, archive

4. **ads/variants/create.blade.php** - Variant creation form
   - Manual entry fields: variant name, headline, body, CTA, media
   - AI generation option with parameters
   - Preview section

5. **ads/variants/show.blade.php** - Variant detail page
   - Variant content preview
   - Performance metrics table (by platform)
   - Performance charts (impressions, CTR, conversions over time)
   - Actions: edit, pause/activate, delete

6. **ads/ab-tests/create.blade.php** - A/B test setup form
   - Test name and type selection
   - Variant selection (checkboxes)
   - Traffic split configuration (sliders)
   - Schedule dates
   - Success metrics selection

7. **ads/ab-tests/show.blade.php** - A/B test results page
   - Test configuration summary
   - Real-time performance comparison table
   - Statistical significance indicator
   - Winner declaration (if completed)
   - Performance charts comparing variants

### API Integration Points

1. **AI Variant Generation**
   ```
   POST /api/ai/ads/generate
   Payload: {
     product_info: string,
     audience: object,
     tone: string,
     num_variants: integer
   }
   Response: {
     variants: [{headline, body, cta, predicted_ctr, predicted_engagement}],
     ai_job_id: string
   }
   ```

2. **Performance Prediction**
   ```
   POST /api/ai/ads/predict
   Payload: {
     variant_id: integer,
     platform: string,
     audience_size: integer
   }
   Response: {
     predicted_metrics: {ctr, engagement, conversions},
     confidence_bands: {low, high},
     ai_job_id: string
   }
   ```

### Jobs/Queue Classes

1. **FetchAdPerformanceJob** (`app/Jobs/FetchAdPerformanceJob.php`)
   - Fetch performance metrics from ad platforms (Facebook, Instagram, etc.)
   - Store in ad_performance_metrics table
   - Schedule: every hour for active variants

2. **GenerateAdVariantsJob** (`app/Jobs/GenerateAdVariantsJob.php`)
   - Call Python AI service to generate variants
   - Store generated variants with AI metadata
   - Notify user when complete

3. **CheckAbTestSignificanceJob** (`app/Jobs/CheckAbTestSignificanceJob.php`)
   - Calculate statistical significance for running tests
   - Auto-complete test if significance reached
   - Schedule: every 6 hours for running tests

### Services to Create

1. **AdVariantService** (`app/Services/AdVariantService.php`)
   - `generateVariants(Ad $ad, array $params)` - Call AI service
   - `calculatePerformance(AdVariant $variant)` - Aggregate metrics
   - `compareVariants(array $variantIds)` - Compare performance

2. **AbTestService** (`app/Services/AbTestService.php`)
   - `createTest(Ad $ad, array $params)` - Setup A/B test
   - `startTest(AbTest $test)` - Activate test
   - `calculateWinner(AbTest $test)` - Determine winner with statistical significance
   - `generateReport(AbTest $test)` - Create detailed report

### Middleware Requirements

1. **EnsureAdOwnership** - Verify user owns the ad's brand
2. **CheckAdApprovalRequired** - Check if approval workflow needed (regulated industries)

### Configuration

Add to `config/ads.php`:
```php
return [
    'approval_required_industries' => ['healthcare', 'finance', 'pharma'],
    'max_variants_per_ad' => 10,
    'min_test_duration_days' => 7,
    'significance_threshold' => 0.95,
    'platforms' => ['facebook', 'instagram', 'twitter', 'linkedin', 'tiktok'],
];
```

### Acceptance Criteria

1. ✅ Variant lifecycle (draft → active → archived) works correctly
2. ✅ Results stored in database and visible in UI
3. ✅ A/B tests can be scheduled, started, and completed
4. ✅ Statistical significance calculated and displayed
5. ✅ Winner automatically determined when significance reached
6. ✅ Performance metrics updated regularly from platforms
7. ✅ AI-generated variants stored with metadata
8. ✅ Approval workflow enforced for regulated industries

### Security Considerations

1. **Ad Approvals Workflow**
   - Implement approval queue for regulated industries
   - Store approval history with timestamps and approver
   - Prevent activation without approval
   - Email notifications for approval requests

2. **Access Control**
   - Verify brand ownership before any ad operations
   - Restrict ad editing to brand admins and creators
   - Audit log for all ad changes

3. **Data Validation**
   - Sanitize all user inputs
   - Validate platform-specific character limits
   - Prevent XSS in ad content

### Operations Considerations

1. **Performance Monitoring**
   - Log all API calls to ad platforms
   - Track AI service response times
   - Monitor queue job failures

2. **Cost Management**
   - Track API usage per brand
   - Implement rate limiting for AI generation
   - Alert on unusual spend patterns

3. **Data Retention**
   - Archive old performance metrics after 1 year
   - Soft delete ads with 30-day recovery window
   - Export functionality for compliance