31 KiB
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:
- Backend Data Model Inconsistencies (2 issues)
- Missing Credit Tracking & Logging (1 major issue)
- 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.pyline 121 - File:
/backend/igny8_core/modules/billing/serializers.pyline 290
Current Code (WRONG):
# 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):
# 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:
backend/igny8_core/ai/model_registry.py(1 fix)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):
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_successai_image_failed
If not, add them to the notification type choices.
Phase 2: Test All Image Generation Paths
Test Cases:
- ✅ Manual image generation via Writer module
- ✅ Automation image generation
- ✅ Bulk image generation
- ✅ Insufficient credits handling
- ✅ 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
{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:
{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:
frontend/src/components/Automation/CurrentProcessingCardV2.tsxfrontend/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:
// 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:
frontend/src/components/Automation/CurrentProcessingCardV2.tsxfrontend/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:
- Add
onChangehandler, or - Change to
defaultValueif read-only, or - Add
readOnlyprop
Example Fix:
// 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:
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
const { activeSite } = useSiteStore();
const { activeSector } = useSectorStore(); // ❌ PROBLEM: sector changes per page
// Fetch with sector filter
const sectorParam = activeSector?.id ? `§or_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.
// 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 ? `§or_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:
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
viewModestate to switch between views
Possible Issues:
- Route not working
- Component not rendering due to data fetch error
- CSS/visibility issue
- Auth/permission issue
Debug Steps:
// 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:
frontend/src/pages/Publisher/ContentCalendar.tsxfrontend/src/App.tsx(check route)- 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:
-
Check if feature exists:
grep -r "auto.approve" backend/ grep -r "auto_approve" backend/ -
Check scheduling:
grep -r "scheduled_publish" backend/ -
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_contentfield 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_schedulefield 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_atfield
Frontend:
- Add scheduling configuration in site settings
- Show schedule preview
- Display scheduled items in calendar
Files to Investigate:
backend/igny8_core/business/automation/models.py(AutomationConfig)backend/igny8_core/modules/integration/models.py(Site model)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:
// 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:
// In App.tsx
<Route path="*" element={<NotFound />} />
Files to Create/Change:
frontend/src/pages/NotFound.tsx(new file)frontend/src/App.tsx(add route)
IMPLEMENTATION PRIORITY & ORDER
Phase 1: Critical Backend Fixes (MUST FIX FIRST)
Estimated Time: 2-3 hours
-
✅ Issue 1: AIModelConfig AttributeError (30 min)
- Fix field name references
- Test all AI functions
-
✅ 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
-
✅ Issue 6: WorkflowCompletionWidget Data Consistency (30 min)
- Remove sector filter from widget
- Test across all pages
-
✅ Issue 4: Credits Not Updating in Automation (1 hour)
- Add credit balance polling
- Test real-time updates
-
✅ 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
-
✅ Issue 3: Automation Button Colors (15 min)
- Update button variants
- Test visual appearance
-
✅ Issue 5: Console Error - WordPress Form (30 min)
- Fix input onChange handlers
- Test form
-
✅ 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
- ✅ 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:
-- 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:
- No attribute errors in AI functions
- All AI functions log to AITaskLog, Notifications, and CreditUsageLog
- Image generation properly deducts credits based on model config
- Cost calculations appear in usage logs for all operations
- Widget shows consistent data across all pages
- Credits update in real-time during automation
- Button colors provide clear visual feedback
- No console errors on any page
- 404 page is branded and functional
- Auto-approve/scheduling works as configured (TBD after investigation)
ROLLBACK PLAN
If issues occur during implementation:
- Database Changes: None expected (only code changes)
- Code Rollback:
git revert <commit-hash>for each fix - Individual Fix Rollback: Each fix is independent, can be reverted separately
- Testing Database: Use development environment first, verify thoroughly before production
MONITORING POST-DEPLOYMENT
After deployment, monitor:
- Error Logs: Check for AttributeError or other exceptions
- Credit Balance: Monitor for incorrect deductions
- AITaskLog Table: Verify entries being created
- Notification Table: Verify notifications being created
- User Reports: Check for any user-reported issues
- Performance: Monitor API response times (should not degrade)
NOTES FOR IMPLEMENTATION
CRITICAL REMINDERS:
- Test EVERY change before moving to next fix
- Don't break existing functionality - regression test after each fix
- Follow the PRIORITY ORDER - backend fixes first, then frontend
- Verify with database queries - don't just trust logs
- Use git branches - one branch per major fix for easy rollback
- 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. 🚀