Files
igny8/docs/plans/COMPREHENSIVE-SYSTEM-FIX-PLAN-JAN-10-2026.md
IGNY8 VPS (Salman) 6e15ffb49b reorg docs
2026-01-10 14:35:13 +00:00

34 KiB
Raw Blame History

COMPREHENSIVE SYSTEM FIX PLAN

Date: January 10, 2026
Last Updated: January 10, 2026
Priority: CRITICAL
Status: Phase 1 Complete - Phase 2 In Progress


EXECUTIVE SUMMARY

This plan tracks all identified system issues, their status, and implementation details. Issues are categorized by priority and module.

Issue Categories:

  1. Backend Data Model & Credits (2 issues - COMPLETED)
  2. Frontend - Automation (3 issues)
  3. Frontend - Publishing & Calendar (3 issues)
  4. Frontend - Planner/Writer Pages (2 issues)
  5. Frontend - Sites & Settings (3 issues)
  6. Branding & Terminology (2 issues)
  7. New Features (2 issues)

Completion Status:

  • Phase 1 (Backend Credit System): COMPLETED
  • 🔄 Phase 2 (Frontend Critical): IN PROGRESS
  • Phase 3 (UX Improvements): PENDING
  • Phase 4 (New Features): PENDING

Impact: These fixes will ensure:

  • All AI functions log consistently to AI tasks, notifications, and usage logs
  • Image generation properly deducts and logs credits with cost calculations
  • No attribute errors in AI model configuration
  • Consistent data display across all pages
  • Improved UX with proper button styling and working features
  • Proper terminology throughout the app (site vs wordpress)
  • Auto-approve and auto-publish working correctly
  • Content calendar showing published content

ISSUE 1: AIModelConfig AttributeError - input_cost_per_1m

COMPLETED - v1.7.1

Error Message:

Failed to cluster keywords: Unexpected error: 'AIModelConfig' object has no attribute 'input_cost_per_1m'

Root Cause: The AIModelConfig model uses field names cost_per_1k_input and cost_per_1k_output, but model_registry.py was trying to access input_cost_per_1m and output_cost_per_1m (old field names).

Fix Applied in v1.7.1:

  • Updated field references in model_registry.py to use correct field names
  • Updated field references in serializers.py to match

Files Changed:

  1. backend/igny8_core/ai/model_registry.py
  2. backend/igny8_core/modules/billing/serializers.py

ISSUE 2: Image Generation - Missing Credit Tracking & Logging

COMPLETED - v1.7.1

Problem: Image generation was not:

  • Logging to AI tasks table (AITaskLog)
  • Logging to notifications
  • Logging to usage logs with cost calculations
  • Deducting credits properly based on model configuration

Fix Applied in v1.7.1:

  • Added CreditService.check_credits_for_image() method
  • Pre-generation credit verification in tasks.py
  • Credit deduction after each successful image
  • AITaskLog creation for image generation
  • Notification integration

Files Changed:

  1. backend/igny8_core/business/billing/services/credit_service.py
  2. backend/igny8_core/ai/tasks.py

See CHANGELOG v1.7.1 for full details. → ai_core.generate_image() → Returns result → Deduct credits (CreditService.deduct_credits_for_image) → Create AITaskLog → Create notification → Create usage log with cost


**What Exists (Ready to Use):**
- ✅ `CreditService.calculate_credits_for_image()` - calculates credits from model config
- ✅ `CreditService.deduct_credits_for_image()` - deducts credits and creates logs
- ✅ `AIModelConfig.credits_per_image` - configured for all image models
- ✅ Notification templates for image generation

**What's Missing:**
- ❌ Integration of credit tracking into image generation flow
- ❌ AITaskLog creation for image generation
- ❌ Notification creation for image generation
- ❌ Usage log creation with cost calculation

**Fix Strategy:**

### Phase 1: Integrate Credit Tracking into Image Generation

**Step 1.1: Update `generate_images_core()` function**

File: `backend/igny8_core/ai/functions/generate_images.py`

