diff --git a/src/yak/models.py b/src/yak/models.py index 9f1aa0c..095b6ea 100644 --- a/src/yak/models.py +++ b/src/yak/models.py @@ -4,31 +4,93 @@ import uuid class Status(models.Model): - status = models.CharField( + """ + Defines statuses which are used as columns on a board + """ + # Metadata + order_key = models.SmallIntegerField( + default=0, + ) + + class Meta: + ordering = ["order_key", "name"] + verbose_name_plural = "statuses" + + # Data + name = models.CharField( max_length=16, + unique=True, + ) + + +class Label(models.Model): + """ + Defines labels which are inter-board groupings for tickets + """ + # Metadata + class Meta: + ordering = ["name"] + + # Data + name = models.CharField( + max_length=64, + unique=True, + ) + + +class Lane(models.Model): + """ + Defines "swim-lanes" which are intra-board groupings for tickets + """ + # Metadata + order_key = models.SmallIntegerField( + default=0, + ) + + class Meta: + ordering = ["order_key", "name"] + + # Data + name = models.CharField( + max_length=16, + unique=True, + ) + + +class Board(models.Model): + """ + Defines boards which are the default way of grouping tickets + """ + # Metadata + id = models.UUIDField( primary_key=True, + editable=False, + default=uuid.uuid4, ) order_key = models.SmallIntegerField( default=0, ) class Meta: - ordering = ["order_key", "status"] - verbose_name_plural = "statuses" + ordering = ["order_key", "name"] + + # Data + name = models.CharField( + max_length=16, + unique=True, + ) -class Card(models.Model): +class Ticket(models.Model): + """ + Tickets are the atomic unit of the Kanban boards. + """ + # Metadata id = models.UUIDField( primary_key=True, editable=False, default=uuid.uuid4, ) - title = models.CharField( - max_length=64, - ) - details = models.TextField( - blank=True, - ) created_datetime = models.DateTimeField( editable=False, auto_now_add=True, @@ -38,29 +100,66 @@ class Card(models.Model): on_delete=models.SET_NULL, editable=False, null=True, - related_name="created_cards", + related_name="created_tickets", ) + order_key = models.SmallIntegerField( + default=0, + ) + visible = models.BooleanField( + default=True, + ) + + class Meta: + get_latest_by = "created_date" + order_with_respect_to = "parent" + ordering = ["order_key", "title"] + + # Data + title = models.CharField( + max_length=64, + ) + details = models.TextField( + blank=True, + ) + users = models.ManyToManyField( get_user_model(), blank=True, ) + start_datetime = models.DateTimeField( + blank=True, + ) + end_datetime = models.DateTimeField( + blank=True, + ) + + # Context Data parent = models.ForeignKey( + # Optional parent ticket allows (infinite) heirarchy + # Should tickets be able to have parents from different boards? "self", on_delete=models.CASCADE, blank=True, null=True, related_name="children", ) - relations = models.ManyToManyField( - "self", - blank=True, - ) status = models.ForeignKey( Status, on_delete=models.SET_NULL, null=True, ) - - class Meta: - get_latest_by = "created_date" - order_with_respect_to = "parent" + labels = models.ManyToManyField( + Label, + on_delete=models.SET_NULL, + blank=True, + null=True, + ) + lane = models.ForeignKey( + Lane, + on_delete=models.SET_NULL, + null=True, + ) + board = models.ForeignKey( + Board, + on_delete=models.CASCADE, + )