HH/apps/social/models.py
2025-12-24 12:42:31 +03:00

139 lines
4.0 KiB
Python

"""
Social models - Social media monitoring and sentiment analysis
This module implements social media monitoring that:
- Tracks mentions across platforms
- Analyzes sentiment
- Creates PX actions for negative mentions
- Monitors brand reputation
"""
from django.db import models
from apps.core.models import TimeStampedModel, UUIDModel
class SocialPlatform(models.TextChoices):
"""Social media platform choices"""
TWITTER = 'twitter', 'Twitter/X'
FACEBOOK = 'facebook', 'Facebook'
INSTAGRAM = 'instagram', 'Instagram'
LINKEDIN = 'linkedin', 'LinkedIn'
YOUTUBE = 'youtube', 'YouTube'
TIKTOK = 'tiktok', 'TikTok'
OTHER = 'other', 'Other'
class SentimentType(models.TextChoices):
"""Sentiment analysis result choices"""
POSITIVE = 'positive', 'Positive'
NEUTRAL = 'neutral', 'Neutral'
NEGATIVE = 'negative', 'Negative'
class SocialMention(UUIDModel, TimeStampedModel):
"""
Social media mention - tracks mentions of hospital/brand.
Negative sentiment triggers PX action creation.
"""
# Platform and source
platform = models.CharField(
max_length=50,
choices=SocialPlatform.choices,
db_index=True
)
post_url = models.URLField(max_length=1000)
post_id = models.CharField(
max_length=200,
unique=True,
db_index=True,
help_text="Unique post ID from platform"
)
# Author information
author_username = models.CharField(max_length=200)
author_name = models.CharField(max_length=200, blank=True)
author_followers = models.IntegerField(null=True, blank=True)
# Content
content = models.TextField()
content_ar = models.TextField(blank=True, help_text="Arabic translation if applicable")
# Organization
hospital = models.ForeignKey(
'organizations.Hospital',
on_delete=models.CASCADE,
null=True,
blank=True,
related_name='social_mentions'
)
department = models.ForeignKey(
'organizations.Department',
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='social_mentions'
)
# Sentiment analysis
sentiment = models.CharField(
max_length=20,
choices=SentimentType.choices,
null=True,
blank=True,
db_index=True
)
sentiment_score = models.DecimalField(
max_digits=5,
decimal_places=2,
null=True,
blank=True,
help_text="Sentiment score (-1 to 1, or 0-100 depending on AI service)"
)
sentiment_analyzed_at = models.DateTimeField(null=True, blank=True)
# Engagement metrics
likes_count = models.IntegerField(default=0)
shares_count = models.IntegerField(default=0)
comments_count = models.IntegerField(default=0)
# Timestamps
posted_at = models.DateTimeField(db_index=True)
collected_at = models.DateTimeField(auto_now_add=True)
# Response tracking
responded = models.BooleanField(default=False)
response_text = models.TextField(blank=True)
responded_at = models.DateTimeField(null=True, blank=True)
responded_by = models.ForeignKey(
'accounts.User',
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='social_responses'
)
# Action tracking
action_created = models.BooleanField(default=False)
px_action = models.ForeignKey(
'px_action_center.PXAction',
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name='social_mentions'
)
# Metadata
metadata = models.JSONField(default=dict, blank=True)
class Meta:
ordering = ['-posted_at']
indexes = [
models.Index(fields=['platform', '-posted_at']),
models.Index(fields=['sentiment', '-posted_at']),
models.Index(fields=['hospital', 'sentiment', '-posted_at']),
]
def __str__(self):
return f"{self.platform} - {self.author_username} - {self.posted_at.strftime('%Y-%m-%d')}"