Implement Stage 3: Enhance content metadata and validation features

- Added entity metadata fields to the Tasks model, including entity_type, taxonomy, and cluster_role.
- Updated CandidateEngine to prioritize content relevance based on cluster mappings.
- Introduced metadata completeness scoring in ContentAnalyzer.
- Enhanced validation services to check for entity type and mapping completeness.
- Updated frontend components to display and validate new metadata fields.
- Implemented API endpoints for content validation and metadata persistence.
- Migrated existing data to populate new metadata fields for Tasks and Content.
This commit is contained in:
IGNY8 VPS (Salman)
2025-11-19 19:21:30 +00:00
parent 38f6026e73
commit bae9ea47d8
33 changed files with 2388 additions and 73 deletions

View File

@@ -35,25 +35,77 @@ class ContentAnalyzer:
readability_score = self._calculate_readability_score(content)
engagement_score = self._calculate_engagement_score(content)
# Overall score is weighted average
# Stage 3: Calculate metadata completeness score
metadata_score = self._calculate_metadata_score(content)
# Overall score is weighted average (includes metadata)
overall_score = (
seo_score * 0.4 +
readability_score * 0.3 +
engagement_score * 0.3
seo_score * 0.35 +
readability_score * 0.25 +
engagement_score * 0.25 +
metadata_score * 0.15
)
return {
'seo_score': round(seo_score, 2),
'readability_score': round(readability_score, 2),
'engagement_score': round(engagement_score, 2),
'metadata_score': round(metadata_score, 2), # Stage 3: Add metadata score
'overall_score': round(overall_score, 2),
'word_count': content.word_count or 0,
'has_meta_title': bool(content.meta_title),
'has_meta_description': bool(content.meta_description),
'has_primary_keyword': bool(content.primary_keyword),
'internal_links_count': len(content.internal_links) if content.internal_links else 0
'internal_links_count': len(content.internal_links) if content.internal_links else 0,
# Stage 3: Metadata completeness indicators
'has_entity_type': bool(content.entity_type),
'has_cluster_mapping': self._has_cluster_mapping(content),
'has_taxonomy_mapping': self._has_taxonomy_mapping(content),
}
def _calculate_metadata_score(self, content: Content) -> float:
"""Stage 3: Calculate metadata completeness score (0-100)"""
score = 0
# Entity type (20 points)
if content.entity_type:
score += 20
# Cluster mapping (30 points)
if self._has_cluster_mapping(content):
score += 30
# Taxonomy mapping (30 points) - required for products/services
if self._has_taxonomy_mapping(content):
score += 30
elif content.entity_type in ['product', 'service']:
# Products/services must have taxonomy
score += 0
else:
# Other types get partial credit
score += 15
# Attributes (20 points) - for products
if content.entity_type == 'product':
from igny8_core.business.content.models import ContentAttributeMap
attr_count = ContentAttributeMap.objects.filter(content=content).count()
if attr_count >= 3:
score += 20
elif attr_count >= 1:
score += 10
return min(score, 100)
def _has_cluster_mapping(self, content: Content) -> bool:
"""Stage 3: Check if content has cluster mapping"""
from igny8_core.business.content.models import ContentClusterMap
return ContentClusterMap.objects.filter(content=content).exists()
def _has_taxonomy_mapping(self, content: Content) -> bool:
"""Stage 3: Check if content has taxonomy mapping"""
from igny8_core.business.content.models import ContentTaxonomyMap
return ContentTaxonomyMap.objects.filter(content=content).exists()
def _calculate_seo_score(self, content: Content) -> float:
"""Calculate SEO score (0-100)"""
score = 0