Coverage for baibu/metrics/models.py: 100%

19 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2026-10-06 13:07 +0000

1import uuid 

2 

3from django.db import models 

4from django.utils.translation import gettext_lazy as _ 

5 

6 

7class DailyMetric(models.Model): 

8 """One aggregate count for one day: never text, names or per-user rows. 

9 

10 ``name`` is a metric from ``baibu.metrics.definitions.METRICS``. 

11 ``dimension`` is empty for a plain total, or the value a breakdown is 

12 split by (a language code, a status, ``scope:tier``, a week number). 

13 Retention rows are dated by the first day of the cohort week. 

14 """ 

15 

16 id = models.UUIDField(primary_key=True, default=uuid.uuid7, editable=False) 

17 date = models.DateField(db_index=True) 

18 name = models.CharField(max_length=64) 

19 dimension = models.CharField(max_length=128, blank=True, default="") 

20 value = models.BigIntegerField() 

21 computed_at = models.DateTimeField(auto_now=True) 

22 

23 class Meta: 

24 ordering = ["date", "name", "dimension"] 

25 constraints = [ 

26 models.UniqueConstraint(fields=["date", "name", "dimension"], name="metrics_one_value_per_day"), 

27 ] 

28 indexes = [models.Index(fields=["name", "date"])] 

29 verbose_name = _("Daily metric") 

30 verbose_name_plural = _("Daily metrics") 

31 

32 def __str__(self) -> str: 

33 suffix = f" [{self.dimension}]" if self.dimension else "" 

34 return f"{self.date} {self.name}{suffix}: {self.value}"