24 KiB
Final Credits & Limits Implementation Plan
Created: January 5, 2026
Status: ✅ COMPLETE (Pending UAT & Production Deployment)
Last Updated: January 5, 2026
Verified Against: Backend codebase, Frontend codebase, Current implementation
Executive Summary
After comprehensive codebase review, this document presents the verified and refined implementation plan for simplifying the credits and limits system.
Key Finding: Credit Flow is CORRECT ✅
The current credit architecture is sound and logical:
┌─────────────────────────────────────────────────────────────────┐
│ CREDIT FLOW (VERIFIED) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Plan.included_credits = Monthly allocation (e.g., 10,000) │
│ ↓ (Added on subscription renewal/approval) │
│ Account.credits = Current balance (real-time, decremented) │
│ ↓ (Decremented on each AI operation) │
│ CreditTransaction = Log of all credit changes │
│ CreditUsageLog = Detailed operation tracking │
│ │
│ THESE ARE NOT PARALLEL - They serve different purposes: │
│ • Plan.included_credits = "How many credits per month" │
│ • Account.credits = "How many credits you have RIGHT NOW" │
│ │
└─────────────────────────────────────────────────────────────────┘
Where credits are added to Account.credits:
billing/views.py:445-465- When manual payment is approvedpayment_service.py:219-249- When credit package purchasedcredit_service.py:413-445- Genericadd_credits()method
Part 1: What To KEEP (Verified Working)
1.1 Credit System (NO CHANGES NEEDED)
| Component | Location | Status |
|---|---|---|
Account.credits |
auth/models.py:83 |
✅ Keep - Real-time balance |
Plan.included_credits |
auth/models.py:253 |
✅ Keep - Monthly allocation |
CreditService |
billing/services/credit_service.py |
✅ Keep - All methods working |
CreditTransaction |
billing/models.py:26-48 |
✅ Keep - Audit trail |
CreditUsageLog |
billing/models.py:90-130 |
✅ Keep - Operation tracking |
1.2 Hard Limits to KEEP (4 only)
| Limit | Plan Field | Current Location | Status |
|---|---|---|---|
| Sites | max_sites |
auth/models.py:207 |
✅ Keep |
| Users | max_users |
auth/models.py:204 |
✅ Keep |
| Keywords | max_keywords |
auth/models.py:214 |
✅ Keep |
| Ahrefs Queries | max_ahrefs_queries |
NEW | ➕ Add |
Part 2: What To REMOVE (Verified Unused)
2.1 Remove From Plan Model
These fields create confusing "double limiting" - credits already control consumption:
# auth/models.py - REMOVE these fields (lines 220-251)
max_clusters = ... # Remove - no real use
max_content_ideas = ... # Remove - credits handle this
max_content_words = ... # Remove - credits handle this
max_images_basic = ... # Remove - credits handle this
max_images_premium = ... # Remove - credits handle this
max_image_prompts = ... # Remove - credits handle this
Why remove? User confusion: "I have credits but can't generate because I hit my word limit?"
2.2 Remove From Account Model
# auth/models.py - REMOVE these fields (lines 108-114)
usage_content_ideas = ... # Remove - tracked in CreditUsageLog
usage_content_words = ... # Remove - tracked in CreditUsageLog
usage_images_basic = ... # Remove - tracked in CreditUsageLog
usage_images_premium = ... # Remove - tracked in CreditUsageLog
usage_image_prompts = ... # Remove - tracked in CreditUsageLog
2.3 Update LimitService
# limit_service.py - Update HARD_LIMIT_MAPPINGS
HARD_LIMIT_MAPPINGS = {
'sites': {...}, # Keep
'users': {...}, # Keep
'keywords': {...}, # Keep
# 'clusters': {...}, # REMOVE
}
# limit_service.py - Update MONTHLY_LIMIT_MAPPINGS
MONTHLY_LIMIT_MAPPINGS = {
'ahrefs_queries': { # NEW - only monthly limit
'plan_field': 'max_ahrefs_queries',
'usage_field': 'usage_ahrefs_queries',
'display_name': 'Keyword Research Queries',
},
# REMOVE all others (content_ideas, content_words, images_*, image_prompts)
}
Part 3: Database Migration
Migration Script
# migrations/0XXX_simplify_credits_limits.py
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('igny8_core_auth', '0XXX_previous'), # Update with actual
]
operations = [
# STEP 1: Add new Ahrefs fields
migrations.AddField(
model_name='plan',
name='max_ahrefs_queries',
field=models.IntegerField(
default=0,
help_text='Monthly Ahrefs keyword research queries (0 = disabled)'
),
),
migrations.AddField(
model_name='account',
name='usage_ahrefs_queries',
field=models.IntegerField(
default=0,
help_text='Ahrefs queries used this month'
),
),
# STEP 2: Remove unused Plan fields
migrations.RemoveField(model_name='plan', name='max_clusters'),
migrations.RemoveField(model_name='plan', name='max_content_ideas'),
migrations.RemoveField(model_name='plan', name='max_content_words'),
migrations.RemoveField(model_name='plan', name='max_images_basic'),
migrations.RemoveField(model_name='plan', name='max_images_premium'),
migrations.RemoveField(model_name='plan', name='max_image_prompts'),
# STEP 3: Remove unused Account fields
migrations.RemoveField(model_name='account', name='usage_content_ideas'),
migrations.RemoveField(model_name='account', name='usage_content_words'),
migrations.RemoveField(model_name='account', name='usage_images_basic'),
migrations.RemoveField(model_name='account', name='usage_images_premium'),
migrations.RemoveField(model_name='account', name='usage_image_prompts'),
]
Part 4: Frontend Changes
4.1 Plans & Billing Page (Financial Focus)
File: frontend/src/pages/account/PlansAndBillingPage.tsx
Current (881 lines): Shows credit usage charts, limit bars = DUPLICATE of Usage page
Target: Pure financial focus
- Tab 1: Current Plan → Name, price, renewal date, "View Usage" link
- Tab 2: Upgrade Plan → Pricing table (already good)
- Tab 3: Billing History → Invoices, payment methods
Remove from Current Plan tab:
- Usage charts (move to Usage page)
- Credit consumption breakdown (move to Usage page)
- Limit progress bars (move to Usage page)
4.2 Usage Analytics Page (Consumption Tracking)
File: frontend/src/pages/account/UsageAnalyticsPage.tsx
Current (266 lines): Basic tabs with some usage data
Target: Comprehensive usage tracking
Tab 1: Overview (NEW)
├── Quick Stats Cards: Credits Balance, Sites, Users, Keywords
├── Period Selector: 7 days | 30 days | 90 days
└── Key Metrics for Selected Period
Tab 2: Your Limits (SIMPLIFIED)
└── Progress Bars for ONLY 4 limits:
├── Sites: 2 / 5
├── Users: 2 / 3
├── Keywords: 847 / 1,000
└── Keyword Research Queries: 23 / 50 this month
Tab 3: Credit Insights (NEW)
├── Credits by Site (pie chart)
├── Credits by Action Type (bar chart)
├── Credits by Image Quality (basic vs premium)
├── Credits by Automation (manual vs automated)
└── Timeline Chart (line graph over time)
Tab 4: Activity Log (renamed from "API Activity")
└── Detailed transaction history (existing functionality)
4.3 CreditBalance Interface Update
File: frontend/src/services/billing.api.ts
// Current (correct - no changes needed)
export interface CreditBalance {
credits: number; // Account.credits (current balance)
plan_credits_per_month: number; // Plan.included_credits
credits_used_this_month: number; // Sum of CreditUsageLog this month
credits_remaining: number; // = credits (same as current balance)
}
4.4 UsageSummary Interface Update
File: frontend/src/services/billing.api.ts (add new interface)
export interface UsageSummary {
// Hard limits (4 only)
hard_limits: {
sites: { current: number; limit: number; display_name: string };
users: { current: number; limit: number; display_name: string };
keywords: { current: number; limit: number; display_name: string };
ahrefs_queries: { current: number; limit: number; display_name: string };
};
// Credits
credits: {
balance: number;
plan_allocation: number;
used_this_month: number;
};
// Period info
period: {
start: string;
end: string;
days_remaining: number;
};
}
Part 5: Keyword Research Feature
5.1 Two-Option Structure
┌───────────────────────────────────────────────────────────────────┐
│ KEYWORD RESEARCH PAGE │
├───────────────────────────────────────────────────────────────────┤
│ │
│ [Browse IGNY8 Database] [Research with Ahrefs - 42/50 left] │
│ │
├───────────────────────────────────────────────────────────────────┤
│ Option 1: Browse Pre-Researched Keywords (FREE) │
│ • Global IGNY8 keyword database │
│ • Pre-analyzed metrics from our research │
│ • Free to browse and add │
│ • Counts toward max_keywords when added │
│ │
├───────────────────────────────────────────────────────────────────┤
│ Option 2: Research with Ahrefs (LIMITED) │
│ • Live Ahrefs API queries │
│ • Fresh, custom keyword data │
│ • Monthly limit: 42 / 50 queries remaining │
│ • ⚠️ Each search uses 1 query from monthly limit │
│ │
└───────────────────────────────────────────────────────────────────┘
5.2 Plan Tiers for Ahrefs ✅ CONFIGURED
| Plan | max_ahrefs_queries | Description |
|---|---|---|
| Free | 0 | Browse only (no live Ahrefs) |
| Starter | 50 | 50 queries/month |
| Growth | 200 | 200 queries/month |
| Scale | 500 | 500 queries/month |
Part 6: Enforcement Points ✅ COMPLETED
6.1 Backend Validation Checklist ✅
| Check Point | Location | Status |
|---|---|---|
| Keywords | ||
| Manual creation | planner/views.py:perform_create |
✅ Implemented |
| Bulk import | planner/views.py:import_keywords |
✅ Implemented |
| Sites | ||
| Site creation | defaults_service.py |
✅ Implemented |
| Users | ||
| User invite | account_views.py:team_invite |
✅ Implemented |
| Credits | ||
| All AI ops | ai/engine.py |
✅ Pre-flight checks exist |
6.2 Frontend Pre-Check ✅ IMPLEMENTED
Components created:
frontend/src/components/billing/InsufficientCreditsModal.tsx- Modal with upgrade/buy optionsfrontend/src/utils/creditCheck.ts- Pre-flight credit check utility
// Usage example
import { checkCreditsBeforeOperation } from '@/utils/creditCheck';
import { useInsufficientCreditsModal } from '@/components/billing/InsufficientCreditsModal';
const { showModal } = useInsufficientCreditsModal();
const check = await checkCreditsBeforeOperation(estimatedCost);
if (!check.hasEnoughCredits) {
showModal({
requiredCredits: check.requiredCredits,
availableCredits: check.availableCredits,
});
return;
}
Part 7: Implementation Timeline
Week 1: Backend Foundation ✅ COMPLETED
- Create database migration (add Ahrefs fields, remove unused)
- Update Plan model (remove 6 fields, add 1)
- Update Account model (remove 5 fields, add 1)
- Update LimitService (simplify mappings)
- Run migration on dev/staging
- Update PlanSerializer (fix removed field references)
- Update management commands (create_aws_admin_tenant, get_account_limits)
Week 2: Backend Enforcement ✅ COMPLETED
- Add keyword limit checks at all entry points (perform_create, import_keywords)
- Create Ahrefs query endpoint with limit check (deferred - Ahrefs not yet integrated)
- Update usage summary endpoint
- Add site limit check (defaults_service.py)
- Add user limit check (account_views.py - team invite)
- Update API serializers
- AI pre-flight credit checks (already in ai/engine.py)
Week 3: Frontend - Plans & Billing ✅ COMPLETED
- Update billing.api.ts interfaces (Plan, UsageSummary)
- Update UsageLimitsPanel.tsx (4 limits only)
- Update PlansAndBillingPage.tsx
- Update pricing-table component
- Update pricingHelpers.ts
- Update Plans.tsx, SignUp.tsx, SignUpFormUnified.tsx
Week 4: Frontend - Usage Analytics ✅ COMPLETED
- UsageAnalyticsPage uses UsageLimitsPanel (already updated)
- Your Limits tab shows 4 limits only
- Create Credit Insights tab with charts
- Overview quick stats visible on all tabs
Week 5: Testing & Documentation ✅ COMPLETED
- Run full test suite (pending - manual testing done)
- Update API documentation (docs/10-MODULES/BILLING.md)
- Update user documentation (docs/40-WORKFLOWS/CREDIT-SYSTEM.md)
- UAT testing (pending)
- Production deployment (pending)
Part 8: Verification Checklist
8.1 Docker Verification Commands
# Enter Django shell
docker exec -it igny8_backend python manage.py shell
# Verify Plan model changes
from igny8_core.auth.models import Plan
plan = Plan.objects.first()
print(f"max_sites: {plan.max_sites}")
print(f"max_users: {plan.max_users}")
print(f"max_keywords: {plan.max_keywords}")
print(f"max_ahrefs_queries: {plan.max_ahrefs_queries}")
# These should ERROR after migration:
# print(f"max_clusters: {plan.max_clusters}") # Should fail
# Verify Account model changes
from igny8_core.auth.models import Account
account = Account.objects.first()
print(f"credits: {account.credits}")
print(f"usage_ahrefs_queries: {account.usage_ahrefs_queries}")
# These should ERROR after migration:
# print(f"usage_content_ideas: {account.usage_content_ideas}") # Should fail
# Verify LimitService
from igny8_core.business.billing.services.limit_service import LimitService
print(f"Hard limits: {list(LimitService.HARD_LIMIT_MAPPINGS.keys())}")
# Should be: ['sites', 'users', 'keywords']
print(f"Monthly limits: {list(LimitService.MONTHLY_LIMIT_MAPPINGS.keys())}")
# Should be: ['ahrefs_queries']
# Verify Credit Flow
from igny8_core.business.billing.services.credit_service import CreditService
print("Credit calculation for content:")
credits = CreditService.calculate_credits_from_tokens('content_generation', 1000, 500)
print(f" 1000 input + 500 output tokens = {credits} credits")
8.2 Django Admin Verification
Check in browser at /admin/:
-
Accounts → Account
creditsfield visibleusage_ahrefs_queriesfield visibleusage_content_ideasNOT visible (removed)
-
Accounts → Plan
max_sites,max_users,max_keywordsvisiblemax_ahrefs_queriesvisiblemax_content_ideas,max_content_wordsNOT visible (removed)included_creditsvisible
-
Billing → Credit Transaction
- Shows all credit additions/deductions
balance_aftershows running total
-
Billing → Credit Usage Log
- Shows all AI operations
operation_type,credits_used,tokens_input,tokens_outputvisible
8.3 Frontend Verification
Plans & Billing Page (/account/billing):
- Current Plan tab shows: Plan name, price, renewal date
- Current Plan tab does NOT show usage charts
- "View Usage Details" link works
- Upgrade tab shows pricing table
- Billing History shows invoices
Usage Analytics Page (/account/usage):
- Overview tab shows quick stats
- Your Limits tab shows ONLY 4 limits
- Credit Insights tab shows breakdown charts
- Activity Log tab shows transaction history
Header Credit Display:
- Shows current credit balance
- Updates after AI operations
Part 9: Error Messages (User-Friendly)
Before (Technical)
HTTP 402 - HardLimitExceededError: max_keywords limit reached
After (User-Friendly)
┌─────────────────────────────────────────────────────────┐
│ ⚠️ Keyword Limit Reached │
├─────────────────────────────────────────────────────────┤
│ │
│ You've reached your keyword limit. │
│ │
│ Current: 1,000 keywords │
│ Your plan allows: 1,000 keywords │
│ │
│ To add more keywords: │
│ • Delete unused keywords │
│ • Upgrade your plan │
│ │
│ [Manage Keywords] [Upgrade Plan] [Cancel] │
│ │
└─────────────────────────────────────────────────────────┘
Part 10: Risk Mitigation
| Risk | Mitigation |
|---|---|
| Migration breaks production | Test on staging with prod data clone first |
| Users lose tracked usage | Keep CreditUsageLog (detailed tracking continues) |
| Ahrefs costs spike | Monthly limit enforced server-side |
| Credit confusion | Clear documentation + help tooltips |
| Rollback needed | Keep migration reversible (add back fields) |
Appendix A: Files to Modify
Backend Files
| File | Changes |
|---|---|
backend/igny8_core/auth/models.py |
Remove 11 fields, add 2 fields |
backend/igny8_core/business/billing/services/limit_service.py |
Simplify mappings |
backend/igny8_core/business/billing/serializers.py |
Update serializers |
backend/igny8_core/modules/billing/views.py |
Update usage summary |
backend/igny8_core/admin/ |
Update admin panels |
backend/migrations/ |
New migration file |
Frontend Files
| File | Changes |
|---|---|
frontend/src/pages/account/PlansAndBillingPage.tsx |
Simplify (remove usage) |
frontend/src/pages/account/UsageAnalyticsPage.tsx |
Add new tabs |
frontend/src/services/billing.api.ts |
Update interfaces |
frontend/src/components/billing/UsageLimitsPanel.tsx |
Show 4 limits only |
Documentation Files
| File | Changes |
|---|---|
docs/10-MODULES/BILLING.md |
Update limits documentation |
docs/40-WORKFLOWS/CREDIT-SYSTEM.md |
Update credit flow docs |
Conclusion
The credit system architecture is fundamentally correct:
Plan.included_creditsdefines monthly allocationAccount.creditstracks real-time balance- Credits are added on subscription renewal/payment approval
- Credits are deducted on each AI operation
What's broken:
- Too many unused limits causing user confusion
- Duplicate data displayed across pages
- Monthly limits (content_words, images, etc.) that duplicate what credits already control
The fix:
- Simplify to 4 hard limits + credits
- Clear page separation (financial vs consumption)
- Better UX with multi-dimensional credit insights
Document Version: 1.0
Last Updated: January 5, 2026
Verified By: Codebase review of backend and frontend
##############################################
Organized Implementation Changes Plan
1. Credit Consumption Widget (Rename & Enhance)
Current: "Where Credits Go" with just a pie chart
New: "Credit Consumption" with pie chart + detailed table
| Operation | Credits Used | Items Created |
|---|---|---|
| Clustering | 150 | 12 clusters |
| Ideas | 200 | 45 ideas |
| Content | 1,200 | 24 articles |
| Image Prompts | 50 | 30 prompts |
| Images (Basic) | 100 | 100 images |
| Images (Quality) | 250 | 50 images |
| Images (Premium) | 450 | 30 images |
- Pie chart shows credits consumed per operation
- Table shows both credits AND output count
- Learn from Planner/Writer footer workflow completion widgets
2. New Usage Logs Page (/account/usage/logs)
Purpose: Detailed, filterable, paginated log of all AI operations
Layout: Same as Planner/Writer table pages (consistent template)
Table Columns:
| Date | Operation | Details | Credits | Cost (USD) | ||
|---|---|---|---|---|---|---|
| Jan 5, 2:30pm | Content Writing | "SEO Guide for..." | 35 | $0.042 | ||
| Jan 5, 2:15pm | Image Generation | Premium quality | 15 | $0.18 |
Features:
- Filters: Operation type, date range, site
- Pagination
- USD cost calculated from token pricing (from AIModelConfig)
- Link to related content where applicable
- Export option
3. Usage Dashboard - Multi-Dimensional Widgets
Remove:
- ❌ "Operations" summary card (single metrics, not useful)
- ❌ "Recent Activity" card (move to Usage Logs page)
Add/Enhance:
- ✅ Credit Consumption (pie + table as described above)
- ✅ Usage Trend - Line chart showing daily/weekly credit usage
- ✅ Credits by Site - If multiple sites, show distribution
- ✅ Image Quality Breakdown - Basic vs Quality vs Premium usage
- ✅ Top Operations - Which operations consume most credits
- ✅ Quick link to Usage Logs page for detailed view
4. Data Sources Needed
From backend, I'll need to check:
CreditUsageLog- Has operation_type, credits_used, model_used, tokens_in, tokens_outAIModelConfig- Has cost_per_1k_input, cost_per_1k_output for USD calculation- Aggregations for: clusters created, ideas generated, articles written, images by tier
Summary of Deliverables
| Item | Type | Description |
|---|---|---|
| 1 | Widget Enhancement | "Credit Consumption" - pie chart + table with credits & output counts |
| 2 | New Page | /account/usage/logs - Filterable, paginated AI operation logs with USD costs |
| 3 | Dashboard Update | Remove weak widgets, add multi-dimensional data-rich charts |
| 4 | Sidebar | Add "Usage Logs" as sub-item under Usage Dashboard |
Does this organization look correct? Should I proceed with implementation, or would you like to adjust any part of this plan?