This commit is contained in:
alorig
2025-11-18 07:13:34 +05:00
parent 51c3986e01
commit 2074191eee
17 changed files with 2578 additions and 0 deletions

View File

@@ -0,0 +1,54 @@
# Generated manually for Phase 8: Universal Content Types
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('writer', '0010_make_content_task_nullable'),
]
operations = [
migrations.AddField(
model_name='content',
name='entity_type',
field=models.CharField(
choices=[
('blog_post', 'Blog Post'),
('article', 'Article'),
('product', 'Product'),
('service', 'Service Page'),
('taxonomy', 'Taxonomy Page'),
('page', 'Page'),
],
db_index=True,
default='blog_post',
help_text='Type of content entity',
max_length=50
),
),
migrations.AddField(
model_name='content',
name='json_blocks',
field=models.JSONField(
blank=True,
default=list,
help_text='Structured content blocks (for products, services, taxonomies)'
),
),
migrations.AddField(
model_name='content',
name='structure_data',
field=models.JSONField(
blank=True,
default=dict,
help_text='Content structure data (metadata, schema, etc.)'
),
),
migrations.AddIndex(
model_name='content',
index=models.Index(fields=['entity_type'], name='igny8_conte_entity__idx'),
),
]

View File

@@ -217,6 +217,10 @@ class ContentSerializer(serializers.ModelSerializer):
'account_id',
'has_image_prompts',
'has_generated_images',
# Phase 8: Universal Content Types
'entity_type',
'json_blocks',
'structure_data',
]
read_only_fields = ['id', 'generated_at', 'updated_at', 'account_id']

View File

@@ -757,4 +757,252 @@ class ContentViewSet(SiteSectorModelViewSet):
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
request=request
)
@action(detail=False, methods=['post'], url_path='generate_product', url_name='generate_product')
def generate_product(self, request):
"""
Generate product content (Phase 8).
POST /api/v1/writer/content/generate_product/
{
"name": "Product Name",
"description": "Product description",
"features": ["Feature 1", "Feature 2"],
"target_audience": "Target audience",
"primary_keyword": "Primary keyword",
"site_id": 1, // optional
"sector_id": 1 // optional
}
"""
from igny8_core.business.content.services.content_generation_service import ContentGenerationService
from igny8_core.auth.models import Site, Sector
account = getattr(request, 'account', None)
if not account:
return error_response(
error='Account not found',
status_code=status.HTTP_400_BAD_REQUEST,
request=request
)
product_data = request.data
site_id = product_data.get('site_id')
sector_id = product_data.get('sector_id')
site = None
sector = None
if site_id:
try:
site = Site.objects.get(id=site_id, account=account)
except Site.DoesNotExist:
return error_response(
error='Site not found',
status_code=status.HTTP_404_NOT_FOUND,
request=request
)
if sector_id:
try:
sector = Sector.objects.get(id=sector_id, account=account)
except Sector.DoesNotExist:
return error_response(
error='Sector not found',
status_code=status.HTTP_404_NOT_FOUND,
request=request
)
service = ContentGenerationService()
try:
result = service.generate_product_content(
product_data=product_data,
account=account,
site=site,
sector=sector
)
if result.get('success'):
return success_response(
data={'task_id': result.get('task_id')},
message=result.get('message', 'Product content generation started'),
request=request
)
else:
return error_response(
error=result.get('error', 'Product content generation failed'),
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
request=request
)
except Exception as e:
return error_response(
error=str(e),
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
request=request
)
@action(detail=False, methods=['post'], url_path='generate_service', url_name='generate_service')
def generate_service(self, request):
"""
Generate service page content (Phase 8).
POST /api/v1/writer/content/generate_service/
{
"name": "Service Name",
"description": "Service description",
"benefits": ["Benefit 1", "Benefit 2"],
"target_audience": "Target audience",
"primary_keyword": "Primary keyword",
"site_id": 1, // optional
"sector_id": 1 // optional
}
"""
from igny8_core.business.content.services.content_generation_service import ContentGenerationService
from igny8_core.auth.models import Site, Sector
account = getattr(request, 'account', None)
if not account:
return error_response(
error='Account not found',
status_code=status.HTTP_400_BAD_REQUEST,
request=request
)
service_data = request.data
site_id = service_data.get('site_id')
sector_id = service_data.get('sector_id')
site = None
sector = None
if site_id:
try:
site = Site.objects.get(id=site_id, account=account)
except Site.DoesNotExist:
return error_response(
error='Site not found',
status_code=status.HTTP_404_NOT_FOUND,
request=request
)
if sector_id:
try:
sector = Sector.objects.get(id=sector_id, account=account)
except Sector.DoesNotExist:
return error_response(
error='Sector not found',
status_code=status.HTTP_404_NOT_FOUND,
request=request
)
service = ContentGenerationService()
try:
result = service.generate_service_page(
service_data=service_data,
account=account,
site=site,
sector=sector
)
if result.get('success'):
return success_response(
data={'task_id': result.get('task_id')},
message=result.get('message', 'Service page generation started'),
request=request
)
else:
return error_response(
error=result.get('error', 'Service page generation failed'),
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
request=request
)
except Exception as e:
return error_response(
error=str(e),
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
request=request
)
@action(detail=False, methods=['post'], url_path='generate_taxonomy', url_name='generate_taxonomy')
def generate_taxonomy(self, request):
"""
Generate taxonomy page content (Phase 8).
POST /api/v1/writer/content/generate_taxonomy/
{
"name": "Taxonomy Name",
"description": "Taxonomy description",
"items": ["Item 1", "Item 2"],
"primary_keyword": "Primary keyword",
"site_id": 1, // optional
"sector_id": 1 // optional
}
"""
from igny8_core.business.content.services.content_generation_service import ContentGenerationService
from igny8_core.auth.models import Site, Sector
account = getattr(request, 'account', None)
if not account:
return error_response(
error='Account not found',
status_code=status.HTTP_400_BAD_REQUEST,
request=request
)
taxonomy_data = request.data
site_id = taxonomy_data.get('site_id')
sector_id = taxonomy_data.get('sector_id')
site = None
sector = None
if site_id:
try:
site = Site.objects.get(id=site_id, account=account)
except Site.DoesNotExist:
return error_response(
error='Site not found',
status_code=status.HTTP_404_NOT_FOUND,
request=request
)
if sector_id:
try:
sector = Sector.objects.get(id=sector_id, account=account)
except Sector.DoesNotExist:
return error_response(
error='Sector not found',
status_code=status.HTTP_404_NOT_FOUND,
request=request
)
service = ContentGenerationService()
try:
result = service.generate_taxonomy(
taxonomy_data=taxonomy_data,
account=account,
site=site,
sector=sector
)
if result.get('success'):
return success_response(
data={'task_id': result.get('task_id')},
message=result.get('message', 'Taxonomy generation started'),
request=request
)
else:
return error_response(
error=result.get('error', 'Taxonomy generation failed'),
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
request=request
)
except Exception as e:
return error_response(
error=str(e),
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
request=request
)