feat: add community contribution ranks

This commit is contained in:
2026-09-29 22:18:57 +03:30
parent 0f6220f72c
commit 77567178ad
46 changed files with 2206 additions and 23 deletions

View File

@@ -0,0 +1,53 @@
import uuid
from django.conf import settings
from django.db import models
from django.db.models import Q
class ContributionLedger(models.Model):
class Activity(models.TextChoices):
ATTENDANCE = "attendance", "Event attendance"
POST = "post", "Published post"
COMMENT = "comment", "Approved comment or reply"
LIKE = "like", "Like given or received"
SAVE = "save", "Save given or received"
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name="contribution_ledger_entries",
)
activity = models.CharField(max_length=20, choices=Activity.choices)
source_type = models.CharField(max_length=32)
source_id = models.CharField(max_length=80)
effect_key = models.CharField(max_length=240, db_index=True)
role = models.CharField(max_length=20)
points = models.IntegerField()
idempotency_key = models.UUIDField(default=uuid.uuid4, unique=True, editable=False)
reversal_of = models.ForeignKey(
"self",
null=True,
blank=True,
on_delete=models.PROTECT,
related_name="reversals",
)
reason = models.CharField(max_length=120, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ["created_at", "id"]
indexes = [
models.Index(fields=["user", "activity"]),
models.Index(fields=["source_type", "source_id"]),
]
constraints = [
models.CheckConstraint(condition=~Q(points=0), name="gamification_nonzero_ledger_points"),
]
class ScoringEpoch(models.Model):
"""The launch boundary for blog scoring; historical blog rows remain unscored."""
id = models.PositiveSmallIntegerField(primary_key=True, default=1, editable=False)
started_at = models.DateTimeField()