This commit is contained in:
IGNY8 VPS (Salman)
2025-12-04 10:45:43 +00:00
parent a8c572a996
commit 32dae2a7d5
4 changed files with 480 additions and 198 deletions

View File

@@ -325,16 +325,45 @@ class AutomationViewSet(viewsets.ViewSet):
from igny8_core.business.planning.models import Keywords, Clusters, ContentIdeas
from igny8_core.business.content.models import Tasks, Content, Images
from django.db.models import Count
# Stage 1: Keywords pending clustering
def _counts_by_status(model, extra_filter=None, exclude_filter=None):
"""Return a dict of counts keyed by status and the total for a given model and site."""
qs = model.objects.filter(site=site)
if extra_filter:
qs = qs.filter(**extra_filter)
if exclude_filter:
qs = qs.exclude(**exclude_filter)
# Group by status when available
try:
rows = qs.values('status').annotate(count=Count('id'))
counts = {r['status']: r['count'] for r in rows}
total = sum(counts.values())
except Exception:
# Fallback: count all
total = qs.count()
counts = {'total': total}
return counts, total
# Stage 1: Keywords pending clustering (keep previous "pending" semantics but also return status breakdown)
stage_1_counts, stage_1_total = _counts_by_status(
Keywords,
extra_filter={'disabled': False}
)
# pending definition used by the UI previously (new & not clustered)
stage_1_pending = Keywords.objects.filter(
site=site,
status='new',
cluster__isnull=True,
disabled=False
).count()
# Stage 2: Clusters needing ideas
stage_2_counts, stage_2_total = _counts_by_status(
Clusters,
extra_filter={'disabled': False}
)
stage_2_pending = Clusters.objects.filter(
site=site,
status='new',
@@ -342,21 +371,24 @@ class AutomationViewSet(viewsets.ViewSet):
).exclude(
ideas__isnull=False
).count()
# Stage 3: Ideas ready to queue
stage_3_counts, stage_3_total = _counts_by_status(ContentIdeas)
stage_3_pending = ContentIdeas.objects.filter(
site=site,
status='new'
).count()
# Stage 4: Tasks ready for content generation
# Tasks don't have content FK - check if content exists via task title matching
stage_4_counts, stage_4_total = _counts_by_status(Tasks)
stage_4_pending = Tasks.objects.filter(
site=site,
status='queued'
).count()
# Stage 5: Content ready for image prompts
# We will provide counts per content status and also compute pending as previous (draft with 0 images)
stage_5_counts, stage_5_total = _counts_by_status(Content)
stage_5_pending = Content.objects.filter(
site=site,
status='draft'
@@ -365,62 +397,79 @@ class AutomationViewSet(viewsets.ViewSet):
).filter(
images_count=0
).count()
# Stage 6: Image prompts ready for generation
stage_6_counts, stage_6_total = _counts_by_status(Images)
stage_6_pending = Images.objects.filter(
site=site,
status='pending'
).count()
# Stage 7: Content ready for review
# Provide counts per status for content and keep previous "review" pending count
stage_7_counts, stage_7_total = _counts_by_status(Content)
stage_7_ready = Content.objects.filter(
site=site,
status='review'
).count()
return Response({
'stages': [
{
'number': 1,
'name': 'Keywords → Clusters',
'pending': stage_1_pending,
'type': 'AI'
'type': 'AI',
'counts': stage_1_counts,
'total': stage_1_total
},
{
'number': 2,
'name': 'Clusters → Ideas',
'pending': stage_2_pending,
'type': 'AI'
'type': 'AI',
'counts': stage_2_counts,
'total': stage_2_total
},
{
'number': 3,
'name': 'Ideas → Tasks',
'pending': stage_3_pending,
'type': 'Local'
'type': 'Local',
'counts': stage_3_counts,
'total': stage_3_total
},
{
'number': 4,
'name': 'Tasks → Content',
'pending': stage_4_pending,
'type': 'AI'
'type': 'AI',
'counts': stage_4_counts,
'total': stage_4_total
},
{
'number': 5,
'name': 'Content → Image Prompts',
'pending': stage_5_pending,
'type': 'AI'
'type': 'AI',
'counts': stage_5_counts,
'total': stage_5_total
},
{
'number': 6,
'name': 'Image Prompts → Images',
'pending': stage_6_pending,
'type': 'AI'
'type': 'AI',
'counts': stage_6_counts,
'total': stage_6_total
},
{
'number': 7,
'name': 'Manual Review Gate',
'pending': stage_7_ready,
'type': 'Manual'
'type': 'Manual',
'counts': stage_7_counts,
'total': stage_7_total
}
]
})