Phase 0: Remove plan operation limit fields (credit-only system)
- Removed all operation limit fields from Plan model - Kept account management limits (max_users, max_sites, etc.) - Updated PlanSerializer to remove limit fields - Updated PlanAdmin to remove limit fieldsets - Created migration to remove limit fields from database - Plan model now only has credits, billing, and account management fields
This commit is contained in:
@@ -19,21 +19,9 @@ class PlanAdmin(admin.ModelAdmin):
|
|||||||
('Plan Info', {
|
('Plan Info', {
|
||||||
'fields': ('name', 'slug', 'price', 'billing_cycle', 'features', 'is_active')
|
'fields': ('name', 'slug', 'price', 'billing_cycle', 'features', 'is_active')
|
||||||
}),
|
}),
|
||||||
('User / Site Limits', {
|
('Account Management Limits', {
|
||||||
'fields': ('max_users', 'max_sites', 'max_industries', 'max_author_profiles')
|
'fields': ('max_users', 'max_sites', 'max_industries', 'max_author_profiles')
|
||||||
}),
|
}),
|
||||||
('Planner Limits', {
|
|
||||||
'fields': ('max_keywords', 'max_clusters', 'daily_cluster_limit', 'daily_keyword_import_limit', 'monthly_cluster_ai_credits')
|
|
||||||
}),
|
|
||||||
('Writer Limits', {
|
|
||||||
'fields': ('daily_content_tasks', 'daily_ai_requests', 'monthly_word_count_limit', 'monthly_content_ai_credits')
|
|
||||||
}),
|
|
||||||
('Image Limits', {
|
|
||||||
'fields': ('monthly_image_count', 'monthly_image_ai_credits', 'max_images_per_task', 'image_model_choices')
|
|
||||||
}),
|
|
||||||
('AI Controls', {
|
|
||||||
'fields': ('daily_ai_request_limit', 'monthly_ai_credit_limit')
|
|
||||||
}),
|
|
||||||
('Billing & Credits', {
|
('Billing & Credits', {
|
||||||
'fields': ('included_credits', 'extra_credit_price', 'allow_credit_topup', 'auto_credit_topup_threshold', 'auto_credit_topup_amount', 'credits_per_month')
|
'fields': ('included_credits', 'extra_credit_price', 'allow_credit_topup', 'auto_credit_topup_threshold', 'auto_credit_topup_amount', 'credits_per_month')
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
# Generated manually for Phase 0: Remove plan operation limit fields (credit-only system)
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('igny8_core_auth', '0013_remove_ai_cost_per_request'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
# Remove Planner Limits
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='plan',
|
||||||
|
name='max_keywords',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='plan',
|
||||||
|
name='max_clusters',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='plan',
|
||||||
|
name='max_content_ideas',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='plan',
|
||||||
|
name='daily_cluster_limit',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='plan',
|
||||||
|
name='daily_keyword_import_limit',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='plan',
|
||||||
|
name='monthly_cluster_ai_credits',
|
||||||
|
),
|
||||||
|
# Remove Writer Limits
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='plan',
|
||||||
|
name='daily_content_tasks',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='plan',
|
||||||
|
name='daily_ai_requests',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='plan',
|
||||||
|
name='monthly_word_count_limit',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='plan',
|
||||||
|
name='monthly_content_ai_credits',
|
||||||
|
),
|
||||||
|
# Remove Image Generation Limits
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='plan',
|
||||||
|
name='monthly_image_count',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='plan',
|
||||||
|
name='daily_image_generation_limit',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='plan',
|
||||||
|
name='monthly_image_ai_credits',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='plan',
|
||||||
|
name='max_images_per_task',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='plan',
|
||||||
|
name='image_model_choices',
|
||||||
|
),
|
||||||
|
# Remove AI Request Controls
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='plan',
|
||||||
|
name='daily_ai_request_limit',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='plan',
|
||||||
|
name='monthly_ai_credit_limit',
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
@@ -93,8 +93,8 @@ class Account(models.Model):
|
|||||||
|
|
||||||
class Plan(models.Model):
|
class Plan(models.Model):
|
||||||
"""
|
"""
|
||||||
Subscription plan model with comprehensive limits and features.
|
Subscription plan model - Phase 0: Credit-only system.
|
||||||
Plans define limits for users, sites, content generation, AI usage, and billing.
|
Plans define credits, billing, and account management limits only.
|
||||||
"""
|
"""
|
||||||
BILLING_CYCLE_CHOICES = [
|
BILLING_CYCLE_CHOICES = [
|
||||||
('monthly', 'Monthly'),
|
('monthly', 'Monthly'),
|
||||||
@@ -110,7 +110,7 @@ class Plan(models.Model):
|
|||||||
is_active = models.BooleanField(default=True)
|
is_active = models.BooleanField(default=True)
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
# User / Site / Scope Limits
|
# Account Management Limits (kept - not operation limits)
|
||||||
max_users = models.IntegerField(default=1, validators=[MinValueValidator(1)], help_text="Total users allowed per account")
|
max_users = models.IntegerField(default=1, validators=[MinValueValidator(1)], help_text="Total users allowed per account")
|
||||||
max_sites = models.IntegerField(
|
max_sites = models.IntegerField(
|
||||||
default=1,
|
default=1,
|
||||||
@@ -120,32 +120,7 @@ class Plan(models.Model):
|
|||||||
max_industries = models.IntegerField(default=None, null=True, blank=True, validators=[MinValueValidator(1)], help_text="Optional limit for industries/sectors")
|
max_industries = models.IntegerField(default=None, null=True, blank=True, validators=[MinValueValidator(1)], help_text="Optional limit for industries/sectors")
|
||||||
max_author_profiles = models.IntegerField(default=5, validators=[MinValueValidator(0)], help_text="Limit for saved writing styles")
|
max_author_profiles = models.IntegerField(default=5, validators=[MinValueValidator(0)], help_text="Limit for saved writing styles")
|
||||||
|
|
||||||
# Planner Limits
|
# Billing & Credits (Phase 0: Credit-only system)
|
||||||
max_keywords = models.IntegerField(default=1000, validators=[MinValueValidator(0)], help_text="Total keywords allowed (global limit)")
|
|
||||||
max_clusters = models.IntegerField(default=100, validators=[MinValueValidator(0)], help_text="Total clusters allowed (global)")
|
|
||||||
max_content_ideas = models.IntegerField(default=300, validators=[MinValueValidator(0)], help_text="Total content ideas allowed (global limit)")
|
|
||||||
daily_cluster_limit = models.IntegerField(default=10, validators=[MinValueValidator(0)], help_text="Max clusters that can be created per day")
|
|
||||||
daily_keyword_import_limit = models.IntegerField(default=100, validators=[MinValueValidator(0)], help_text="SeedKeywords import limit per day")
|
|
||||||
monthly_cluster_ai_credits = models.IntegerField(default=50, validators=[MinValueValidator(0)], help_text="AI credits allocated for clustering")
|
|
||||||
|
|
||||||
# Writer Limits
|
|
||||||
daily_content_tasks = models.IntegerField(default=10, validators=[MinValueValidator(0)], help_text="Max number of content tasks (blogs) per day")
|
|
||||||
daily_ai_requests = models.IntegerField(default=50, validators=[MinValueValidator(0)], help_text="Total AI executions (content + idea + image) allowed per day")
|
|
||||||
monthly_word_count_limit = models.IntegerField(default=50000, validators=[MinValueValidator(0)], help_text="Monthly word limit (for generated content)")
|
|
||||||
monthly_content_ai_credits = models.IntegerField(default=200, validators=[MinValueValidator(0)], help_text="AI credit pool for content generation")
|
|
||||||
|
|
||||||
# Image Generation Limits
|
|
||||||
monthly_image_count = models.IntegerField(default=100, validators=[MinValueValidator(0)], help_text="Max images per month")
|
|
||||||
daily_image_generation_limit = models.IntegerField(default=25, validators=[MinValueValidator(0)], help_text="Max images that can be generated per day")
|
|
||||||
monthly_image_ai_credits = models.IntegerField(default=100, validators=[MinValueValidator(0)], help_text="AI credit pool for image generation")
|
|
||||||
max_images_per_task = models.IntegerField(default=4, validators=[MinValueValidator(1)], help_text="Max images per content task")
|
|
||||||
image_model_choices = models.JSONField(default=list, blank=True, help_text="Allowed image models (e.g., ['dalle3', 'hidream'])")
|
|
||||||
|
|
||||||
# AI Request Controls
|
|
||||||
daily_ai_request_limit = models.IntegerField(default=100, validators=[MinValueValidator(0)], help_text="Global daily AI request cap")
|
|
||||||
monthly_ai_credit_limit = models.IntegerField(default=500, validators=[MinValueValidator(0)], help_text="Unified credit ceiling per month (all AI functions)")
|
|
||||||
|
|
||||||
# Billing & Add-ons
|
|
||||||
included_credits = models.IntegerField(default=0, validators=[MinValueValidator(0)], help_text="Monthly credits included")
|
included_credits = models.IntegerField(default=0, validators=[MinValueValidator(0)], help_text="Monthly credits included")
|
||||||
extra_credit_price = models.DecimalField(max_digits=10, decimal_places=2, default=0.01, help_text="Price per additional credit")
|
extra_credit_price = models.DecimalField(max_digits=10, decimal_places=2, default=0.01, help_text="Price per additional credit")
|
||||||
allow_credit_topup = models.BooleanField(default=True, help_text="Can user purchase more credits?")
|
allow_credit_topup = models.BooleanField(default=True, help_text="Can user purchase more credits?")
|
||||||
|
|||||||
@@ -11,10 +11,10 @@ class PlanSerializer(serializers.ModelSerializer):
|
|||||||
model = Plan
|
model = Plan
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'name', 'slug', 'price', 'billing_cycle', 'features', 'is_active',
|
'id', 'name', 'slug', 'price', 'billing_cycle', 'features', 'is_active',
|
||||||
'max_users', 'max_sites', 'max_keywords', 'max_clusters', 'max_content_ideas',
|
'max_users', 'max_sites', 'max_industries', 'max_author_profiles',
|
||||||
'monthly_word_count_limit', 'monthly_ai_credit_limit', 'monthly_image_count',
|
'included_credits', 'extra_credit_price', 'allow_credit_topup',
|
||||||
'daily_content_tasks', 'daily_ai_request_limit', 'daily_image_generation_limit',
|
'auto_credit_topup_threshold', 'auto_credit_topup_amount',
|
||||||
'included_credits', 'image_model_choices', 'credits_per_month'
|
'stripe_product_id', 'stripe_price_id', 'credits_per_month'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user