Dynavera/apps/domains/models.py

124 lines
4 KiB
Python
Raw Normal View History

from django.db.models import (
CASCADE,
CharField,
FileField,
ForeignKey,
UUIDField,
Model,
TextField,
2025-12-18 23:27:24 +00:00
ManyToManyField,
DateTimeField,
BooleanField,
TextChoices,
)
2025-12-18 23:27:24 +00:00
from django.utils.translation import gettext_lazy as _
from uuid import uuid4
2025-12-18 23:27:24 +00:00
from datetime import timedelta
from django.utils import timezone
from apps.users.models import TimeStampMixin, User
2025-12-18 23:27:24 +00:00
class Organization(TimeStampMixin, Model):
2025-12-18 23:27:24 +00:00
name = CharField(max_length=255, unique=True)
uuid = UUIDField(default=uuid4, editable=False, unique=True)
description = TextField(blank=True, default="")
owner = ForeignKey(User, on_delete=CASCADE, related_name="owned_organizations")
members = ManyToManyField(User, through="OrganizationMembership", related_name="organizations")
class Meta:
verbose_name = _("Organization")
verbose_name_plural = _("Organizations")
def __str__(self) -> str:
return self.name
2025-12-18 23:27:24 +00:00
class OrganizationMembership(TimeStampMixin, Model):
class Role(TextChoices):
EMPLOYER = "employer", _("Employer")
EMPLOYEE = "employee", _("Employee")
user = ForeignKey(User, on_delete=CASCADE, related_name="organization_memberships")
organization = ForeignKey(Organization, on_delete=CASCADE, related_name="memberships")
role = CharField(max_length=50, choices=Role.choices, default=Role.EMPLOYEE)
class Meta:
verbose_name = _("Organization Membership")
verbose_name_plural = _("Organization Memberships")
unique_together = [["user", "organization"]]
def __str__(self) -> str:
return f"{self.user.full_name} - {self.organization.name} ({self.role})"
class InviteToken(TimeStampMixin, Model):
token = UUIDField(default=uuid4, unique=True, editable=False)
organization = ForeignKey(Organization, on_delete=CASCADE, related_name="invite_tokens")
created_by = ForeignKey(User, on_delete=CASCADE, related_name="created_invites")
expires_at = DateTimeField()
used_by = ForeignKey(User, on_delete=CASCADE, null=True, blank=True, related_name="used_invites")
used_at = DateTimeField(null=True, blank=True)
is_active = BooleanField(default=True)
class Meta:
verbose_name = _("Invite Token")
verbose_name_plural = _("Invite Tokens")
def save(self, *args, **kwargs):
if not self.expires_at:
self.expires_at = timezone.now() + timedelta(days=7)
super().save(*args, **kwargs)
def is_valid(self):
return self.is_active and not self.used_by and timezone.now() < self.expires_at
def __str__(self) -> str:
return f"Invite for {self.organization.name} (expires {self.expires_at})"
class Domain(Model):
name = CharField(max_length=255, unique=True)
uuid = UUIDField(default=uuid4, editable=False, unique=True)
description = TextField(blank=True, default="")
organization = ForeignKey(Organization, on_delete=CASCADE, related_name="domains", null=True, blank=True)
members = ManyToManyField(User, through="DomainMembership", related_name="domains")
class Meta:
verbose_name = _("Domain")
verbose_name_plural = _("Domains")
def __str__(self) -> str:
return self.name
2025-12-18 23:27:24 +00:00
class DomainMembership(TimeStampMixin, Model):
user = ForeignKey(User, on_delete=CASCADE, related_name="domain_memberships")
domain = ForeignKey(Domain, on_delete=CASCADE, related_name="memberships")
class Meta:
verbose_name = _("Domain Membership")
verbose_name_plural = _("Domain Memberships")
unique_together = [["user", "domain"]]
def __str__(self) -> str:
return f"{self.user.full_name} - {self.domain.name}"
class Dataset(TimeStampMixin, Model):
domain = ForeignKey(Domain, on_delete = CASCADE, related_name = "datasets")
name = CharField(max_length = 255)
uuid = UUIDField(default = uuid4, editable = False, unique = True)
description = TextField(blank = True, default = "")
created_by = ForeignKey(User, on_delete = CASCADE, related_name = "created_datasets")
datafile = FileField(upload_to = "datasets/")
def __str__(self) -> str:
2025-12-20 22:33:49 +00:00
return f"{self.name} ({self.domain.name})"
Organisation = Organization