diff --git a/backend/=0.27.0 b/backend/=0.27.0 deleted file mode 100644 index 337634e1..00000000 --- a/backend/=0.27.0 +++ /dev/null @@ -1,37 +0,0 @@ -Collecting drf-spectacular - Downloading drf_spectacular-0.29.0-py3-none-any.whl.metadata (14 kB) -Requirement already satisfied: Django>=2.2 in /usr/local/lib/python3.11/site-packages (from drf-spectacular) (5.2.8) -Requirement already satisfied: djangorestframework>=3.10.3 in /usr/local/lib/python3.11/site-packages (from drf-spectacular) (3.16.1) -Collecting uritemplate>=2.0.0 (from drf-spectacular) - Downloading uritemplate-4.2.0-py3-none-any.whl.metadata (2.6 kB) -Collecting PyYAML>=5.1 (from drf-spectacular) - Downloading pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.metadata (2.4 kB) -Collecting jsonschema>=2.6.0 (from drf-spectacular) - Downloading jsonschema-4.25.1-py3-none-any.whl.metadata (7.6 kB) -Collecting inflection>=0.3.1 (from drf-spectacular) - Downloading inflection-0.5.1-py2.py3-none-any.whl.metadata (1.7 kB) -Requirement already satisfied: asgiref>=3.8.1 in /usr/local/lib/python3.11/site-packages (from Django>=2.2->drf-spectacular) (3.10.0) -Requirement already satisfied: sqlparse>=0.3.1 in /usr/local/lib/python3.11/site-packages (from Django>=2.2->drf-spectacular) (0.5.3) -Collecting attrs>=22.2.0 (from jsonschema>=2.6.0->drf-spectacular) - Downloading attrs-25.4.0-py3-none-any.whl.metadata (10 kB) -Collecting jsonschema-specifications>=2023.03.6 (from jsonschema>=2.6.0->drf-spectacular) - Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl.metadata (2.9 kB) -Collecting referencing>=0.28.4 (from jsonschema>=2.6.0->drf-spectacular) - Downloading referencing-0.37.0-py3-none-any.whl.metadata (2.8 kB) -Collecting rpds-py>=0.7.1 (from jsonschema>=2.6.0->drf-spectacular) - Downloading rpds_py-0.28.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.1 kB) -Requirement already satisfied: typing-extensions>=4.4.0 in /usr/local/lib/python3.11/site-packages (from referencing>=0.28.4->jsonschema>=2.6.0->drf-spectacular) (4.15.0) -Downloading drf_spectacular-0.29.0-py3-none-any.whl (105 kB) -Downloading inflection-0.5.1-py2.py3-none-any.whl (9.5 kB) -Downloading jsonschema-4.25.1-py3-none-any.whl (90 kB) -Downloading attrs-25.4.0-py3-none-any.whl (67 kB) -Downloading jsonschema_specifications-2025.9.1-py3-none-any.whl (18 kB) -Downloading pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (806 kB) - ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 806.6/806.6 kB 36.0 MB/s 0:00:00 -Downloading referencing-0.37.0-py3-none-any.whl (26 kB) -Downloading rpds_py-0.28.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (382 kB) -Downloading uritemplate-4.2.0-py3-none-any.whl (11 kB) -Installing collected packages: uritemplate, rpds-py, PyYAML, inflection, attrs, referencing, jsonschema-specifications, jsonschema, drf-spectacular - -Successfully installed PyYAML-6.0.3 attrs-25.4.0 drf-spectacular-0.29.0 inflection-0.5.1 jsonschema-4.25.1 jsonschema-specifications-2025.9.1 referencing-0.37.0 rpds-py-0.28.0 uritemplate-4.2.0 -WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager, possibly rendering your system unusable. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv. Use the --root-user-action option if you know what you are doing and want to suppress this warning. diff --git a/backend/frontend/public/images/ai-images/image_42_1762923342.webp b/backend/frontend/public/images/ai-images/image_42_1762923342.webp deleted file mode 100644 index 38713e0d..00000000 Binary files a/backend/frontend/public/images/ai-images/image_42_1762923342.webp and /dev/null differ diff --git a/backend/igny8_core/modules/writer/migrations/0009_add_content_site_source_fields.py b/backend/igny8_core/modules/writer/migrations/0009_add_content_site_source_fields.py new file mode 100644 index 00000000..97eca950 --- /dev/null +++ b/backend/igny8_core/modules/writer/migrations/0009_add_content_site_source_fields.py @@ -0,0 +1,119 @@ +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('igny8_core_auth', '0008_passwordresettoken_alter_industry_options_and_more'), + ('writer', '0008_change_image_url_to_charfield'), + ] + + operations = [ + migrations.AddField( + model_name='content', + name='source', + field=models.CharField( + choices=[ + ('igny8', 'IGNY8 Generated'), + ('wordpress', 'WordPress Synced'), + ('shopify', 'Shopify Synced'), + ('custom', 'Custom API Synced'), + ], + db_index=True, + default='igny8', + help_text='Source of the content', + max_length=50, + ), + ), + migrations.AddField( + model_name='content', + name='sync_status', + field=models.CharField( + choices=[ + ('native', 'Native IGNY8 Content'), + ('imported', 'Imported from External'), + ('synced', 'Synced from External'), + ], + db_index=True, + default='native', + help_text='Sync status of the content', + max_length=50, + ), + ), + migrations.AddField( + model_name='content', + name='external_id', + field=models.CharField( + blank=True, + help_text='External platform ID', + max_length=255, + null=True, + ), + ), + migrations.AddField( + model_name='content', + name='external_url', + field=models.URLField( + blank=True, + help_text='External platform URL', + null=True, + ), + ), + migrations.AddField( + model_name='content', + name='sync_metadata', + field=models.JSONField( + blank=True, + default=dict, + help_text='Platform-specific sync metadata', + ), + ), + migrations.AddField( + model_name='content', + name='internal_links', + field=models.JSONField( + blank=True, + default=list, + help_text='Internal links added by linker', + ), + ), + migrations.AddField( + model_name='content', + name='linker_version', + field=models.IntegerField( + default=0, + help_text='Version of linker processing', + ), + ), + migrations.AddField( + model_name='content', + name='optimizer_version', + field=models.IntegerField( + default=0, + help_text='Version of optimizer processing', + ), + ), + migrations.AddField( + model_name='content', + name='optimization_scores', + field=models.JSONField( + blank=True, + default=dict, + help_text='Optimization scores (SEO, readability, engagement)', + ), + ), + migrations.AddIndex( + model_name='content', + index=models.Index(fields=['source'], name='igny8_conte_source_idx'), + ), + migrations.AddIndex( + model_name='content', + index=models.Index(fields=['sync_status'], name='igny8_conte_sync_idx'), + ), + migrations.AddIndex( + model_name='content', + index=models.Index(fields=['source', 'sync_status'], name='igny8_conte_source_sync_idx'), + ), + ] + diff --git a/backend/igny8_core/modules/writer/serializers.py b/backend/igny8_core/modules/writer/serializers.py index aeb4f3a9..db1529d7 100644 --- a/backend/igny8_core/modules/writer/serializers.py +++ b/backend/igny8_core/modules/writer/serializers.py @@ -1,5 +1,6 @@ from rest_framework import serializers from django.db import models +from django.core.exceptions import ObjectDoesNotExist from .models import Tasks, Images, Content from igny8_core.business.planning.models import Clusters, ContentIdeas @@ -85,7 +86,7 @@ class TasksSerializer(serializers.ModelSerializer): def _get_content_record(self, obj): try: return obj.content_record - except AttributeError: + except (AttributeError, ObjectDoesNotExist): return None def get_content_html(self, obj):