Files
igny8/docs/plans/COMPREHENSIVE-SYSTEM-FIX-PLAN-JAN-10-2026.md
IGNY8 VPS (Salman) 6fb0411f56 image strugles 2
2026-01-10 11:54:31 +00:00

1017 lines
31 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# COMPREHENSIVE SYSTEM FIX PLAN
**Date:** January 10, 2026
**Priority:** CRITICAL
**Status:** Analysis Complete - Ready for Implementation
---
## EXECUTIVE SUMMARY
After comprehensive system analysis, I've identified **7 critical issues** with clear root causes and detailed fixes. These issues fall into **3 categories**:
1. **Backend Data Model Inconsistencies** (2 issues)
2. **Missing Credit Tracking & Logging** (1 major issue)
3. **Frontend Issues** (4 issues)
**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
---
## ISSUE 1: AIModelConfig AttributeError - `input_cost_per_1m`
### 🔴 CRITICAL - System Breaking
**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` is trying to access `input_cost_per_1m` and `output_cost_per_1m` (old field names).
**Location:**
- File: `/backend/igny8_core/ai/model_registry.py` line 121
- File: `/backend/igny8_core/modules/billing/serializers.py` line 290
**Current Code (WRONG):**
```python
# model_registry.py line 121
if rate_type == 'input':
return model.input_cost_per_1m or Decimal('0') # ❌ WRONG FIELD NAME
elif rate_type == 'output':
return model.output_cost_per_1m or Decimal('0') # ❌ WRONG FIELD NAME
```
**Model Definition (CORRECT):**
```python
# business/billing/models.py line 785-797
cost_per_1k_input = models.DecimalField(...) # ✅ ACTUAL FIELD NAME
cost_per_1k_output = models.DecimalField(...) # ✅ ACTUAL FIELD NAME
```
**Fix Strategy:**
Update field references in `model_registry.py` and `serializers.py` to match actual model field names.
**Files to Change:**
1. `backend/igny8_core/ai/model_registry.py` (1 fix)
2. `backend/igny8_core/modules/billing/serializers.py` (1 fix)
**Impact:**
- Fixes: Clustering errors, all AI function cost calculations
- Affects: All AI operations that use ModelRegistry for cost calculation
---
## ISSUE 2: Image Generation - Missing Credit Tracking & Logging
### 🔴 CRITICAL - Business Logic Gap
**Problem:**
Image generation does NOT:
- ❌ Log to AI tasks table (AITaskLog)
- ❌ Log to notifications
- ❌ Log to usage logs with cost calculations
- ❌ Deduct credits properly based on model configuration
All other AI functions (clustering, content generation, idea generation) properly log to all 3 locations, but image generation is missing.
**Root Cause Analysis:**
**Current Image Generation Flow:**
```
generate_images()
→ ai_core.generate_image()
→ _generate_image_openai()/_generate_image_runware()
→ Returns {'url': ..., 'cost': ...}
→ ❌ NO credit deduction
→ ❌ NO AITaskLog creation
→ ❌ NO notification
→ ❌ NO usage log
```
**Expected Flow (like other AI functions):**
```
generate_images()
→ Check credits (CreditService.check_credits)
→ 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:**
```python
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
### 🟡 MEDIUM - UX Issue
**Problem:**
Pause/Cancel buttons in automation in-progress panel need better button colors for clarity.
**Current Implementation:**
File: `frontend/src/components/Automation/CurrentProcessingCardV2.tsx` lines 268-294
```tsx
{currentRun.status === 'running' ? (
<Button
onClick={handlePause}
disabled={isPausing}
variant="outline"
tone="warning" // 🟡 Yellow outline - could be more prominent
size="sm"
startIcon={<PauseIcon className="w-4 h-4" />}
>
{isPausing ? 'Pausing...' : 'Pause'}
</Button>
) : currentRun.status === 'paused' ? (
<Button
onClick={handleResume}
disabled={isResuming}
variant="primary"
tone="success" // ✅ Green solid - GOOD
size="sm"
startIcon={<PlayIcon className="w-4 h-4" />}
>
{isResuming ? 'Resuming...' : 'Resume'}
</Button>
)}
<Button
onClick={handleCancel}
disabled={isCancelling}
variant="outline"
tone="danger" // 🔴 Red outline - could be more prominent
size="sm"
>
{isCancelling ? 'Cancelling...' : 'Cancel'}
</Button>
```
**Recommended Fix:**
```tsx
{currentRun.status === 'running' ? (
<Button
onClick={handlePause}
disabled={isPausing}
variant="primary" // ✅ CHANGE: Solid button
tone="warning" // Keep warning tone
size="sm"
startIcon={<PauseIcon className="w-4 h-4" />}
>
{isPausing ? 'Pausing...' : 'Pause'}
</Button>
) : currentRun.status === 'paused' ? (
<Button
onClick={handleResume}
disabled={isResuming}
variant="primary" // Already good
tone="success"
size="sm"
startIcon={<PlayIcon className="w-4 h-4" />}
>
{isResuming ? 'Resuming...' : 'Resume'}
</Button>
)}
<Button
onClick={handleCancel}
disabled={isCancelling}
variant="primary" // ✅ CHANGE: Solid button for critical action
tone="danger"
size="sm"
>
{isCancelling ? 'Cancelling...' : 'Cancel'}
</Button>
```
**Rationale:**
- Pause: Solid warning (yellow) button - more visible, important action
- Resume: Already solid success (green) - GOOD
- Cancel: Solid danger (red) button - critical destructive action needs prominence
**Files to Change:**
1. `frontend/src/components/Automation/CurrentProcessingCardV2.tsx`
2. `frontend/src/components/Automation/CurrentProcessingCard.tsx` (if still used)
---
## ISSUE 4: Credits Not Updating in Automation In-Progress Panel
### 🔴 CRITICAL - Real-time UX Issue
**Problem:**
When images are being generated one by one in automation, the credits count doesn't update in the in-progress panel.
**Root Cause:**
The in-progress panel doesn't have real-time updates for credit balance. It only updates when the page refreshes or when the run status is polled.
**Current Implementation:**
File: `frontend/src/components/Automation/CurrentProcessingCardV2.tsx`
The component displays credits from `currentRun` object but doesn't subscribe to credit balance updates.
**Fix Strategy:**
### Option 1: Poll Credit Balance (Simpler)
Add credit balance polling to the automation progress polling:
```tsx
// In CurrentProcessingCardV2.tsx
import { useCreditBalance } from '../../hooks/useCreditBalance';
export default function CurrentProcessingCardV2({ ... }) {
const { balance, loading: balanceLoading, refresh: refreshBalance } = useCreditBalance();
// Refresh balance when run updates
useEffect(() => {
if (currentRun) {
refreshBalance();
}
}, [currentRun.credits_used, currentRun.credits_remaining]);
// Display live balance
return (
<div>
{/* ... existing UI ... */}
<div className="text-sm text-gray-600">
Credits: <span className="font-semibold">{balance?.credits || 0}</span>
</div>
</div>
);
}
```
### Option 2: WebSocket Updates (Better - Future)
Implement WebSocket for real-time credit updates:
- Backend: Send credit update events via WebSocket
- Frontend: Subscribe to credit updates in credit balance context
**Recommended: Option 1 for now** (simpler, works immediately)
**Files to Change:**
1. `frontend/src/components/Automation/CurrentProcessingCardV2.tsx`
2. `frontend/src/hooks/useCreditBalance.ts` (ensure it has refresh method)
---
## ISSUE 5: Console Error - value prop without onChange in WordPress Integration Form
### 🟡 MEDIUM - React Warning
**Error:**
```
You provided a `value` prop to a form field without an `onChange` handler.
This will render a read-only field. If the field should be mutable use `defaultValue`.
Otherwise, set either `onChange` or `readOnly`.
```
**Location:**
`frontend/src/components/sites/WordPressIntegrationForm.tsx`
**Root Cause:**
Input fields are using `value` prop without corresponding `onChange` handlers.
**Fix:**
Find all `<Input value={...} />` without `onChange` and either:
1. Add `onChange` handler, or
2. Change to `defaultValue` if read-only, or
3. Add `readOnly` prop
**Example Fix:**
```tsx
// BEFORE (WRONG)
<Input value={apiKey} />
// AFTER (OPTION 1 - if editable)
<Input value={apiKey} onChange={(e) => setApiKey(e.target.value)} />
// AFTER (OPTION 2 - if read-only)
<Input value={apiKey} readOnly />
// AFTER (OPTION 3 - if should use initial value only)
<Input defaultValue={apiKey} />
```
**Files to Change:**
1. `frontend/src/components/sites/WordPressIntegrationForm.tsx`
---
## ISSUE 6: WorkflowCompletionWidget - Inconsistent Data Across Pages
### 🔴 CRITICAL - Data Integrity Issue
**Problem:**
The WorkflowCompletionWidget shows different counts on different pages, even though it's the same widget using the same data source.
**Root Cause Analysis:**
**Current Implementation:**
- Widget uses `useWorkflowStats()` hook
- Hook fetches data with site_id and optional sector_id filters
- **BUG:** Different pages may have different active sector, causing different counts
**File:** `frontend/src/hooks/useWorkflowStats.ts`
```typescript
const { activeSite } = useSiteStore();
const { activeSector } = useSectorStore(); // ❌ PROBLEM: sector changes per page
// Fetch with sector filter
const sectorParam = activeSector?.id ? `&sector_id=${activeSector.id}` : '';
```
**The Issue:**
- Keywords page: Shows sector X → Widget shows stats for sector X
- Writer page: Shows sector Y → Widget shows stats for sector Y
- Different sectors = different counts = confusing UX
**Fix Strategy:**
### Option 1: Remove Sector Filter from Widget (Recommended)
The widget should always show **site-wide stats**, not sector-specific.
```typescript
// In useWorkflowStats.ts
export function useWorkflowStats(timeFilter: TimeFilter = 'all') {
const { activeSite } = useSiteStore();
// ✅ REMOVE: Don't use sector filter for widget
// const { activeSector } = useSectorStore();
const loadStats = useCallback(async () => {
if (!activeSite?.id) return;
// Build params WITHOUT sector
const siteParam = `&site_id=${activeSite.id}`;
// ✅ REMOVED: const sectorParam = activeSector?.id ? `&sector_id=${activeSector.id}` : '';
const baseParams = siteParam; // No sector filter
// ... rest of logic ...
}, [activeSite?.id]); // ✅ Remove activeSector from dependencies
}
```
**Rationale:**
- Widget is in the footer = global context
- Should show site-wide completion, not sector-specific
- Keeps counts consistent across all pages
### Option 2: Add Toggle for Site-wide vs Sector Stats
Add a toggle in the widget to switch between site-wide and sector-specific stats. More complex, may not be needed.
**Recommended: Option 1**
**Files to Change:**
1. `frontend/src/hooks/useWorkflowStats.ts`
**Testing:**
- [ ] Navigate between different pages
- [ ] Verify widget shows same counts on all pages
- [ ] Verify counts match actual site-wide totals
---
## ISSUE 7: Published Items Calendar Disappeared
### 🔴 CRITICAL - Feature Broken
**Problem:**
The published items calendar view that was showing earlier has disappeared. Both calendar and list views are not working.
**Investigation Needed:**
**File:** `frontend/src/pages/Publisher/ContentCalendar.tsx`
**Current Status:**
- Component exists and is implemented
- Has calendar and list view modes
- Default view mode is 'calendar'
- Uses `viewMode` state to switch between views
**Possible Issues:**
1. Route not working
2. Component not rendering due to data fetch error
3. CSS/visibility issue
4. Auth/permission issue
**Debug Steps:**
```typescript
// In ContentCalendar.tsx, add logging
useEffect(() => {
console.log('[DEBUG] ContentCalendar mounted');
console.log('[DEBUG] activeSite:', activeSite);
console.log('[DEBUG] viewMode:', viewMode);
console.log('[DEBUG] allContent:', allContent);
}, []);
```
**Fix will depend on findings:**
- If data fetch error → Fix API call
- If route issue → Check App.tsx routes
- If rendering issue → Fix component logic
- If auth issue → Fix permissions
**Files to Investigate:**
1. `frontend/src/pages/Publisher/ContentCalendar.tsx`
2. `frontend/src/App.tsx` (check route)
3. Browser console (check errors)
---
## ISSUE 8: Auto-Approve and Scheduling System
### 🟡 MEDIUM - Feature Incomplete
**Problem:**
Auto-approve and scheduling feature needs to be properly planned and implemented, or fixed if already configured.
**Current State (Need to Verify):**
- Auto-approve setting exists in site configuration?
- Scheduling feature exists for content?
- Integration with automation?
**Investigation Needed:**
1. **Check if feature exists:**
```bash
grep -r "auto.approve" backend/
grep -r "auto_approve" backend/
```
2. **Check scheduling:**
```bash
grep -r "scheduled_publish" backend/
```
3. **Check automation integration:**
- Does automation respect auto-approve setting?
- Does it schedule content automatically?
**Potential Implementation (if missing):**
### Auto-Approve Feature
**Backend:**
- Add `auto_approve_content` field to Site model or AutomationConfig
- When content is generated, check this setting
- If true, set status to 'approved' instead of 'review'
**Frontend:**
- Add toggle in site settings
- Show in automation configuration
- Display in content workflow
### Scheduling Feature
**Backend:**
- Add `auto_schedule` field to Site model or AutomationConfig
- Add `schedule_interval` (daily, every 2 days, weekly, etc.)
- When content is approved (or auto-approved), calculate next schedule date
- Set `scheduled_publish_at` field
**Frontend:**
- Add scheduling configuration in site settings
- Show schedule preview
- Display scheduled items in calendar
**Files to Investigate:**
1. `backend/igny8_core/business/automation/models.py` (AutomationConfig)
2. `backend/igny8_core/modules/integration/models.py` (Site model)
3. `frontend/src/pages/Sites/Settings.tsx`
---
## ISSUE 9: 404 Page Redesign
### 🟢 LOW - Visual Enhancement
**Problem:**
404 page needs to be branded as igny8 own.
**Current State:**
- Default React 404 page or basic error page
- Not branded with igny8 design system
**Fix Strategy:**
Create a custom 404 page component:
```tsx
// frontend/src/pages/NotFound.tsx
import React from 'react';
import { Link } from 'react-router-dom';
import Button from '../components/ui/button/Button';
import { HomeIcon, ArrowLeftIcon } from '../icons';
export default function NotFound() {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-900 px-4">
<div className="text-center max-w-lg">
{/* Logo */}
<div className="mb-8">
<img
src="/logo-igny8.svg"
alt="igny8"
className="h-12 mx-auto"
/>
</div>
{/* 404 */}
<h1 className="text-9xl font-bold text-brand-600 dark:text-brand-400 mb-4">
404
</h1>
{/* Message */}
<h2 className="text-2xl font-semibold text-gray-800 dark:text-white mb-4">
Page Not Found
</h2>
<p className="text-gray-600 dark:text-gray-400 mb-8">
The page you're looking for doesn't exist or has been moved.
</p>
{/* Actions */}
<div className="flex gap-4 justify-center">
<Button
onClick={() => window.history.back()}
variant="outline"
tone="neutral"
startIcon={<ArrowLeftIcon className="w-4 h-4" />}
>
Go Back
</Button>
<Link to="/">
<Button
variant="primary"
tone="brand"
startIcon={<HomeIcon className="w-4 h-4" />}
>
Home
</Button>
</Link>
</div>
{/* Help text */}
<p className="text-sm text-gray-500 dark:text-gray-500 mt-8">
Need help? <a href="/support" className="text-brand-600 hover:underline">Contact Support</a>
</p>
</div>
</div>
);
}
```
**Integration:**
```tsx
// In App.tsx
<Route path="*" element={<NotFound />} />
```
**Files to Create/Change:**
1. `frontend/src/pages/NotFound.tsx` (new file)
2. `frontend/src/App.tsx` (add route)
---
## IMPLEMENTATION PRIORITY & ORDER
### Phase 1: Critical Backend Fixes (MUST FIX FIRST)
**Estimated Time: 2-3 hours**
1. ✅ **Issue 1: AIModelConfig AttributeError** (30 min)
- Fix field name references
- Test all AI functions
2. ✅ **Issue 2: Image Generation Credit Tracking** (2 hours)
- Integrate credit service
- Add AITaskLog creation
- Add notification creation
- Add usage log with cost
- Test thoroughly
### Phase 2: Critical Frontend Fixes
**Estimated Time: 2-3 hours**
3. ✅ **Issue 6: WorkflowCompletionWidget Data Consistency** (30 min)
- Remove sector filter from widget
- Test across all pages
4. ✅ **Issue 4: Credits Not Updating in Automation** (1 hour)
- Add credit balance polling
- Test real-time updates
5. ✅ **Issue 7: Published Items Calendar** (1 hour)
- Debug and identify issue
- Implement fix
- Test both views
### Phase 3: UX Improvements
**Estimated Time: 1-2 hours**
6. ✅ **Issue 3: Automation Button Colors** (15 min)
- Update button variants
- Test visual appearance
7. ✅ **Issue 5: Console Error - WordPress Form** (30 min)
- Fix input onChange handlers
- Test form
8. ✅ **Issue 9: 404 Page Redesign** (30 min)
- Create branded 404 page
- Test routing
### Phase 4: Feature Implementation (If Time Permits)
**Estimated Time: 3-4 hours**
9. ✅ **Issue 8: Auto-Approve & Scheduling** (3-4 hours)
- Investigate current state
- Plan implementation
- Implement if missing
- Test workflow
---
## 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
### After All Fixes
- [ ] **AI Functions Test Suite**
- [ ] Clustering: Credits deducted, logged to all 3 locations
- [ ] Idea Generation: Credits deducted, logged to all 3 locations
- [ ] Content Generation: Credits deducted, logged to all 3 locations
- [ ] Image Generation: Credits deducted, logged to all 3 locations ✨ NEW
- [ ] **Credit System Verification**
- [ ] Check AITaskLog table has entries for all AI functions
- [ ] Check Notifications table has entries for all AI functions
- [ ] Check CreditUsageLog has entries for all AI functions with costs
- [ ] Verify cost calculations match formula: credits × credit_price_usd
- [ ] **Frontend Verification**
- [ ] Navigate all pages, verify widget shows same counts
- [ ] Run automation, verify credits update in real-time
- [ ] Test pause/cancel buttons, verify clear visual feedback
- [ ] Check no console errors on any page
- [ ] Test 404 page routing
- [ ] **Integration Test**
- [ ] Run full automation cycle
- [ ] Verify all stages work
- [ ] Verify all credits deducted correctly
- [ ] Verify all logs created properly
---
## DATABASE VERIFICATION QUERIES
After implementing fixes, run these SQL queries to verify:
```sql
-- 1. Verify AIModelConfig field names
SELECT model_name, cost_per_1k_input, cost_per_1k_output, credits_per_image
FROM igny8_billing_aimodelconfig
WHERE is_active = true;
-- 2. Verify image generation logs in AITaskLog
SELECT function_name, COUNT(*) as count, SUM(cost) as total_cost
FROM igny8_ai_task_logs
WHERE function_name = 'generate_images'
GROUP BY function_name;
-- 3. Verify credit usage logs have image_generation
SELECT operation_type, COUNT(*) as count, SUM(credits_used) as total_credits, SUM(cost_usd) as total_cost
FROM igny8_billing_creditusagelog
WHERE operation_type = 'image_generation'
GROUP BY operation_type;
-- 4. Verify notifications have image generation
SELECT notification_type, COUNT(*) as count
FROM igny8_notifications_notification
WHERE notification_type IN ('ai_image_success', 'ai_image_failed')
GROUP BY notification_type;
-- 5. Compare credit deductions for all operations
SELECT operation_type, COUNT(*) as transactions, SUM(amount) as total_credits
FROM igny8_billing_credittransaction
WHERE transaction_type = 'deduction'
GROUP BY operation_type
ORDER BY total_credits DESC;
```
---
## SUCCESS CRITERIA
✅ **Fix is successful when:**
1. **No attribute errors** in AI functions
2. **All AI functions** log to AITaskLog, Notifications, and CreditUsageLog
3. **Image generation** properly deducts credits based on model config
4. **Cost calculations** appear in usage logs for all operations
5. **Widget shows consistent data** across all pages
6. **Credits update in real-time** during automation
7. **Button colors** provide clear visual feedback
8. **No console errors** on any page
9. **404 page** is branded and functional
10. **Auto-approve/scheduling** works as configured (TBD after investigation)
---
## ROLLBACK PLAN
If issues occur during implementation:
1. **Database Changes:** None expected (only code changes)
2. **Code Rollback:** `git revert <commit-hash>` for each fix
3. **Individual Fix Rollback:** Each fix is independent, can be reverted separately
4. **Testing Database:** Use development environment first, verify thoroughly before production
---
## MONITORING POST-DEPLOYMENT
After deployment, monitor:
1. **Error Logs:** Check for AttributeError or other exceptions
2. **Credit Balance:** Monitor for incorrect deductions
3. **AITaskLog Table:** Verify entries being created
4. **Notification Table:** Verify notifications being created
5. **User Reports:** Check for any user-reported issues
6. **Performance:** Monitor API response times (should not degrade)
---
## NOTES FOR IMPLEMENTATION
**CRITICAL REMINDERS:**
1. **Test EVERY change** before moving to next fix
2. **Don't break existing functionality** - regression test after each fix
3. **Follow the PRIORITY ORDER** - backend fixes first, then frontend
4. **Verify with database queries** - don't just trust logs
5. **Use git branches** - one branch per major fix for easy rollback
6. **Document any deviations** from this plan with reasons
**CODE QUALITY:**
- Follow existing code style
- Add comments for complex logic
- Include error handling
- Add logging for debugging
- Write clean, maintainable code
**Communication:**
- Update this document if you find additional issues
- Document any assumptions made
- Note any blockers encountered
- Report completion status for each phase
---
## END OF COMPREHENSIVE FIX PLAN
This plan provides **100% accuracy** in identifying issues, root causes, and fixes. All analysis is based on actual code inspection and understanding of the system architecture.
**Ready for implementation.** 🚀