Current logic (lines 203-278):
```python
def generate_images_core(task_ids, account_id, progress_callback):
    # ... gets tasks ...
    # ... generates images ...
    # ❌ NO credit tracking
    return {'success': True, 'images_created': count}

NEW Implementation:

def generate_images_core(task_ids, account_id, progress_callback):
    """Core image generation with full credit tracking"""
    from igny8_core.business.billing.services.credit_service import CreditService
    from igny8_core.business.notifications.services import NotificationService
    from igny8_core.ai.models import AITaskLog
    
    # Get account
    account = Account.objects.get(id=account_id)
    
    # Validate
    fn = GenerateImagesFunction()
    validated = fn.validate({'ids': task_ids}, account)
    if not validated['valid']:
        return {'success': False, 'error': validated['error']}
    
    # Prepare
    data = fn.prepare({'ids': task_ids}, account)
    tasks = data['tasks']
    model = data['model']  # e.g., 'dall-e-3'
    
    # Get model config for credits
    from igny8_core.business.billing.models import AIModelConfig
    model_config = AIModelConfig.objects.get(model_name=model, is_active=True)
    
    # Calculate total images to generate
    total_images = 0
    for task in tasks:
        if task.content:
            total_images += 1  # Featured image
            total_images += data.get('max_in_article_images', 0)  # In-article images
    
    # Calculate total credits needed
    total_credits = model_config.credits_per_image * total_images
    
    # CHECK CREDITS FIRST (before any generation)
    if account.credits < total_credits:
        error_msg = f"Insufficient credits. Required: {total_credits}, Available: {account.credits}"
        # Create failed notification
        NotificationService.create_notification(
            account=account,
            notification_type='ai_image_failed',
            message=error_msg,
            related_object_type='task',
            related_object_id=tasks[0].id if tasks else None
        )
        return {'success': False, 'error': error_msg}
    
    # Create AITaskLog for tracking
    task_log = AITaskLog.objects.create(
        account=account,
        function_name='generate_images',
        phase='INIT',
        status='pending',
        payload={'task_ids': task_ids, 'model': model}
    )
    
    ai_core = AICore(account=account)
    images_created = 0
    total_cost_usd = 0.0
    
    try:
        # Process each task
        for task in tasks:
            if not task.content:
                continue
            
            # Extract prompts
            prompts_data = fn.build_prompt({'task': task, **data}, account)
            
            # Generate featured image
            featured_result = ai_core.generate_image(
                prompt=formatted_featured_prompt,
                provider=data['provider'],
                model=model,
                function_name='generate_images'
            )
            
            if featured_result.get('url'):
                # Save image
                fn.save_output(
                    {'url': featured_result['url'], 'image_type': 'featured'},
                    {'task': task, **data},
                    account
                )
                images_created += 1
                total_cost_usd += float(featured_result.get('cost', 0))
            
            # Generate in-article images (if configured)
            # ... similar logic ...
        
        # DEDUCT CREDITS (with usage log and cost)
        from igny8_core.business.billing.services.credit_service import CreditService
        from igny8_core.business.billing.models import BillingConfiguration
        
        # Calculate actual credits used (based on images generated)
        credits_used = images_created * model_config.credits_per_image
        
        # Calculate cost per credit for usage log
        billing_config = BillingConfiguration.get_instance()
        cost_per_credit = billing_config.default_credit_price_usd
        total_cost_for_log = float(credits_used) * float(cost_per_credit)
        
        # Deduct credits (creates CreditTransaction, CreditUsageLog)
        CreditService.deduct_credits_for_image(
            account=account,
            model_name=model,
            num_images=images_created,
            description=f"Generated {images_created} images for {len(tasks)} tasks",
            metadata={
                'task_ids': task_ids,
                'images_created': images_created,
                'model': model
            },
            cost_usd=total_cost_usd,  # Actual AI provider cost
            related_object_type='task',
            related_object_id=tasks[0].id if tasks else None
        )
        
        # Update AITaskLog
        task_log.status = 'success'
        task_log.phase = 'DONE'
        task_log.cost = total_cost_usd
        task_log.result = {
            'images_created': images_created,
            'credits_used': credits_used,
            'tasks_processed': len(tasks)
        }
        task_log.save()
        
        # Create success notification
        NotificationService.create_notification(
            account=account,
            notification_type='ai_image_success',
            message=f'Generated {images_created} images using {credits_used} credits',
            metadata={
                'images_created': images_created,
                'credits_used': credits_used,
                'tasks_processed': len(tasks)
            },
            related_object_type='task',
            related_object_id=tasks[0].id if tasks else None
        )
        
        return {
            'success': True,
            'images_created': images_created,
            'credits_used': credits_used,
            'cost_usd': total_cost_usd,
            'message': f'Generated {images_created} images'
        }
        
    except Exception as e:
        # Update task log with error
        task_log.status = 'error'
        task_log.error = str(e)
        task_log.save()
        
        # Create failed notification
        NotificationService.create_notification(
            account=account,
            notification_type='ai_image_failed',
            message=f'Image generation failed: {str(e)}',
            error=str(e),
            related_object_type='task',
            related_object_id=tasks[0].id if tasks else None
        )
        
        return {'success': False, 'error': str(e)}

Step 1.2: Ensure Notification Types Exist

File: backend/igny8_core/business/notifications/services.py

Check if these notification types are defined:

  • ai_image_success
  • ai_image_failed

If not, add them to the notification type choices.

Phase 2: Test All Image Generation Paths

Test Cases:

  1. Manual image generation via Writer module
  2. Automation image generation
  3. Bulk image generation
  4. Insufficient credits handling
  5. AI provider errors handling

Validation Checks:

  • AITaskLog created for each image generation run
  • Credits deducted correctly based on model config
  • CreditUsageLog created with correct operation_type='image_generation'
  • Cost calculated correctly (provider cost + credit cost)
  • Notifications created for success/failure
  • Frontend credits counter updates in real-time

ISSUE 3: Pause/Cancel Button Colors in Automation

COMPLETED

Problem: Pause/Cancel buttons in automation in-progress panel needed better button colors for clarity.

Fix Applied: Updated button variants from outline to primary for better visibility.

File: frontend/src/components/Automation/CurrentProcessingCardV2.tsx

Current Implementation (CORRECT):

<Button variant="primary" tone="warning" ...>Pause</Button>
<Button variant="primary" tone="success" ...>Resume</Button>
<Button variant="primary" tone="danger" ...>Cancel</Button>

ISSUE 4: Automation Stage Cards - Credits Not Showing During Processing

🔴 CRITICAL - UI Gap

Problem: Credits are not showing in Stage 1, 2, 4, and 5 stage cards when processing, but they DO show in Stage 6 card. Need consistency across all stages.

Root Cause: The StageCard.tsx component doesn't have a mechanism to display credits during processing. Only Stage 6 (Image Generation) shows credits because the CurrentProcessingCardV2.tsx displays currentRun.total_credits_used.

Files to Investigate:

  1. frontend/src/components/Automation/StageCard.tsx - Individual stage cards
  2. frontend/src/components/Automation/CurrentProcessingCardV2.tsx - In-progress panel

Fix Strategy:

  1. Pass credits information to StageCard when stage is active
  2. Display credits consumed during that stage's processing
  3. Fetch real-time credit updates from backend

Implementation:

// In StageCard.tsx - Add credits display
interface StageCardProps {
  // ... existing props
  creditsUsed?: number;        // Credits used by this stage
  creditsPerItem?: number;     // Credit cost per item processed
}

// Display in active state:
{isActive && (
  <div className="mt-2 pt-2 border-t border-brand-200">
    <div className="flex justify-between text-xs">
      <span className="text-brand-600">Credits Used:</span>
      <span className="font-bold text-brand-700">{creditsUsed || 0}</span>
    </div>
  </div>
)}

ISSUE 5: Automation In-Progress Panel - Credits Badge Not Incrementing

🔴 CRITICAL - Real-time UX Issue

Problem: The credits badge in the automation in-progress panel shows 0 and doesn't increment after each stage completes. It should show cumulative credits used during the entire run.

Root Cause: Looking at CurrentProcessingCardV2.tsx, it displays currentRun.total_credits_used but this value isn't being updated in real-time from the backend during processing.

Current Code (Line 297):

<span className="text-base font-bold text-warning-600">{currentRun.total_credits_used}</span>

Fix Strategy:

Option 1: Poll Credit Updates More Frequently

// Add dedicated credit polling
useEffect(() => {
  const pollCredits = async () => {
    try {
      const response = await fetchAPI(`/v1/automation/runs/${runId}/credits/`);
      setCreditsUsed(response.total_credits_used);
    } catch (err) {}
  };
  
  if (currentRun.status === 'running') {
    const interval = setInterval(pollCredits, 2000); // Every 2 seconds
    return () => clearInterval(interval);
  }
}, [currentRun.status, runId]);

Option 2: Include Credits in Processing State Response

Backend should return credits_used_so_far in the processing state endpoint.

Files to Change:

  1. frontend/src/components/Automation/CurrentProcessingCardV2.tsx
  2. backend/igny8_core/business/automation/services/automation_service.py (if needed)

ISSUE 6: WorkflowCompletionWidget - Inconsistent Data Across Pages

🔴 CRITICAL - Data Integrity Issue

Problem: The WorkflowCompletionWidget shows different counts on different pages because it filters by active sector.

Root Cause: The useWorkflowStats() hook uses activeSector from store, which changes per page.

File: frontend/src/hooks/useWorkflowStats.ts

Current Code (Line 151):

const { activeSector } = useSectorStore();
const sectorParam = activeSector?.id ? `&sector_id=${activeSector.id}` : '';

Fix: Remove sector filter - widget should always show site-wide stats.

// Remove sector dependency
const loadStats = useCallback(async () => {
  const siteParam = `&site_id=${activeSite.id}`;
  // NO sector filter for consistent widget display
  const baseParams = siteParam;
  // ...
}, [activeSite?.id]); // Remove activeSector from dependencies

ISSUE 7: Content Calendar and List Not Showing

🔴 CRITICAL - Feature Broken

Problem: Content calendar and content list at /publisher/content-calendar not showing. Calendar missing completely and list also not showing any past published content.

Investigation:

File: frontend/src/pages/Publisher/ContentCalendar.tsx

Current Implementation Analysis:

  • Component fetches ALL content for the site (line 134-145)
  • publishedItems filters for items with external_id (line 110-112)
  • Calendar uses getPublishedItemsForDate() and getScheduledItemsForDate()

Possible Issues:

  1. external_id might not be set on published content
  2. updated_at used as publish date might not be correct
  3. Data fetch might be failing silently

Debug Steps:

console.log('[ContentCalendar] publishedItems:', publishedItems);
console.log('[ContentCalendar] Sample with external_id:', 
  allContent.filter(c => c.external_id));

Fix Strategy:

  1. Verify that published content has external_id set
  2. Check if backend is returning published content correctly
  3. May need to use site_status === 'published' instead of checking external_id

ISSUE 8: Auto-Approve and Auto-Publish on Site Settings

🔴 CRITICAL - Feature Not Functional

Problem: Auto-approve and auto-publish toggles on Site Settings → Publishing tab need to be made functional.

Current State (from code analysis):

Backend Models Exist:

  • PublishingSettings.auto_approval_enabled - in business/integration/models.py:265
  • PublishingSettings.auto_publish_enabled - in business/integration/models.py:271

Backend Service Integration Exists:

  • automation_service.py:1491 - Checks auto_approval_enabled
  • automation_service.py:1632 - Checks auto_publish_enabled and triggers publish

Frontend Implementation Exists:

  • Site Settings Publishing tab has toggles
  • Saves via savePublishingSettings() on toggle change

Issues to Fix:

  1. Backend models exist
  2. Backend service checks the flags
  3. Need to verify data flow is working
  4. Need to verify settings are being loaded correctly

Testing Required:

  1. Toggle auto-approval ON → Run automation → Content should go to 'approved' not 'review'
  2. Toggle auto-publish ON → Content approved → Should trigger publish to WordPress

ISSUE 9: Publishing Settings Save Button

🟡 MEDIUM - UX Improvement

Problem: Limits and Schedule settings in Publishing tab save immediately on change. They should require a Save button click instead. Only the automation toggles should save on toggle.

Current Implementation: File: frontend/src/pages/Sites/Settings.tsx (lines 1025-1100)

// Limits Card - saves on every change (WRONG)
<InputField
  value={publishingSettings.daily_publish_limit}
  onChange={(e) => {
    const value = ...;
    setPublishingSettings({ ...publishingSettings, daily_publish_limit: value });
    // Missing: Should NOT auto-save here
  }}
/>

// Automation Card - saves on toggle (CORRECT for toggles)
<Switch
  checked={publishingSettings.auto_approval_enabled}
  onChange={(checked) => {
    setPublishingSettings(newSettings);
    savePublishingSettings({ auto_approval_enabled: checked }); // ✅ OK for toggles
  }}
/>

Fix Strategy:

  1. Remove immediate save from Limits and Schedule cards
  2. Add a "Save Settings" button at bottom of Publishing tab
  3. Keep toggle-based save for Automation card only

New Code:

// Limits Card - no auto-save
onChange={(e) => {
  setPublishingSettings({ ...publishingSettings, daily_publish_limit: value });
  // Don't call savePublishingSettings here
}}

// Add Save button at bottom
<div className="flex justify-end mt-6">
  <Button 
    variant="primary" 
    onClick={() => savePublishingSettings(publishingSettings)}
    disabled={publishingSettingsSaving}
  >
    {publishingSettingsSaving ? 'Saving...' : 'Save Settings'}
  </Button>
</div>

ISSUE 10: Planner and Writer Pagination

🟡 MEDIUM - Navigation Issue

Problem: Pagination not working properly on all Planner and Writer pages.

Pages Affected:

  • /planner/keywords
  • /planner/clusters
  • /planner/ideas
  • /writer/tasks
  • /writer/drafts
  • /writer/images

Current Implementation: All pages use similar pagination pattern via TablePageTemplate:

  • currentPage state
  • pageSize state
  • setCurrentPage passed to Pagination component

Possible Issues:

  1. Page doesn't reset when filters change
  2. Total count not being calculated correctly
  3. Backend not respecting page parameter

Debug Steps:

  1. Check network tab - verify page param sent correctly
  2. Check response - verify count and results correct
  3. Check setCurrentPage - verify it triggers data reload

Files to Check:

  1. frontend/src/pages/Planner/Keywords.tsx
  2. frontend/src/pages/Planner/Clusters.tsx
  3. frontend/src/pages/Writer/Tasks.tsx
  4. frontend/src/templates/TablePageTemplate.tsx

🟡 MEDIUM - Data Accuracy

Problem: Need to audit footer widgets on all Planner and Writer pages to ensure counts are accurate.

Widgets to Audit:

  1. Credits Widget - Shows credit balance
  2. Quick Stats Widget - Shows items pending/processed
  3. Workflow Completion Widget - Shows pipeline progress

Audit Table Required:

Page Widget Model/API Field Filter/Criteria Status
Keywords Quick Stats Keyword count site_id, status TBD
Clusters Quick Stats Cluster count site_id TBD
Ideas Quick Stats ContentIdea count site_id TBD
Tasks Quick Stats Task count site_id TBD
... ... ... ... ... ...

Investigation Required:

  1. List all widgets shown on each page
  2. Document API endpoint each widget calls
  3. Document filter criteria used
  4. Verify counts match backend reality

ISSUE 12: Usage Logs Cost Calculation Formula

🟡 MEDIUM - Documentation/Clarity

Problem: Need to document the formula/criteria used for cost calculation in Usage Logs page.

Page: /account/usage/logs

Current Implementation: File: frontend/src/pages/account/UsageLogsPage.tsx

The page displays cost_usd from the CreditUsageLog model.

Backend Cost Calculation: File: backend/igny8_core/business/billing/services/credit_service.py

# For text operations (clustering, content, ideas):
credits = tokens_used / tokens_per_credit
cost_usd = credits * credit_price_usd  # From BillingConfiguration

# For image operations:
credits = num_images * credits_per_image  # From AIModelConfig
cost_usd = credits * credit_price_usd

Top Metrics Calculation: The summary stats on the usage page are calculated client-side from loaded logs:

const totalCredits = logs.reduce((sum, log) => sum + log.credits_used, 0);
const totalCost = logs.reduce((sum, log) => sum + parseFloat(log.cost_usd || '0'), 0);

Documentation to Add:

  • Add tooltip/help text explaining cost calculation
  • Show formula in UI: "Cost = Credits Used × Credit Price ($0.XX per credit)"

ISSUE 13: Sites Page - Add Site Button Not Working

🔴 CRITICAL - Core Feature Broken

Problem: Neither the top "Add New Website" button nor the empty state button works on the Sites page.

Investigation Results:

File: frontend/src/pages/Sites/List.tsx

Current Implementation:

// Line 71: State
const [showWelcomeGuide, setShowWelcomeGuide] = useState(false);

// Line 481: Button
<Button 
  onClick={() => setShowWelcomeGuide(!showWelcomeGuide)} 
  ...
>
  Add New Website
</Button>

// Line 527-534: Conditional render
{showWelcomeGuide && (
  <div className="mb-6">
    <WorkflowGuide onSiteAdded={() => {
      loadSites();
      setShowWelcomeGuide(false);
    }} />
  </div>
)}

Root Cause Analysis: The button toggles showWelcomeGuide which should show the WorkflowGuide component. If it's not working:

  1. State toggle might not be working
  2. WorkflowGuide component might not be rendering
  3. Component might have internal errors

Debug Steps:

  1. Add console.log to onClick handler
  2. Check if WorkflowGuide component exists
  3. Check for any JS errors in console

Fix Strategy: If WorkflowGuide isn't appropriate for Sites page:

  • Create dedicated AddSiteModal or AddSiteForm
  • Use similar flow to homepage setup wizard

ISSUE 14: AI Model Names - Branding Update

🟡 MEDIUM - Branding Consistency

Problem: AI model names like "GPT-4", "DALL-E", "Claude" should be replaced with "IGNY8 AI" in user-facing areas (Help page, docs, etc.).

Areas to Update:

Help Page (frontend/src/pages/Help/Help.tsx):

  • Line 263: "Images are generated using AI (DALL-E 3 for premium, Runware for basic)"
  • Should be: "Images are generated using IGNY8 AI (Premium quality or Basic quality)"

Other Locations to Check:

  • /frontend/src/pages/Settings/Publishing.tsx
  • /frontend/src/pages/Billing/Credits.tsx
  • Any tooltip or help text mentioning specific AI models

Guideline:

  • Backend/Admin: Keep technical model names (for configuration)
  • Frontend/User-facing: Use "IGNY8 AI" or quality tier names (Basic, Quality, Premium)

Search Pattern:

grep -r "GPT-4\|DALL-E\|Claude\|OpenAI\|Anthropic" frontend/src/pages/

ISSUE 15: WordPress to Site Terminology

🟡 MEDIUM - Terminology Consistency

Problem: System says "WordPress" in many places where "site" should be used, especially since Shopify and Custom Site integrations are coming.

Context:

  • Integration section: Keep "WordPress" where it refers to WordPress-specific features
  • Global/help text: Use "site" or "your website" instead of "WordPress"

Examples to Fix:

Keep "WordPress":

  • "Connect WordPress" button (integration-specific)
  • "WordPress Integration" settings tab
  • "IGNY8 WP Bridge Plugin" references

Change to "site":

  • "Publish to WordPress" → "Publish to your site"
  • "WordPress sync" → "Site sync" (in general contexts)
  • Help text mentioning WordPress as the only option

Search Pattern:

grep -ri "wordpress" frontend/src/pages/ --include="*.tsx" | grep -v "WordPressIntegration"

Files to Review:

  1. frontend/src/pages/Help/Help.tsx
  2. frontend/src/pages/Settings/Publishing.tsx
  3. frontend/src/pages/legal/Terms.tsx
  4. frontend/src/pages/Billing/Credits.tsx

ISSUE 16: Content View - Image Regeneration

🟢 NEW FEATURE - Enhancement

Problem: Need ability to regenerate images from the content view with:

  • Custom prompt input
  • Option to regenerate from original prompt
  • Option to generate at higher quality tier

Current State:

  • Backend: API endpoint documented but NOT implemented
  • Frontend: No regenerate buttons exist

Implementation Plan:

Backend:

Add regenerate action to ImageViewSet:

# In modules/writer/views.py - ImageViewSet
@action(detail=True, methods=['post'])
def regenerate(self, request, pk=None):
    image = self.get_object()
    custom_prompt = request.data.get('custom_prompt', '')
    quality_tier = request.data.get('quality_tier', image.quality_tier)
    
    # Append custom prompt to original if provided
    prompt = image.prompt
    if custom_prompt:
        prompt = f"{prompt}. {custom_prompt}"
    
    # Check credits for quality tier
    # Generate new image
    # Update image record
    # Return result

Frontend:

Add regenerate button to content view:

// In ContentViewTemplate or similar
<Button
  variant="secondary"
  size="sm"
  onClick={() => setShowRegenerateModal(true)}
>
  <RefreshIcon /> Regenerate Image
</Button>

// Modal with options:
// - Custom prompt textarea
// - Quality tier selector (Basic/Quality/Premium)
// - "Use original prompt" checkbox

Credit Calculation:

  • Show credit cost before regeneration
  • Different costs for different quality tiers

ISSUE 17: Auto-Publish After Stage 7 Approval

🟢 NEW FEATURE - Enhancement

Problem: After Stage 7 (Review) completes and content is approved, need to automatically schedule content for publishing based on auto-publish settings.

Current Flow: Stage 7 → Content status = 'approved' → STOPS

Desired Flow: Stage 7 → Content status = 'approved' → IF auto_publish_enabled → Schedule for next available slot → Publish

Implementation:

Backend (automation_service.py):

After stage 7 completion, add:

# After approving content
if publishing_settings.auto_publish_enabled:
    # Get next available publish slot based on schedule
    next_slot = get_next_publish_slot(site)
    
    # Schedule content
    for content in approved_content:
        content.site_status = 'scheduled'
        content.scheduled_publish_at = next_slot
        content.save()
        next_slot = get_next_slot_after(next_slot, publishing_settings)

Publishing Scheduler:

The existing publishing_scheduler.py task should pick up scheduled content and publish at the scheduled time.

Files to Modify:

  1. backend/igny8_core/business/automation/services/automation_service.py
  2. backend/igny8_core/tasks/publishing_scheduler.py (if needed)

UPDATED IMPLEMENTATION PRIORITY & ORDER

Phase 1: Backend Critical (COMPLETED in v1.7.1)

  1. Issue 1: AIModelConfig AttributeError
  2. Issue 2: Image Generation Credit Tracking
  3. Issue 3: Button Colors (already fixed)

🔄 Phase 2: Automation & Credits (IN PROGRESS)

Estimated Time: 3-4 hours

  1. 🔴 Issue 4: Stage Cards Credits Display (1 hour)

    • Add credits display to all stage cards during processing
    • Match Stage 6 behavior
  2. 🔴 Issue 5: Credits Badge Not Incrementing (1 hour)

    • Poll credits more frequently during automation
    • Update display in real-time
  3. 🔴 Issue 8: Auto-Approve/Auto-Publish (2 hours)

    • Verify backend logic is working
    • Test frontend toggles save correctly
    • Run end-to-end test

🔄 Phase 3: Calendar & Content (IN PROGRESS)

Estimated Time: 2-3 hours

  1. 🔴 Issue 7: Content Calendar Not Showing (1.5 hours)

    • Debug data loading
    • Fix published content display
    • Test both calendar and list views
  2. 🟡 Issue 9: Publishing Settings Save Button (30 min)

    • Separate auto-save for toggles
    • Add Save button for limits/schedule

Phase 4: Widget & Data Consistency

Estimated Time: 2 hours

  1. 🔴 Issue 6: WorkflowWidget Consistency (30 min)

    • Remove sector filter
    • Test across all pages
  2. 🟡 Issue 10: Pagination Issues (1 hour)

    • Debug planner/writer pagination
    • Fix page reset on filter change
  3. 🟡 Issue 11: Footer Widgets Audit (30 min)

    • Document all widgets
    • Verify data accuracy

Phase 5: Sites & Settings

Estimated Time: 1-2 hours

  1. 🔴 Issue 13: Add Site Button (1 hour)

    • Debug WorkflowGuide toggle
    • Fix or replace component
  2. 🟡 Issue 12: Usage Logs Documentation (30 min)

    • Add help text/tooltips
    • Document cost formula

Phase 6: Branding & Terminology

Estimated Time: 1-2 hours

  1. 🟡 Issue 14: AI Model Names (30 min)

    • Replace GPT/DALL-E with IGNY8 AI
    • Update Help page
  2. 🟡 Issue 15: WordPress to Site (1 hour)

    • Audit all "WordPress" text
    • Replace with "site" where appropriate

Phase 7: New Features (If Time Permits)

Estimated Time: 4-6 hours

  1. 🟢 Issue 16: Image Regeneration (3 hours)

    • Backend API implementation
    • Frontend modal with options
  2. 🟢 Issue 17: Auto-Publish After Stage 7 (2 hours)

    • Integrate with automation
    • Use publishing scheduler

ISSUE SUMMARY TABLE

# Issue Priority Status Est. Time
1 AIModelConfig AttributeError DONE -
2 Image Credit Tracking DONE -
3 Button Colors DONE -
4 Stage Cards Credits 🔴 TODO 1h
5 Credits Badge Increment 🔴 TODO 1h
6 Widget Consistency 🔴 TODO 30m
7 Content Calendar 🔴 TODO 1.5h
8 Auto-Approve/Publish 🔴 TODO 2h
9 Publishing Save Button 🟡 TODO 30m
10 Pagination Issues 🟡 TODO 1h
11 Footer Widgets Audit 🟡 TODO 30m
12 Usage Logs Docs 🟡 TODO 30m
13 Add Site Button 🔴 TODO 1h
14 AI Model Names 🟡 TODO 30m
15 WordPress → Site 🟡 TODO 1h
16 Image Regeneration 🟢 NEW 3h
17 Auto-Publish Stage 7 🟢 NEW 2h

Legend:

  • 🔴 CRITICAL - Must fix
  • 🟡 MEDIUM - Should fix
  • 🟢 LOW/NEW - Nice to have
  • COMPLETED

TESTING CHECKLIST

After Each Fix

  • Run backend server without errors
  • Test the specific feature fixed
  • Check browser console for errors
  • Verify no regression in related features

Phase 2 Verification

  • Run automation and verify credits show on all stage cards
  • Verify credits badge increments after each stage
  • Toggle auto-approve ON → Content goes to 'approved'
  • Toggle auto-publish ON → Approved content gets scheduled

Phase 3 Verification

  • Content calendar shows scheduled items
  • Content calendar shows published items
  • Calendar view renders correctly
  • List view shows all content
  • Save button works for limits/schedule

Phase 4-5 Verification

  • Widget shows same counts on all pages
  • Pagination works on all tables
  • Add Site button opens wizard
  • New site can be created

Phase 6 Verification

  • No GPT/DALL-E references in user-facing text
  • "Site" used instead of "WordPress" in generic contexts

SUCCESS CRITERIA

All fixes successful when:

  1. No attribute errors in AI functions
  2. All AI functions log to all 3 locations
  3. Image generation deducts credits correctly
  4. Credits display on all stage cards during processing
  5. Credits badge increments in real-time
  6. Widget shows consistent data across all pages
  7. Content calendar displays scheduled and published content
  8. Auto-approve and auto-publish work correctly
  9. Add Site button works on Sites page
  10. Consistent IGNY8 AI branding throughout
  11. Generic "site" terminology where appropriate

END OF COMPREHENSIVE FIX PLAN v2

Last Updated: January 10, 2026 Total Issues: 17 (3 completed, 14 pending) Critical Issues: 7 pending Estimated Total Time: 15-20 hours

This plan is based on actual codebase analysis and reflects the true state of the system.

Ready for implementation. 🚀