[WEB-5044] fix: ruff lint and format errors (#7868)

* fix: lint errors

* fix: file formatting

* fix: code refactor
This commit is contained in:
sriram veeraghanta 2025-09-29 19:15:32 +05:30 committed by GitHub
parent 1fb22bd252
commit 9237f568dd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
261 changed files with 2199 additions and 6378 deletions

View file

@ -14,9 +14,7 @@ class Command(BaseCommand):
try:
if options["key"]:
cache.delete(options["key"])
self.stdout.write(
self.style.SUCCESS(f"Cache Cleared for key: {options['key']}")
)
self.stdout.write(self.style.SUCCESS(f"Cache Cleared for key: {options['key']}"))
return
cache.clear()

View file

@ -16,12 +16,8 @@ class Command(BaseCommand):
s3_client = boto3.client(
"s3",
endpoint_url=os.environ.get("AWS_S3_ENDPOINT_URL"), # MinIO endpoint
aws_access_key_id=os.environ.get(
"AWS_ACCESS_KEY_ID"
), # MinIO access key
aws_secret_access_key=os.environ.get(
"AWS_SECRET_ACCESS_KEY"
), # MinIO secret key
aws_access_key_id=os.environ.get("AWS_ACCESS_KEY_ID"), # MinIO access key
aws_secret_access_key=os.environ.get("AWS_SECRET_ACCESS_KEY"), # MinIO secret key
region_name=os.environ.get("AWS_REGION"), # MinIO region
config=boto3.session.Config(signature_version="s3v4"),
)
@ -38,32 +34,20 @@ class Command(BaseCommand):
bucket_name = os.environ.get("AWS_S3_BUCKET_NAME")
if error_code == 404:
# Bucket does not exist, create it
self.stdout.write(
self.style.WARNING(
f"Bucket '{bucket_name}' does not exist. Creating bucket..."
)
)
self.stdout.write(self.style.WARNING(f"Bucket '{bucket_name}' does not exist. Creating bucket..."))
try:
s3_client.create_bucket(Bucket=bucket_name)
self.stdout.write(
self.style.SUCCESS(
f"Bucket '{bucket_name}' created successfully."
)
)
self.stdout.write(self.style.SUCCESS(f"Bucket '{bucket_name}' created successfully."))
# Handle the exception if the bucket creation fails
except ClientError as create_error:
self.stdout.write(
self.style.ERROR(f"Failed to create bucket: {create_error}")
)
self.stdout.write(self.style.ERROR(f"Failed to create bucket: {create_error}"))
# Handle the exception if access to the bucket is forbidden
elif error_code == 403:
# Access to the bucket is forbidden
self.stdout.write(
self.style.ERROR(
f"Access to the bucket '{bucket_name}' is forbidden. Check permissions."
)
self.style.ERROR(f"Access to the bucket '{bucket_name}' is forbidden. Check permissions.")
)
else:
# Another ClientError occurred

View file

@ -23,27 +23,20 @@ class Command(BaseCommand):
creator = input("Your email: ")
if creator == "" or not User.objects.filter(email=creator).exists():
raise CommandError(
"User email is required and should have signed in plane"
)
raise CommandError("User email is required and should have signed in plane")
user = User.objects.get(email=creator)
members = input("Enter Member emails (comma separated): ")
members = members.split(",") if members != "" else []
# Create workspace
workspace = Workspace.objects.create(
slug=workspace_slug, name=workspace_name, owner=user
)
workspace = Workspace.objects.create(slug=workspace_slug, name=workspace_name, owner=user)
# Create workspace member
WorkspaceMember.objects.create(workspace=workspace, role=20, member=user)
user_ids = User.objects.filter(email__in=members)
_ = WorkspaceMember.objects.bulk_create(
[
WorkspaceMember(workspace=workspace, member=user_id, role=20)
for user_id in user_ids
],
[WorkspaceMember(workspace=workspace, member=user_id, role=20) for user_id in user_ids],
ignore_conflicts=True,
)
@ -55,9 +48,7 @@ class Command(BaseCommand):
cycle_count = int(input("Number of cycles to be created: "))
module_count = int(input("Number of modules to be created: "))
pages_count = int(input("Number of pages to be created: "))
intake_issue_count = int(
input("Number of intake issues to be created: ")
)
intake_issue_count = int(input("Number of intake issues to be created: "))
from plane.bgtasks.dummy_data_task import create_dummy_data

View file

@ -28,9 +28,7 @@ class Command(BaseCommand):
instance = Instance.objects.last()
# Get or create an instance admin
_, created = InstanceAdmin.objects.get_or_create(
user=user, instance=instance, role=20
)
_, created = InstanceAdmin.objects.get_or_create(user=user, instance=instance, role=20)
if not created:
raise CommandError("The provided email is already an instance admin.")

View file

@ -19,9 +19,7 @@ class Command(BaseCommand):
# Positional argument
parser.add_argument("--project_id", type=str, nargs="?", help="Project ID")
parser.add_argument("--user_email", type=str, nargs="?", help="User Email")
parser.add_argument(
"--role", type=int, nargs="?", help="Role of the user in the project"
)
parser.add_argument("--role", type=int, nargs="?", help="Role of the user in the project")
def handle(self, *args: Any, **options: Any):
try:
@ -46,16 +44,12 @@ class Command(BaseCommand):
raise CommandError("Project not found")
# Check if the user exists in the workspace
if not WorkspaceMember.objects.filter(
workspace=project.workspace, member=user, is_active=True
).exists():
if not WorkspaceMember.objects.filter(workspace=project.workspace, member=user, is_active=True).exists():
raise CommandError("User not member in workspace")
# Get the smallest sort order
smallest_sort_order = (
ProjectMember.objects.filter(workspace_id=project.workspace_id)
.order_by("sort_order")
.first()
ProjectMember.objects.filter(workspace_id=project.workspace_id).order_by("sort_order").first()
)
if smallest_sort_order:
@ -70,17 +64,13 @@ class Command(BaseCommand):
)
else:
# Create the project member
ProjectMember.objects.create(
project=project, member=user, role=role, sort_order=sort_order
)
ProjectMember.objects.create(project=project, member=user, role=role, sort_order=sort_order)
# Issue Property
IssueUserProperty.objects.get_or_create(user=user, project=project)
# Success message
self.stdout.write(
self.style.SUCCESS(f"User {user_email} added to project {project_id}")
)
self.stdout.write(self.style.SUCCESS(f"User {user_email} added to project {project_id}"))
return
except CommandError as e:
self.stdout.write(self.style.ERROR(e))

View file

@ -43,23 +43,15 @@ class Command(BaseCommand):
issue_sequence = self.strict_str_to_int(identifier[1])
# Fetch the project
project = Project.objects.get(
identifier__iexact=project_identifier, workspace__slug=workspace_slug
)
project = Project.objects.get(identifier__iexact=project_identifier, workspace__slug=workspace_slug)
# Get the issues
issues = Issue.objects.filter(project=project, sequence_id=issue_sequence)
# Check if there are duplicate issues
if not issues.count() > 1:
raise CommandError(
"No duplicate issues found with the given identifier"
)
raise CommandError("No duplicate issues found with the given identifier")
self.stdout.write(
self.style.SUCCESS(
f"{issues.count()} issues found with identifier {issue_identifier}"
)
)
self.stdout.write(self.style.SUCCESS(f"{issues.count()} issues found with identifier {issue_identifier}"))
with transaction.atomic():
# This ensures only one transaction per project can execute this code at a time
lock_key = convert_uuid_to_integer(project.id)
@ -70,17 +62,14 @@ class Command(BaseCommand):
cursor.execute("SELECT pg_advisory_xact_lock(%s)", [lock_key])
# Get the maximum sequence ID for the project
last_sequence = IssueSequence.objects.filter(project=project).aggregate(
largest=Max("sequence")
)["largest"]
last_sequence = IssueSequence.objects.filter(project=project).aggregate(largest=Max("sequence"))[
"largest"
]
bulk_issues = []
bulk_issue_sequences = []
issue_sequence_map = {
isq.issue_id: isq
for isq in IssueSequence.objects.filter(project=project)
}
issue_sequence_map = {isq.issue_id: isq for isq in IssueSequence.objects.filter(project=project)}
# change the ids of duplicate issues
for index, issue in enumerate(issues[1:]):

View file

@ -14,10 +14,6 @@ class Command(BaseCommand):
batch_size = input("Enter the batch size: ")
batch_countdown = input("Enter the batch countdown: ")
schedule_issue_description_version.delay(
batch_size=batch_size, countdown=int(batch_countdown)
)
schedule_issue_description_version.delay(batch_size=batch_size, countdown=int(batch_countdown))
self.stdout.write(
self.style.SUCCESS("Successfully created issue description version task")
)
self.stdout.write(self.style.SUCCESS("Successfully created issue description version task"))

View file

@ -12,8 +12,6 @@ class Command(BaseCommand):
batch_size = input("Enter the batch size: ")
batch_countdown = input("Enter the batch countdown: ")
schedule_issue_version.delay(
batch_size=batch_size, countdown=int(batch_countdown)
)
schedule_issue_version.delay(batch_size=batch_size, countdown=int(batch_countdown))
self.stdout.write(self.style.SUCCESS("Successfully created issue version task"))

View file

@ -60,6 +60,4 @@ class Command(BaseCommand):
msg.send()
self.stdout.write(self.style.SUCCESS("Email successfully sent"))
except Exception as e:
self.stdout.write(
self.style.ERROR(f"Error: Email could not be delivered due to {e}")
)
self.stdout.write(self.style.ERROR(f"Error: Email could not be delivered due to {e}"))

View file

@ -16,9 +16,7 @@ class Command(BaseCommand):
"s3",
endpoint_url=os.environ.get("AWS_S3_ENDPOINT_URL"), # MinIO endpoint
aws_access_key_id=os.environ.get("AWS_ACCESS_KEY_ID"), # MinIO access key
aws_secret_access_key=os.environ.get(
"AWS_SECRET_ACCESS_KEY"
), # MinIO secret key
aws_secret_access_key=os.environ.get("AWS_SECRET_ACCESS_KEY"), # MinIO secret key
region_name=os.environ.get("AWS_REGION"), # MinIO region
config=boto3.session.Config(signature_version="s3v4"),
)
@ -59,9 +57,7 @@ class Command(BaseCommand):
# 3. Test s3:PutObject (attempt to upload an object)
try:
s3_client.put_object(
Bucket=bucket_name, Key="test_permission_check.txt", Body=b"Test"
)
s3_client.put_object(Bucket=bucket_name, Key="test_permission_check.txt", Body=b"Test")
permissions["s3:PutObject"] = True
# Clean up
except ClientError as e:
@ -106,9 +102,7 @@ class Command(BaseCommand):
if "Contents" in response:
for obj in response["Contents"]:
object_key = obj["Key"]
public_object_resource.append(
f"arn:aws:s3:::{bucket_name}/{object_key}"
)
public_object_resource.append(f"arn:aws:s3:::{bucket_name}/{object_key}")
bucket_policy = {
"Version": "2012-10-17",
"Statement": [
@ -128,9 +122,7 @@ class Command(BaseCommand):
# Get the bucket policy
bucket_policy = self.generate_bucket_policy(bucket_name)
# Apply the policy to the bucket
s3_client.put_bucket_policy(
Bucket=bucket_name, Policy=json.dumps(bucket_policy)
)
s3_client.put_bucket_policy(Bucket=bucket_name, Policy=json.dumps(bucket_policy))
# Print a success message
self.stdout.write("Bucket is private, but existing objects remain public.")
return
@ -144,11 +136,7 @@ class Command(BaseCommand):
bucket_name = os.environ.get("AWS_S3_BUCKET_NAME")
if not bucket_name:
self.stdout.write(
self.style.ERROR(
"Please set the AWS_S3_BUCKET_NAME environment variable."
)
)
self.stdout.write(self.style.ERROR("Please set the AWS_S3_BUCKET_NAME environment variable."))
return
self.stdout.write(self.style.NOTICE("Checking bucket..."))
@ -158,9 +146,7 @@ class Command(BaseCommand):
except ClientError as e:
error_code = e.response["Error"]["Code"]
if error_code == "404":
self.stdout.write(
self.style.ERROR(f"Bucket '{bucket_name}' does not exist.")
)
self.stdout.write(self.style.ERROR(f"Bucket '{bucket_name}' does not exist."))
return
else:
self.stdout.write(f"Error: {e}")
@ -177,9 +163,7 @@ class Command(BaseCommand):
# If the access key has the required permissions
try:
if all(permissions.values()):
self.stdout.write(
self.style.SUCCESS("Access key has the required permissions.")
)
self.stdout.write(self.style.SUCCESS("Access key has the required permissions."))
# Making the existing objects public
self.make_objects_public(bucket_name)
return
@ -187,18 +171,12 @@ class Command(BaseCommand):
self.stdout.write(f"Error: {e}")
# write the bucket policy to a file
self.stdout.write(
self.style.WARNING(
"Generating permissions.json for manual bucket policy update."
)
)
self.stdout.write(self.style.WARNING("Generating permissions.json for manual bucket policy update."))
try:
# Writing to a file
with open("permissions.json", "w") as f:
f.write(json.dumps(self.generate_bucket_policy(bucket_name)))
self.stdout.write(
self.style.WARNING("Permissions have been written to permissions.json.")
)
self.stdout.write(self.style.WARNING("Permissions have been written to permissions.json."))
return
except IOError as e:
self.stdout.write(f"Error writing permissions.json: {e}")

View file

@ -4,9 +4,7 @@ from plane.db.models import Workspace
class Command(BaseCommand):
help = (
"Updates the slug of a soft-deleted workspace by appending the epoch timestamp"
)
help = "Updates the slug of a soft-deleted workspace by appending the epoch timestamp"
def add_arguments(self, parser):
parser.add_argument(
@ -28,17 +26,13 @@ class Command(BaseCommand):
try:
workspace = Workspace.all_objects.get(slug=slug)
except Workspace.DoesNotExist:
self.stdout.write(
self.style.ERROR(f"Workspace with slug '{slug}' not found.")
)
self.stdout.write(self.style.ERROR(f"Workspace with slug '{slug}' not found."))
return
# Check if the workspace is soft-deleted
if workspace.deleted_at is None:
self.stdout.write(
self.style.WARNING(
f"Workspace '{workspace.name}' (slug: {workspace.slug}) is not deleted."
)
self.style.WARNING(f"Workspace '{workspace.name}' (slug: {workspace.slug}) is not deleted.")
)
return
@ -58,9 +52,7 @@ class Command(BaseCommand):
new_slug = f"{workspace.slug}__{deletion_timestamp}"
if dry_run:
self.stdout.write(
f"Would update workspace '{workspace.name}' slug from '{workspace.slug}' to '{new_slug}'"
)
self.stdout.write(f"Would update workspace '{workspace.name}' slug from '{workspace.slug}' to '{new_slug}'")
else:
try:
with transaction.atomic():
@ -72,8 +64,4 @@ class Command(BaseCommand):
)
)
except Exception as e:
self.stdout.write(
self.style.ERROR(
f"Error updating workspace '{workspace.name}': {str(e)}"
)
)
self.stdout.write(self.style.ERROR(f"Error updating workspace '{workspace.name}': {str(e)}"))

View file

@ -13,9 +13,7 @@ class Command(BaseCommand):
self.stdout.write("Waiting for database migrations to complete...")
time.sleep(10) # wait for 10 seconds before checking again
self.stdout.write(
self.style.SUCCESS("No migrations Pending. Starting processes ...")
)
self.stdout.write(self.style.SUCCESS("No migrations Pending. Starting processes ..."))
def _pending_migrations(self):
connection = connections[DEFAULT_DB_ALIAS]

View file

@ -48,9 +48,7 @@ class SoftDeletionQuerySet(models.QuerySet):
class SoftDeletionManager(models.Manager):
def get_queryset(self):
return SoftDeletionQuerySet(self.model, using=self._db).filter(
deleted_at__isnull=True
)
return SoftDeletionQuerySet(self.model, using=self._db).filter(deleted_at__isnull=True)
class SoftDeleteModel(models.Model):
@ -70,9 +68,7 @@ class SoftDeleteModel(models.Model):
self.deleted_at = timezone.now()
self.save(using=using)
soft_delete_related_objects.delay(
self._meta.app_label, self._meta.model_name, self.pk, using=using
)
soft_delete_related_objects.delay(self._meta.app_label, self._meta.model_name, self.pk, using=using)
else:
# Perform hard delete if soft deletion is not enabled

View file

@ -84,4 +84,4 @@ from .device import Device, DeviceSession
from .sticky import Sticky
from .description import Description, DescriptionVersion
from .description import Description, DescriptionVersion

View file

@ -5,9 +5,7 @@ from .base import BaseModel
class AnalyticView(BaseModel):
workspace = models.ForeignKey(
"db.Workspace", related_name="analytics", on_delete=models.CASCADE
)
workspace = models.ForeignKey("db.Workspace", related_name="analytics", on_delete=models.CASCADE)
name = models.CharField(max_length=255)
description = models.TextField(blank=True)
query = models.JSONField()

View file

@ -24,20 +24,12 @@ class APIToken(BaseModel):
last_used = models.DateTimeField(null=True)
# Token
token = models.CharField(
max_length=255, unique=True, default=generate_token, db_index=True
)
token = models.CharField(max_length=255, unique=True, default=generate_token, db_index=True)
# User Information
user = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="bot_tokens"
)
user_type = models.PositiveSmallIntegerField(
choices=((0, "Human"), (1, "Bot")), default=0
)
workspace = models.ForeignKey(
"db.Workspace", related_name="api_tokens", on_delete=models.CASCADE, null=True
)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="bot_tokens")
user_type = models.PositiveSmallIntegerField(choices=((0, "Human"), (1, "Bot")), default=0)
workspace = models.ForeignKey("db.Workspace", related_name="api_tokens", on_delete=models.CASCADE, null=True)
expired_at = models.DateTimeField(blank=True, null=True)
is_service = models.BooleanField(default=False)

View file

@ -40,27 +40,13 @@ class FileAsset(BaseModel):
attributes = models.JSONField(default=dict)
asset = models.FileField(upload_to=get_upload_path, max_length=800)
user = models.ForeignKey(
"db.User", on_delete=models.CASCADE, null=True, related_name="assets"
)
workspace = models.ForeignKey(
"db.Workspace", on_delete=models.CASCADE, null=True, related_name="assets"
)
draft_issue = models.ForeignKey(
"db.DraftIssue", on_delete=models.CASCADE, null=True, related_name="assets"
)
project = models.ForeignKey(
"db.Project", on_delete=models.CASCADE, null=True, related_name="assets"
)
issue = models.ForeignKey(
"db.Issue", on_delete=models.CASCADE, null=True, related_name="assets"
)
comment = models.ForeignKey(
"db.IssueComment", on_delete=models.CASCADE, null=True, related_name="assets"
)
page = models.ForeignKey(
"db.Page", on_delete=models.CASCADE, null=True, related_name="assets"
)
user = models.ForeignKey("db.User", on_delete=models.CASCADE, null=True, related_name="assets")
workspace = models.ForeignKey("db.Workspace", on_delete=models.CASCADE, null=True, related_name="assets")
draft_issue = models.ForeignKey("db.DraftIssue", on_delete=models.CASCADE, null=True, related_name="assets")
project = models.ForeignKey("db.Project", on_delete=models.CASCADE, null=True, related_name="assets")
issue = models.ForeignKey("db.Issue", on_delete=models.CASCADE, null=True, related_name="assets")
comment = models.ForeignKey("db.IssueComment", on_delete=models.CASCADE, null=True, related_name="assets")
page = models.ForeignKey("db.Page", on_delete=models.CASCADE, null=True, related_name="assets")
entity_type = models.CharField(max_length=255, null=True, blank=True)
entity_identifier = models.CharField(max_length=255, null=True, blank=True)
is_deleted = models.BooleanField(default=False)
@ -78,12 +64,8 @@ class FileAsset(BaseModel):
ordering = ("-created_at",)
indexes = [
models.Index(fields=["entity_type"], name="asset_entity_type_idx"),
models.Index(
fields=["entity_identifier"], name="asset_entity_identifier_idx"
),
models.Index(
fields=["entity_type", "entity_identifier"], name="asset_entity_idx"
),
models.Index(fields=["entity_identifier"], name="asset_entity_identifier_idx"),
models.Index(fields=["entity_type", "entity_identifier"], name="asset_entity_idx"),
]
def __str__(self):
@ -100,7 +82,7 @@ class FileAsset(BaseModel):
return f"/api/assets/v2/static/{self.id}/"
if self.entity_type == self.EntityTypeContext.ISSUE_ATTACHMENT:
return f"/api/assets/v2/workspaces/{self.workspace.slug}/projects/{self.project_id}/issues/{self.issue_id}/attachments/{self.id}/"
return f"/api/assets/v2/workspaces/{self.workspace.slug}/projects/{self.project_id}/issues/{self.issue_id}/attachments/{self.id}/" # noqa: E501
if self.entity_type in [
self.EntityTypeContext.ISSUE_DESCRIPTION,

View file

@ -11,9 +11,7 @@ from ..mixins import AuditModel
class BaseModel(AuditModel):
id = models.UUIDField(
default=uuid.uuid4, unique=True, editable=False, db_index=True, primary_key=True
)
id = models.UUIDField(default=uuid.uuid4, unique=True, editable=False, db_index=True, primary_key=True)
class Meta:
abstract = True

View file

@ -102,12 +102,8 @@ class CycleIssue(ProjectBaseModel):
Cycle Issues
"""
issue = models.ForeignKey(
"db.Issue", on_delete=models.CASCADE, related_name="issue_cycle"
)
cycle = models.ForeignKey(
Cycle, on_delete=models.CASCADE, related_name="issue_cycle"
)
issue = models.ForeignKey("db.Issue", on_delete=models.CASCADE, related_name="issue_cycle")
cycle = models.ForeignKey(Cycle, on_delete=models.CASCADE, related_name="issue_cycle")
class Meta:
unique_together = ["issue", "cycle", "deleted_at"]
@ -128,9 +124,7 @@ class CycleIssue(ProjectBaseModel):
class CycleUserProperties(ProjectBaseModel):
cycle = models.ForeignKey(
"db.Cycle", on_delete=models.CASCADE, related_name="cycle_user_properties"
)
cycle = models.ForeignKey("db.Cycle", on_delete=models.CASCADE, related_name="cycle_user_properties")
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,

View file

@ -25,14 +25,10 @@ class DeployBoard(WorkspaceBaseModel):
entity_identifier = models.UUIDField(null=True)
entity_name = models.CharField(max_length=30, null=True, blank=True)
anchor = models.CharField(
max_length=255, default=get_anchor, unique=True, db_index=True
)
anchor = models.CharField(max_length=255, default=get_anchor, unique=True, db_index=True)
is_comments_enabled = models.BooleanField(default=False)
is_reactions_enabled = models.BooleanField(default=False)
intake = models.ForeignKey(
"db.Intake", related_name="publish_intake", on_delete=models.SET_NULL, null=True
)
intake = models.ForeignKey("db.Intake", related_name="publish_intake", on_delete=models.SET_NULL, null=True)
is_votes_enabled = models.BooleanField(default=False)
view_props = models.JSONField(default=dict)
is_activity_enabled = models.BooleanField(default=True)

View file

@ -4,8 +4,6 @@ from .workspace import WorkspaceBaseModel
class Description(WorkspaceBaseModel):
description_json = models.JSONField(default=dict, blank=True)
description_html = models.TextField(blank=True, default="<p></p>")
description_binary = models.BinaryField(null=True)
@ -32,9 +30,7 @@ class DescriptionVersion(WorkspaceBaseModel):
DescriptionVersion is a model used to store historical versions of a Description.
"""
description = models.ForeignKey(
"db.Description", on_delete=models.CASCADE, related_name="versions"
)
description = models.ForeignKey("db.Description", on_delete=models.CASCADE, related_name="versions")
description_json = models.JSONField(default=dict, blank=True)
description_html = models.TextField(blank=True, default="<p></p>")
description_binary = models.BinaryField(null=True)

View file

@ -11,9 +11,7 @@ class Device(BaseModel):
WEB = "WEB", "Web"
DESKTOP = "DESKTOP", "Desktop"
user = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="devices"
)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="devices")
device_id = models.CharField(max_length=255, blank=True, null=True)
device_type = models.CharField(max_length=255, choices=DeviceType.choices)
push_token = models.CharField(max_length=255, blank=True, null=True)
@ -26,12 +24,8 @@ class Device(BaseModel):
class DeviceSession(BaseModel):
device = models.ForeignKey(
Device, on_delete=models.CASCADE, related_name="sessions"
)
session = models.ForeignKey(
"db.Session", on_delete=models.CASCADE, related_name="device_sessions"
)
device = models.ForeignKey(Device, on_delete=models.CASCADE, related_name="sessions")
session = models.ForeignKey("db.Session", on_delete=models.CASCADE, related_name="device_sessions")
is_active = models.BooleanField(default=True)
user_agent = models.CharField(max_length=255, null=True, blank=True)
ip_address = models.GenericIPAddressField(null=True, blank=True)

View file

@ -38,9 +38,7 @@ class DraftIssue(WorkspaceBaseModel):
null=True,
blank=True,
)
name = models.CharField(
max_length=255, verbose_name="Issue Name", blank=True, null=True
)
name = models.CharField(max_length=255, verbose_name="Issue Name", blank=True, null=True)
description = models.JSONField(blank=True, default=dict)
description_html = models.TextField(blank=True, default="<p></p>")
description_stripped = models.TextField(blank=True, null=True)
@ -60,9 +58,7 @@ class DraftIssue(WorkspaceBaseModel):
through="DraftIssueAssignee",
through_fields=("draft_issue", "assignee"),
)
labels = models.ManyToManyField(
"db.Label", blank=True, related_name="draft_labels", through="DraftIssueLabel"
)
labels = models.ManyToManyField("db.Label", blank=True, related_name="draft_labels", through="DraftIssueLabel")
sort_order = models.FloatField(default=65535)
completed_at = models.DateTimeField(null=True)
external_source = models.CharField(max_length=255, null=True, blank=True)
@ -90,9 +86,7 @@ class DraftIssue(WorkspaceBaseModel):
~models.Q(is_triage=True), project=self.project, default=True
).first()
if default_state is None:
random_state = State.objects.filter(
~models.Q(is_triage=True), project=self.project
).first()
random_state = State.objects.filter(~models.Q(is_triage=True), project=self.project).first()
self.state = random_state
else:
self.state = default_state
@ -116,9 +110,9 @@ class DraftIssue(WorkspaceBaseModel):
if (self.description_html == "" or self.description_html is None)
else strip_tags(self.description_html)
)
largest_sort_order = DraftIssue.objects.filter(
project=self.project, state=self.state
).aggregate(largest=models.Max("sort_order"))["largest"]
largest_sort_order = DraftIssue.objects.filter(project=self.project, state=self.state).aggregate(
largest=models.Max("sort_order")
)["largest"]
if largest_sort_order is not None:
self.sort_order = largest_sort_order + 10000
@ -139,9 +133,7 @@ class DraftIssue(WorkspaceBaseModel):
class DraftIssueAssignee(WorkspaceBaseModel):
draft_issue = models.ForeignKey(
DraftIssue, on_delete=models.CASCADE, related_name="draft_issue_assignee"
)
draft_issue = models.ForeignKey(DraftIssue, on_delete=models.CASCADE, related_name="draft_issue_assignee")
assignee = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
@ -167,12 +159,8 @@ class DraftIssueAssignee(WorkspaceBaseModel):
class DraftIssueLabel(WorkspaceBaseModel):
draft_issue = models.ForeignKey(
"db.DraftIssue", on_delete=models.CASCADE, related_name="draft_label_issue"
)
label = models.ForeignKey(
"db.Label", on_delete=models.CASCADE, related_name="draft_label_issue"
)
draft_issue = models.ForeignKey("db.DraftIssue", on_delete=models.CASCADE, related_name="draft_label_issue")
label = models.ForeignKey("db.Label", on_delete=models.CASCADE, related_name="draft_label_issue")
class Meta:
verbose_name = "Draft Issue Label"
@ -185,12 +173,8 @@ class DraftIssueLabel(WorkspaceBaseModel):
class DraftIssueModule(WorkspaceBaseModel):
module = models.ForeignKey(
"db.Module", on_delete=models.CASCADE, related_name="draft_issue_module"
)
draft_issue = models.ForeignKey(
"db.DraftIssue", on_delete=models.CASCADE, related_name="draft_issue_module"
)
module = models.ForeignKey("db.Module", on_delete=models.CASCADE, related_name="draft_issue_module")
draft_issue = models.ForeignKey("db.DraftIssue", on_delete=models.CASCADE, related_name="draft_issue_module")
class Meta:
unique_together = ["draft_issue", "module", "deleted_at"]
@ -215,12 +199,8 @@ class DraftIssueCycle(WorkspaceBaseModel):
Draft Issue Cycles
"""
draft_issue = models.ForeignKey(
"db.DraftIssue", on_delete=models.CASCADE, related_name="draft_issue_cycle"
)
cycle = models.ForeignKey(
"db.Cycle", on_delete=models.CASCADE, related_name="draft_issue_cycle"
)
draft_issue = models.ForeignKey("db.DraftIssue", on_delete=models.CASCADE, related_name="draft_issue_cycle")
cycle = models.ForeignKey("db.Cycle", on_delete=models.CASCADE, related_name="draft_issue_cycle")
class Meta:
unique_together = ["draft_issue", "cycle", "deleted_at"]

View file

@ -33,12 +33,8 @@ class Estimate(ProjectBaseModel):
class EstimatePoint(ProjectBaseModel):
estimate = models.ForeignKey(
"db.Estimate", on_delete=models.CASCADE, related_name="points"
)
key = models.IntegerField(
default=0, validators=[MinValueValidator(0), MaxValueValidator(12)]
)
estimate = models.ForeignKey("db.Estimate", on_delete=models.CASCADE, related_name="points")
key = models.IntegerField(default=0, validators=[MinValueValidator(0), MaxValueValidator(12)])
description = models.TextField(blank=True)
value = models.CharField(max_length=255)

View file

@ -18,9 +18,7 @@ def generate_token():
class ExporterHistory(BaseModel):
name = models.CharField(
max_length=255, verbose_name="Exporter Name", null=True, blank=True
)
name = models.CharField(max_length=255, verbose_name="Exporter Name", null=True, blank=True)
type = models.CharField(
max_length=50,
default="issue_exports",
@ -29,13 +27,9 @@ class ExporterHistory(BaseModel):
("issue_worklogs", "Issue Worklogs"),
),
)
workspace = models.ForeignKey(
"db.WorkSpace", on_delete=models.CASCADE, related_name="workspace_exporters"
)
workspace = models.ForeignKey("db.WorkSpace", on_delete=models.CASCADE, related_name="workspace_exporters")
project = ArrayField(models.UUIDField(default=uuid.uuid4), blank=True, null=True)
provider = models.CharField(
max_length=50, choices=(("json", "json"), ("csv", "csv"), ("xlsx", "xlsx"))
)
provider = models.CharField(max_length=50, choices=(("json", "json"), ("csv", "csv"), ("xlsx", "xlsx")))
status = models.CharField(
max_length=50,
choices=(

View file

@ -12,9 +12,7 @@ class UserFavorite(WorkspaceBaseModel):
UserFavorite (model): To store all the favorites of the user
"""
user = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="favorites"
)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="favorites")
entity_type = models.CharField(max_length=100)
entity_identifier = models.UUIDField(null=True, blank=True)
name = models.CharField(max_length=255, blank=True, null=True)
@ -43,24 +41,20 @@ class UserFavorite(WorkspaceBaseModel):
ordering = ("-created_at",)
indexes = [
models.Index(fields=["entity_type"], name="fav_entity_type_idx"),
models.Index(
fields=["entity_identifier"], name="fav_entity_identifier_idx"
),
models.Index(
fields=["entity_type", "entity_identifier"], name="fav_entity_idx"
),
models.Index(fields=["entity_identifier"], name="fav_entity_identifier_idx"),
models.Index(fields=["entity_type", "entity_identifier"], name="fav_entity_idx"),
]
def save(self, *args, **kwargs):
if self._state.adding:
if self.project:
largest_sequence = UserFavorite.objects.filter(
workspace=self.project.workspace
).aggregate(largest=models.Max("sequence"))["largest"]
largest_sequence = UserFavorite.objects.filter(workspace=self.project.workspace).aggregate(
largest=models.Max("sequence")
)["largest"]
else:
largest_sequence = UserFavorite.objects.filter(
workspace=self.workspace
).aggregate(largest=models.Max("sequence"))["largest"]
largest_sequence = UserFavorite.objects.filter(workspace=self.workspace).aggregate(
largest=models.Max("sequence")
)["largest"]
if largest_sequence is not None:
self.sequence = largest_sequence + 10000

View file

@ -7,9 +7,7 @@ from .project import ProjectBaseModel
class Importer(ProjectBaseModel):
service = models.CharField(
max_length=50, choices=(("github", "GitHub"), ("jira", "Jira"))
)
service = models.CharField(max_length=50, choices=(("github", "GitHub"), ("jira", "Jira")))
status = models.CharField(
max_length=50,
choices=(
@ -20,15 +18,11 @@ class Importer(ProjectBaseModel):
),
default="queued",
)
initiated_by = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="imports"
)
initiated_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="imports")
metadata = models.JSONField(default=dict)
config = models.JSONField(default=dict)
data = models.JSONField(default=dict)
token = models.ForeignKey(
"db.APIToken", on_delete=models.CASCADE, related_name="importer"
)
token = models.ForeignKey("db.APIToken", on_delete=models.CASCADE, related_name="importer")
imported_data = models.JSONField(null=True)
class Meta:

View file

@ -44,12 +44,8 @@ class IntakeIssueStatus(models.IntegerChoices):
class IntakeIssue(ProjectBaseModel):
intake = models.ForeignKey(
"db.Intake", related_name="issue_intake", on_delete=models.CASCADE
)
issue = models.ForeignKey(
"db.Issue", related_name="issue_intake", on_delete=models.CASCADE
)
intake = models.ForeignKey("db.Intake", related_name="issue_intake", on_delete=models.CASCADE)
issue = models.ForeignKey("db.Issue", related_name="issue_intake", on_delete=models.CASCADE)
status = models.IntegerField(
choices=(
(-2, "Pending"),

View file

@ -10,14 +10,10 @@ from plane.db.mixins import AuditModel
class Integration(AuditModel):
id = models.UUIDField(
default=uuid.uuid4, unique=True, editable=False, db_index=True, primary_key=True
)
id = models.UUIDField(default=uuid.uuid4, unique=True, editable=False, db_index=True, primary_key=True)
title = models.CharField(max_length=400)
provider = models.CharField(max_length=400, unique=True)
network = models.PositiveIntegerField(
default=1, choices=((1, "Private"), (2, "Public"))
)
network = models.PositiveIntegerField(default=1, choices=((1, "Private"), (2, "Public")))
description = models.JSONField(default=dict)
author = models.CharField(max_length=400, blank=True)
webhook_url = models.TextField(blank=True)
@ -39,19 +35,11 @@ class Integration(AuditModel):
class WorkspaceIntegration(BaseModel):
workspace = models.ForeignKey(
"db.Workspace", related_name="workspace_integrations", on_delete=models.CASCADE
)
workspace = models.ForeignKey("db.Workspace", related_name="workspace_integrations", on_delete=models.CASCADE)
# Bot user
actor = models.ForeignKey(
"db.User", related_name="integrations", on_delete=models.CASCADE
)
integration = models.ForeignKey(
"db.Integration", related_name="integrated_workspaces", on_delete=models.CASCADE
)
api_token = models.ForeignKey(
"db.APIToken", related_name="integrations", on_delete=models.CASCADE
)
actor = models.ForeignKey("db.User", related_name="integrations", on_delete=models.CASCADE)
integration = models.ForeignKey("db.Integration", related_name="integrated_workspaces", on_delete=models.CASCADE)
api_token = models.ForeignKey("db.APIToken", related_name="integrations", on_delete=models.CASCADE)
metadata = models.JSONField(default=dict)
config = models.JSONField(default=dict)

View file

@ -26,20 +26,14 @@ class GithubRepository(ProjectBaseModel):
class GithubRepositorySync(ProjectBaseModel):
repository = models.OneToOneField(
"db.GithubRepository", on_delete=models.CASCADE, related_name="syncs"
)
repository = models.OneToOneField("db.GithubRepository", on_delete=models.CASCADE, related_name="syncs")
credentials = models.JSONField(default=dict)
# Bot user
actor = models.ForeignKey(
"db.User", related_name="user_syncs", on_delete=models.CASCADE
)
actor = models.ForeignKey("db.User", related_name="user_syncs", on_delete=models.CASCADE)
workspace_integration = models.ForeignKey(
"db.WorkspaceIntegration", related_name="github_syncs", on_delete=models.CASCADE
)
label = models.ForeignKey(
"db.Label", on_delete=models.SET_NULL, null=True, related_name="repo_syncs"
)
label = models.ForeignKey("db.Label", on_delete=models.SET_NULL, null=True, related_name="repo_syncs")
def __str__(self):
"""Return the repo sync"""
@ -57,12 +51,8 @@ class GithubIssueSync(ProjectBaseModel):
repo_issue_id = models.BigIntegerField()
github_issue_id = models.BigIntegerField()
issue_url = models.URLField(blank=False)
issue = models.ForeignKey(
"db.Issue", related_name="github_syncs", on_delete=models.CASCADE
)
repository_sync = models.ForeignKey(
"db.GithubRepositorySync", related_name="issue_syncs", on_delete=models.CASCADE
)
issue = models.ForeignKey("db.Issue", related_name="github_syncs", on_delete=models.CASCADE)
repository_sync = models.ForeignKey("db.GithubRepositorySync", related_name="issue_syncs", on_delete=models.CASCADE)
def __str__(self):
"""Return the github issue sync"""
@ -78,12 +68,8 @@ class GithubIssueSync(ProjectBaseModel):
class GithubCommentSync(ProjectBaseModel):
repo_comment_id = models.BigIntegerField()
comment = models.ForeignKey(
"db.IssueComment", related_name="comment_syncs", on_delete=models.CASCADE
)
issue_sync = models.ForeignKey(
"db.GithubIssueSync", related_name="comment_syncs", on_delete=models.CASCADE
)
comment = models.ForeignKey("db.IssueComment", related_name="comment_syncs", on_delete=models.CASCADE)
issue_sync = models.ForeignKey("db.GithubIssueSync", related_name="comment_syncs", on_delete=models.CASCADE)
def __str__(self):
"""Return the github issue sync"""

View file

@ -123,9 +123,7 @@ class Issue(ProjectBaseModel):
blank=True,
related_name="state_issue",
)
point = models.IntegerField(
validators=[MinValueValidator(0), MaxValueValidator(12)], null=True, blank=True
)
point = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(12)], null=True, blank=True)
estimate_point = models.ForeignKey(
"db.EstimatePoint",
on_delete=models.SET_NULL,
@ -154,9 +152,7 @@ class Issue(ProjectBaseModel):
through_fields=("issue", "assignee"),
)
sequence_id = models.IntegerField(default=1, verbose_name="Issue Sequence ID")
labels = models.ManyToManyField(
"db.Label", blank=True, related_name="labels", through="IssueLabel"
)
labels = models.ManyToManyField("db.Label", blank=True, related_name="labels", through="IssueLabel")
sort_order = models.FloatField(default=65535)
completed_at = models.DateTimeField(null=True)
archived_at = models.DateField(null=True)
@ -188,9 +184,7 @@ class Issue(ProjectBaseModel):
~models.Q(is_triage=True), project=self.project, default=True
).first()
if default_state is None:
random_state = State.objects.filter(
~models.Q(is_triage=True), project=self.project
).first()
random_state = State.objects.filter(~models.Q(is_triage=True), project=self.project).first()
self.state = random_state
else:
self.state = default_state
@ -219,29 +213,25 @@ class Issue(ProjectBaseModel):
try:
# Get the last sequence for the project
last_sequence = IssueSequence.objects.filter(
project=self.project
).aggregate(largest=models.Max("sequence"))["largest"]
last_sequence = IssueSequence.objects.filter(project=self.project).aggregate(
largest=models.Max("sequence")
)["largest"]
self.sequence_id = last_sequence + 1 if last_sequence else 1
# Strip the html tags using html parser
self.description_stripped = (
None
if (
self.description_html == "" or self.description_html is None
)
if (self.description_html == "" or self.description_html is None)
else strip_tags(self.description_html)
)
largest_sort_order = Issue.objects.filter(
project=self.project, state=self.state
).aggregate(largest=models.Max("sort_order"))["largest"]
largest_sort_order = Issue.objects.filter(project=self.project, state=self.state).aggregate(
largest=models.Max("sort_order")
)["largest"]
if largest_sort_order is not None:
self.sort_order = largest_sort_order + 10000
super(Issue, self).save(*args, **kwargs)
IssueSequence.objects.create(
issue=self, sequence=self.sequence_id, project=self.project
)
IssueSequence.objects.create(issue=self, sequence=self.sequence_id, project=self.project)
finally:
# Release the lock
with connection.cursor() as cursor:
@ -261,12 +251,8 @@ class Issue(ProjectBaseModel):
class IssueBlocker(ProjectBaseModel):
block = models.ForeignKey(
Issue, related_name="blocker_issues", on_delete=models.CASCADE
)
blocked_by = models.ForeignKey(
Issue, related_name="blocked_issues", on_delete=models.CASCADE
)
block = models.ForeignKey(Issue, related_name="blocker_issues", on_delete=models.CASCADE)
blocked_by = models.ForeignKey(Issue, related_name="blocked_issues", on_delete=models.CASCADE)
class Meta:
verbose_name = "Issue Blocker"
@ -288,12 +274,8 @@ class IssueRelationChoices(models.TextChoices):
class IssueRelation(ProjectBaseModel):
issue = models.ForeignKey(
Issue, related_name="issue_relation", on_delete=models.CASCADE
)
related_issue = models.ForeignKey(
Issue, related_name="issue_related", on_delete=models.CASCADE
)
issue = models.ForeignKey(Issue, related_name="issue_relation", on_delete=models.CASCADE)
related_issue = models.ForeignKey(Issue, related_name="issue_related", on_delete=models.CASCADE)
relation_type = models.CharField(
max_length=20,
verbose_name="Issue Relation Type",
@ -319,12 +301,8 @@ class IssueRelation(ProjectBaseModel):
class IssueMention(ProjectBaseModel):
issue = models.ForeignKey(
Issue, on_delete=models.CASCADE, related_name="issue_mention"
)
mention = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="issue_mention"
)
issue = models.ForeignKey(Issue, on_delete=models.CASCADE, related_name="issue_mention")
mention = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="issue_mention")
class Meta:
unique_together = ["issue", "mention", "deleted_at"]
@ -345,9 +323,7 @@ class IssueMention(ProjectBaseModel):
class IssueAssignee(ProjectBaseModel):
issue = models.ForeignKey(
Issue, on_delete=models.CASCADE, related_name="issue_assignee"
)
issue = models.ForeignKey(Issue, on_delete=models.CASCADE, related_name="issue_assignee")
assignee = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
@ -375,9 +351,7 @@ class IssueAssignee(ProjectBaseModel):
class IssueLink(ProjectBaseModel):
title = models.CharField(max_length=255, null=True, blank=True)
url = models.TextField()
issue = models.ForeignKey(
"db.Issue", on_delete=models.CASCADE, related_name="issue_link"
)
issue = models.ForeignKey("db.Issue", on_delete=models.CASCADE, related_name="issue_link")
metadata = models.JSONField(default=dict)
class Meta:
@ -403,9 +377,7 @@ def file_size(value):
class IssueAttachment(ProjectBaseModel):
attributes = models.JSONField(default=dict)
asset = models.FileField(upload_to=get_upload_path, validators=[file_size])
issue = models.ForeignKey(
"db.Issue", on_delete=models.CASCADE, related_name="issue_attachment"
)
issue = models.ForeignKey("db.Issue", on_delete=models.CASCADE, related_name="issue_attachment")
external_source = models.CharField(max_length=255, null=True, blank=True)
external_id = models.CharField(max_length=255, blank=True, null=True)
@ -420,13 +392,9 @@ class IssueAttachment(ProjectBaseModel):
class IssueActivity(ProjectBaseModel):
issue = models.ForeignKey(
Issue, on_delete=models.SET_NULL, null=True, related_name="issue_activity"
)
issue = models.ForeignKey(Issue, on_delete=models.SET_NULL, null=True, related_name="issue_activity")
verb = models.CharField(max_length=255, verbose_name="Action", default="created")
field = models.CharField(
max_length=255, verbose_name="Field Name", blank=True, null=True
)
field = models.CharField(max_length=255, verbose_name="Field Name", blank=True, null=True)
old_value = models.TextField(verbose_name="Old Value", blank=True, null=True)
new_value = models.TextField(verbose_name="New Value", blank=True, null=True)
@ -464,9 +432,7 @@ class IssueComment(ProjectBaseModel):
comment_json = models.JSONField(blank=True, default=dict)
comment_html = models.TextField(blank=True, default="<p></p>")
attachments = ArrayField(models.URLField(), size=10, blank=True, default=list)
issue = models.ForeignKey(
Issue, on_delete=models.CASCADE, related_name="issue_comments"
)
issue = models.ForeignKey(Issue, on_delete=models.CASCADE, related_name="issue_comments")
# System can also create comment
actor = models.ForeignKey(
settings.AUTH_USER_MODEL,
@ -484,9 +450,7 @@ class IssueComment(ProjectBaseModel):
edited_at = models.DateTimeField(null=True, blank=True)
def save(self, *args, **kwargs):
self.comment_stripped = (
strip_tags(self.comment_html) if self.comment_html != "" else ""
)
self.comment_stripped = strip_tags(self.comment_html) if self.comment_html != "" else ""
return super(IssueComment, self).save(*args, **kwargs)
class Meta:
@ -531,12 +495,8 @@ class IssueUserProperty(ProjectBaseModel):
class IssueLabel(ProjectBaseModel):
issue = models.ForeignKey(
"db.Issue", on_delete=models.CASCADE, related_name="label_issue"
)
label = models.ForeignKey(
"db.Label", on_delete=models.CASCADE, related_name="label_issue"
)
issue = models.ForeignKey("db.Issue", on_delete=models.CASCADE, related_name="label_issue")
label = models.ForeignKey("db.Label", on_delete=models.CASCADE, related_name="label_issue")
class Meta:
verbose_name = "Issue Label"
@ -566,9 +526,7 @@ class IssueSequence(ProjectBaseModel):
class IssueSubscriber(ProjectBaseModel):
issue = models.ForeignKey(
Issue, on_delete=models.CASCADE, related_name="issue_subscribers"
)
issue = models.ForeignKey(Issue, on_delete=models.CASCADE, related_name="issue_subscribers")
subscriber = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
@ -599,9 +557,7 @@ class IssueReaction(ProjectBaseModel):
on_delete=models.CASCADE,
related_name="issue_reactions",
)
issue = models.ForeignKey(
Issue, on_delete=models.CASCADE, related_name="issue_reactions"
)
issue = models.ForeignKey(Issue, on_delete=models.CASCADE, related_name="issue_reactions")
reaction = models.TextField()
class Meta:
@ -628,9 +584,7 @@ class CommentReaction(ProjectBaseModel):
on_delete=models.CASCADE,
related_name="comment_reactions",
)
comment = models.ForeignKey(
IssueComment, on_delete=models.CASCADE, related_name="comment_reactions"
)
comment = models.ForeignKey(IssueComment, on_delete=models.CASCADE, related_name="comment_reactions")
reaction = models.TextField()
class Meta:
@ -653,9 +607,7 @@ class CommentReaction(ProjectBaseModel):
class IssueVote(ProjectBaseModel):
issue = models.ForeignKey(Issue, on_delete=models.CASCADE, related_name="votes")
actor = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="votes"
)
actor = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="votes")
vote = models.IntegerField(choices=((-1, "DOWNVOTE"), (1, "UPVOTE")), default=1)
class Meta:
@ -713,9 +665,7 @@ class IssueVersion(ProjectBaseModel):
meta = models.JSONField(default=dict) # issue meta
last_saved_at = models.DateTimeField(default=timezone.now)
issue = models.ForeignKey(
"db.Issue", on_delete=models.CASCADE, related_name="versions"
)
issue = models.ForeignKey("db.Issue", on_delete=models.CASCADE, related_name="versions")
activity = models.ForeignKey(
"db.IssueActivity",
on_delete=models.SET_NULL,
@ -760,17 +710,9 @@ class IssueVersion(ProjectBaseModel):
priority=issue.priority,
start_date=issue.start_date,
target_date=issue.target_date,
assignees=list(
IssueAssignee.objects.filter(issue=issue).values_list(
"assignee_id", flat=True
)
),
assignees=list(IssueAssignee.objects.filter(issue=issue).values_list("assignee_id", flat=True)),
sequence_id=issue.sequence_id,
labels=list(
IssueLabel.objects.filter(issue=issue).values_list(
"label_id", flat=True
)
),
labels=list(IssueLabel.objects.filter(issue=issue).values_list("label_id", flat=True)),
sort_order=issue.sort_order,
completed_at=issue.completed_at,
archived_at=issue.archived_at,
@ -779,9 +721,7 @@ class IssueVersion(ProjectBaseModel):
external_id=issue.external_id,
type=issue.type_id,
cycle=cycle_issue.cycle_id if cycle_issue else None,
modules=list(
Module.objects.filter(issue=issue).values_list("id", flat=True)
),
modules=list(Module.objects.filter(issue=issue).values_list("id", flat=True)),
properties={},
meta={},
last_saved_at=timezone.now(),
@ -794,9 +734,7 @@ class IssueVersion(ProjectBaseModel):
class IssueDescriptionVersion(ProjectBaseModel):
issue = models.ForeignKey(
"db.Issue", on_delete=models.CASCADE, related_name="description_versions"
)
issue = models.ForeignKey("db.Issue", on_delete=models.CASCADE, related_name="description_versions")
description_binary = models.BinaryField(null=True)
description_html = models.TextField(blank=True, default="<p></p>")
description_stripped = models.TextField(blank=True, null=True)

View file

@ -8,9 +8,7 @@ from .base import BaseModel
class IssueType(BaseModel):
workspace = models.ForeignKey(
"db.Workspace", related_name="issue_types", on_delete=models.CASCADE
)
workspace = models.ForeignKey("db.Workspace", related_name="issue_types", on_delete=models.CASCADE)
name = models.CharField(max_length=255)
description = models.TextField(blank=True)
logo_props = models.JSONField(default=dict)
@ -31,9 +29,7 @@ class IssueType(BaseModel):
class ProjectIssueType(ProjectBaseModel):
issue_type = models.ForeignKey(
"db.IssueType", related_name="project_issue_types", on_delete=models.CASCADE
)
issue_type = models.ForeignKey("db.IssueType", related_name="project_issue_types", on_delete=models.CASCADE)
level = models.PositiveIntegerField(default=0)
is_default = models.BooleanField(default=False)

View file

@ -42,9 +42,7 @@ class Label(WorkspaceBaseModel):
def save(self, *args, **kwargs):
if self._state.adding:
# Get the maximum sequence value from the database
last_id = Label.objects.filter(project=self.project).aggregate(
largest=models.Max("sort_order")
)["largest"]
last_id = Label.objects.filter(project=self.project).aggregate(largest=models.Max("sort_order"))["largest"]
# if last_id is not None
if last_id is not None:
self.sort_order = last_id + 10000

View file

@ -63,12 +63,8 @@ class ModuleStatus(models.TextChoices):
class Module(ProjectBaseModel):
name = models.CharField(max_length=255, verbose_name="Module Name")
description = models.TextField(verbose_name="Module Description", blank=True)
description_text = models.JSONField(
verbose_name="Module Description RT", blank=True, null=True
)
description_html = models.JSONField(
verbose_name="Module Description HTML", blank=True, null=True
)
description_text = models.JSONField(verbose_name="Module Description RT", blank=True, null=True)
description_html = models.JSONField(verbose_name="Module Description HTML", blank=True, null=True)
start_date = models.DateField(null=True)
target_date = models.DateField(null=True)
status = models.CharField(
@ -83,9 +79,7 @@ class Module(ProjectBaseModel):
default="planned",
max_length=20,
)
lead = models.ForeignKey(
"db.User", on_delete=models.SET_NULL, related_name="module_leads", null=True
)
lead = models.ForeignKey("db.User", on_delete=models.SET_NULL, related_name="module_leads", null=True)
members = models.ManyToManyField(
settings.AUTH_USER_MODEL,
blank=True,
@ -152,12 +146,8 @@ class ModuleMember(ProjectBaseModel):
class ModuleIssue(ProjectBaseModel):
module = models.ForeignKey(
"db.Module", on_delete=models.CASCADE, related_name="issue_module"
)
issue = models.ForeignKey(
"db.Issue", on_delete=models.CASCADE, related_name="issue_module"
)
module = models.ForeignKey("db.Module", on_delete=models.CASCADE, related_name="issue_module")
issue = models.ForeignKey("db.Issue", on_delete=models.CASCADE, related_name="issue_module")
class Meta:
unique_together = ["issue", "module", "deleted_at"]
@ -180,9 +170,7 @@ class ModuleIssue(ProjectBaseModel):
class ModuleLink(ProjectBaseModel):
title = models.CharField(max_length=255, blank=True, null=True)
url = models.URLField()
module = models.ForeignKey(
Module, on_delete=models.CASCADE, related_name="link_module"
)
module = models.ForeignKey(Module, on_delete=models.CASCADE, related_name="link_module")
metadata = models.JSONField(default=dict)
class Meta:
@ -196,9 +184,7 @@ class ModuleLink(ProjectBaseModel):
class ModuleUserProperties(ProjectBaseModel):
module = models.ForeignKey(
"db.Module", on_delete=models.CASCADE, related_name="module_user_properties"
)
module = models.ForeignKey("db.Module", on_delete=models.CASCADE, related_name="module_user_properties")
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,

View file

@ -7,12 +7,8 @@ from .base import BaseModel
class Notification(BaseModel):
workspace = models.ForeignKey(
"db.Workspace", related_name="notifications", on_delete=models.CASCADE
)
project = models.ForeignKey(
"db.Project", related_name="notifications", on_delete=models.CASCADE, null=True
)
workspace = models.ForeignKey("db.Workspace", related_name="notifications", on_delete=models.CASCADE)
project = models.ForeignKey("db.Project", related_name="notifications", on_delete=models.CASCADE, null=True)
data = models.JSONField(null=True)
entity_identifier = models.UUIDField(null=True)
entity_name = models.CharField(max_length=255)
@ -27,9 +23,7 @@ class Notification(BaseModel):
on_delete=models.SET_NULL,
null=True,
)
receiver = models.ForeignKey(
"db.User", related_name="received_notifications", on_delete=models.CASCADE
)
receiver = models.ForeignKey("db.User", related_name="received_notifications", on_delete=models.CASCADE)
read_at = models.DateTimeField(null=True)
snoozed_till = models.DateTimeField(null=True)
archived_at = models.DateTimeField(null=True)
@ -40,9 +34,7 @@ class Notification(BaseModel):
db_table = "notifications"
ordering = ("-created_at",)
indexes = [
models.Index(
fields=["entity_identifier"], name="notif_entity_identifier_idx"
),
models.Index(fields=["entity_identifier"], name="notif_entity_identifier_idx"),
models.Index(fields=["entity_name"], name="notif_entity_name_idx"),
models.Index(fields=["read_at"], name="notif_read_at_idx"),
models.Index(fields=["receiver", "read_at"], name="notif_entity_idx"),

View file

@ -23,24 +23,16 @@ class Page(BaseModel):
ACCESS_CHOICES = ((PRIVATE_ACCESS, "Private"), (PUBLIC_ACCESS, "Public"))
workspace = models.ForeignKey(
"db.Workspace", on_delete=models.CASCADE, related_name="pages"
)
workspace = models.ForeignKey("db.Workspace", on_delete=models.CASCADE, related_name="pages")
name = models.TextField(blank=True)
description = models.JSONField(default=dict, blank=True)
description_binary = models.BinaryField(null=True)
description_html = models.TextField(blank=True, default="<p></p>")
description_stripped = models.TextField(blank=True, null=True)
owned_by = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="pages"
)
access = models.PositiveSmallIntegerField(
choices=((0, "Public"), (1, "Private")), default=0
)
owned_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="pages")
access = models.PositiveSmallIntegerField(choices=((0, "Public"), (1, "Private")), default=0)
color = models.CharField(max_length=255, blank=True)
labels = models.ManyToManyField(
"db.Label", blank=True, related_name="pages", through="db.PageLabel"
)
labels = models.ManyToManyField("db.Label", blank=True, related_name="pages", through="db.PageLabel")
parent = models.ForeignKey(
"self",
on_delete=models.CASCADE,
@ -53,9 +45,7 @@ class Page(BaseModel):
view_props = models.JSONField(default=get_view_props)
logo_props = models.JSONField(default=dict)
is_global = models.BooleanField(default=False)
projects = models.ManyToManyField(
"db.Project", related_name="pages", through="db.ProjectPage"
)
projects = models.ManyToManyField("db.Project", related_name="pages", through="db.ProjectPage")
moved_to_page = models.UUIDField(null=True, blank=True)
moved_to_project = models.UUIDField(null=True, blank=True)
sort_order = models.FloatField(default=DEFAULT_SORT_ORDER)
@ -102,12 +92,8 @@ class PageLog(BaseModel):
page = models.ForeignKey(Page, related_name="page_log", on_delete=models.CASCADE)
entity_identifier = models.UUIDField(null=True, blank=True)
entity_name = models.CharField(max_length=30, verbose_name="Transaction Type")
entity_type = models.CharField(
max_length=30, verbose_name="Entity Type", null=True, blank=True
)
workspace = models.ForeignKey(
"db.Workspace", on_delete=models.CASCADE, related_name="workspace_page_log"
)
entity_type = models.CharField(max_length=30, verbose_name="Entity Type", null=True, blank=True)
workspace = models.ForeignKey("db.Workspace", on_delete=models.CASCADE, related_name="workspace_page_log")
class Meta:
unique_together = ["page", "transaction"]
@ -119,12 +105,8 @@ class PageLog(BaseModel):
models.Index(fields=["entity_type"], name="pagelog_entity_type_idx"),
models.Index(fields=["entity_identifier"], name="pagelog_entity_id_idx"),
models.Index(fields=["entity_name"], name="pagelog_entity_name_idx"),
models.Index(
fields=["entity_type", "entity_identifier"], name="pagelog_type_id_idx"
),
models.Index(
fields=["entity_name", "entity_identifier"], name="pagelog_name_id_idx"
),
models.Index(fields=["entity_type", "entity_identifier"], name="pagelog_type_id_idx"),
models.Index(fields=["entity_name", "entity_identifier"], name="pagelog_name_id_idx"),
]
def __str__(self):
@ -132,15 +114,9 @@ class PageLog(BaseModel):
class PageLabel(BaseModel):
label = models.ForeignKey(
"db.Label", on_delete=models.CASCADE, related_name="page_labels"
)
page = models.ForeignKey(
"db.Page", on_delete=models.CASCADE, related_name="page_labels"
)
workspace = models.ForeignKey(
"db.Workspace", on_delete=models.CASCADE, related_name="workspace_page_label"
)
label = models.ForeignKey("db.Label", on_delete=models.CASCADE, related_name="page_labels")
page = models.ForeignKey("db.Page", on_delete=models.CASCADE, related_name="page_labels")
workspace = models.ForeignKey("db.Workspace", on_delete=models.CASCADE, related_name="workspace_page_label")
class Meta:
verbose_name = "Page Label"
@ -153,15 +129,9 @@ class PageLabel(BaseModel):
class ProjectPage(BaseModel):
project = models.ForeignKey(
"db.Project", on_delete=models.CASCADE, related_name="project_pages"
)
page = models.ForeignKey(
"db.Page", on_delete=models.CASCADE, related_name="project_pages"
)
workspace = models.ForeignKey(
"db.Workspace", on_delete=models.CASCADE, related_name="project_pages"
)
project = models.ForeignKey("db.Project", on_delete=models.CASCADE, related_name="project_pages")
page = models.ForeignKey("db.Page", on_delete=models.CASCADE, related_name="project_pages")
workspace = models.ForeignKey("db.Workspace", on_delete=models.CASCADE, related_name="project_pages")
class Meta:
unique_together = ["project", "page", "deleted_at"]
@ -182,16 +152,10 @@ class ProjectPage(BaseModel):
class PageVersion(BaseModel):
workspace = models.ForeignKey(
"db.Workspace", on_delete=models.CASCADE, related_name="page_versions"
)
page = models.ForeignKey(
"db.Page", on_delete=models.CASCADE, related_name="page_versions"
)
workspace = models.ForeignKey("db.Workspace", on_delete=models.CASCADE, related_name="page_versions")
page = models.ForeignKey("db.Page", on_delete=models.CASCADE, related_name="page_versions")
last_saved_at = models.DateTimeField(default=timezone.now)
owned_by = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="page_versions"
)
owned_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="page_versions")
description_binary = models.BinaryField(null=True)
description_html = models.TextField(blank=True, default="<p></p>")
description_stripped = models.TextField(blank=True, null=True)

View file

@ -66,19 +66,11 @@ class Project(BaseModel):
NETWORK_CHOICES = ((0, "Secret"), (2, "Public"))
name = models.CharField(max_length=255, verbose_name="Project Name")
description = models.TextField(verbose_name="Project Description", blank=True)
description_text = models.JSONField(
verbose_name="Project Description RT", blank=True, null=True
)
description_html = models.JSONField(
verbose_name="Project Description HTML", blank=True, null=True
)
description_text = models.JSONField(verbose_name="Project Description RT", blank=True, null=True)
description_html = models.JSONField(verbose_name="Project Description HTML", blank=True, null=True)
network = models.PositiveSmallIntegerField(default=2, choices=NETWORK_CHOICES)
workspace = models.ForeignKey(
"db.WorkSpace", on_delete=models.CASCADE, related_name="workspace_project"
)
identifier = models.CharField(
max_length=12, verbose_name="Project Identifier", db_index=True
)
workspace = models.ForeignKey("db.WorkSpace", on_delete=models.CASCADE, related_name="workspace_project")
identifier = models.CharField(max_length=12, verbose_name="Project Identifier", db_index=True)
default_assignee = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
@ -111,19 +103,11 @@ class Project(BaseModel):
blank=True,
related_name="project_cover_image",
)
estimate = models.ForeignKey(
"db.Estimate", on_delete=models.SET_NULL, related_name="projects", null=True
)
archive_in = models.IntegerField(
default=0, validators=[MinValueValidator(0), MaxValueValidator(12)]
)
close_in = models.IntegerField(
default=0, validators=[MinValueValidator(0), MaxValueValidator(12)]
)
estimate = models.ForeignKey("db.Estimate", on_delete=models.SET_NULL, related_name="projects", null=True)
archive_in = models.IntegerField(default=0, validators=[MinValueValidator(0), MaxValueValidator(12)])
close_in = models.IntegerField(default=0, validators=[MinValueValidator(0), MaxValueValidator(12)])
logo_props = models.JSONField(default=dict)
default_state = models.ForeignKey(
"db.State", on_delete=models.SET_NULL, null=True, related_name="default_state"
)
default_state = models.ForeignKey("db.State", on_delete=models.SET_NULL, null=True, related_name="default_state")
archived_at = models.DateTimeField(null=True)
# timezone
TIMEZONE_CHOICES = tuple(zip(pytz.common_timezones, pytz.common_timezones))
@ -176,12 +160,8 @@ class Project(BaseModel):
class ProjectBaseModel(BaseModel):
project = models.ForeignKey(
Project, on_delete=models.CASCADE, related_name="project_%(class)s"
)
workspace = models.ForeignKey(
"db.Workspace", on_delete=models.CASCADE, related_name="workspace_%(class)s"
)
project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name="project_%(class)s")
workspace = models.ForeignKey("db.Workspace", on_delete=models.CASCADE, related_name="workspace_%(class)s")
class Meta:
abstract = True
@ -258,12 +238,8 @@ class ProjectMember(ProjectBaseModel):
# TODO: Remove workspace relation later
class ProjectIdentifier(AuditModel):
workspace = models.ForeignKey(
"db.Workspace", models.CASCADE, related_name="project_identifiers", null=True
)
project = models.OneToOneField(
Project, on_delete=models.CASCADE, related_name="project_identifier"
)
workspace = models.ForeignKey("db.Workspace", models.CASCADE, related_name="project_identifiers", null=True)
project = models.OneToOneField(Project, on_delete=models.CASCADE, related_name="project_identifier")
name = models.CharField(max_length=12, db_index=True)
class Meta:
@ -298,14 +274,10 @@ def get_default_views():
# DEPRECATED TODO:
# used to get the old anchors for the project deploy boards
class ProjectDeployBoard(ProjectBaseModel):
anchor = models.CharField(
max_length=255, default=get_anchor, unique=True, db_index=True
)
anchor = models.CharField(max_length=255, default=get_anchor, unique=True, db_index=True)
comments = models.BooleanField(default=False)
reactions = models.BooleanField(default=False)
intake = models.ForeignKey(
"db.Intake", related_name="board_intake", on_delete=models.SET_NULL, null=True
)
intake = models.ForeignKey("db.Intake", related_name="board_intake", on_delete=models.SET_NULL, null=True)
votes = models.BooleanField(default=False)
views = models.JSONField(default=get_default_views)

View file

@ -52,9 +52,7 @@ class State(ProjectBaseModel):
self.slug = slugify(self.name)
if self._state.adding:
# Get the maximum sequence value from the database
last_id = State.objects.filter(project=self.project).aggregate(
largest=models.Max("sequence")
)["largest"]
last_id = State.objects.filter(project=self.project).aggregate(largest=models.Max("sequence"))["largest"]
# if last_id is not None
if last_id is not None:
self.sequence = last_id + 15000

View file

@ -21,12 +21,8 @@ class Sticky(BaseModel):
color = models.CharField(max_length=255, blank=True, null=True)
background_color = models.CharField(max_length=255, blank=True, null=True)
workspace = models.ForeignKey(
"db.Workspace", on_delete=models.CASCADE, related_name="stickies"
)
owner = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="stickies"
)
workspace = models.ForeignKey("db.Workspace", on_delete=models.CASCADE, related_name="stickies")
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="stickies")
sort_order = models.FloatField(default=65535)
class Meta:
@ -44,9 +40,9 @@ class Sticky(BaseModel):
)
if self._state.adding:
# Get the maximum sequence value from the database
last_id = Sticky.objects.filter(workspace=self.workspace).aggregate(
largest=models.Max("sort_order")
)["largest"]
last_id = Sticky.objects.filter(workspace=self.workspace).aggregate(largest=models.Max("sort_order"))[
"largest"
]
# if last_id is not None
if last_id is not None:
self.sort_order = last_id + 10000

View file

@ -36,9 +36,7 @@ def get_mobile_default_onboarding():
class User(AbstractBaseUser, PermissionsMixin):
id = models.UUIDField(
default=uuid.uuid4, unique=True, editable=False, db_index=True, primary_key=True
)
id = models.UUIDField(default=uuid.uuid4, unique=True, editable=False, db_index=True, primary_key=True)
username = models.CharField(max_length=128, unique=True)
# user fields
mobile_number = models.CharField(max_length=255, blank=True, null=True)
@ -97,15 +95,11 @@ class User(AbstractBaseUser, PermissionsMixin):
# my_issues_prop = models.JSONField(null=True)
is_bot = models.BooleanField(default=False)
bot_type = models.CharField(
max_length=30, verbose_name="Bot Type", blank=True, null=True
)
bot_type = models.CharField(max_length=30, verbose_name="Bot Type", blank=True, null=True)
# timezone
USER_TIMEZONE_CHOICES = tuple(zip(pytz.common_timezones, pytz.common_timezones))
user_timezone = models.CharField(
max_length=255, default="UTC", choices=USER_TIMEZONE_CHOICES
)
user_timezone = models.CharField(max_length=255, default="UTC", choices=USER_TIMEZONE_CHOICES)
# email validation
is_email_valid = models.BooleanField(default=False)
@ -189,13 +183,9 @@ class Profile(TimeAuditModel):
(SATURDAY, "Saturday"),
)
id = models.UUIDField(
default=uuid.uuid4, unique=True, editable=False, db_index=True, primary_key=True
)
id = models.UUIDField(default=uuid.uuid4, unique=True, editable=False, db_index=True, primary_key=True)
# User
user = models.OneToOneField(
"db.User", on_delete=models.CASCADE, related_name="profile"
)
user = models.OneToOneField("db.User", on_delete=models.CASCADE, related_name="profile")
# General
theme = models.JSONField(default=dict)
is_app_rail_docked = models.BooleanField(default=True)
@ -220,9 +210,7 @@ class Profile(TimeAuditModel):
mobile_timezone_auto_set = models.BooleanField(default=False)
# language
language = models.CharField(max_length=255, default="en")
start_of_the_week = models.PositiveSmallIntegerField(
choices=START_OF_THE_WEEK_CHOICES, default=SUNDAY
)
start_of_the_week = models.PositiveSmallIntegerField(choices=START_OF_THE_WEEK_CHOICES, default=SUNDAY)
goals = models.JSONField(default=dict)
background_color = models.CharField(max_length=255, default=get_random_color)
@ -243,12 +231,8 @@ class Account(TimeAuditModel):
("gitlab", "GitLab"),
)
id = models.UUIDField(
default=uuid.uuid4, unique=True, editable=False, db_index=True, primary_key=True
)
user = models.ForeignKey(
"db.User", on_delete=models.CASCADE, related_name="accounts"
)
id = models.UUIDField(default=uuid.uuid4, unique=True, editable=False, db_index=True, primary_key=True)
user = models.ForeignKey("db.User", on_delete=models.CASCADE, related_name="accounts")
provider_account_id = models.CharField(max_length=255)
provider = models.CharField(choices=PROVIDER_CHOICES)
access_token = models.TextField()

View file

@ -59,14 +59,10 @@ class IssueView(WorkspaceBaseModel):
display_filters = models.JSONField(default=get_default_display_filters)
display_properties = models.JSONField(default=get_default_display_properties)
rich_filters = models.JSONField(default=dict)
access = models.PositiveSmallIntegerField(
default=1, choices=((0, "Private"), (1, "Public"))
)
access = models.PositiveSmallIntegerField(default=1, choices=((0, "Private"), (1, "Public")))
sort_order = models.FloatField(default=65535)
logo_props = models.JSONField(default=dict)
owned_by = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="views"
)
owned_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="views")
is_locked = models.BooleanField(default=False)
class Meta:
@ -81,13 +77,13 @@ class IssueView(WorkspaceBaseModel):
if self._state.adding:
if self.project:
largest_sort_order = IssueView.objects.filter(
project=self.project
).aggregate(largest=models.Max("sort_order"))["largest"]
largest_sort_order = IssueView.objects.filter(project=self.project).aggregate(
largest=models.Max("sort_order")
)["largest"]
else:
largest_sort_order = IssueView.objects.filter(
workspace=self.workspace, project__isnull=True
).aggregate(largest=models.Max("sort_order"))["largest"]
largest_sort_order = IssueView.objects.filter(workspace=self.workspace, project__isnull=True).aggregate(
largest=models.Max("sort_order")
)["largest"]
if largest_sort_order is not None:
self.sort_order = largest_sort_order + 10000

View file

@ -28,12 +28,8 @@ def validate_domain(value):
class Webhook(BaseModel):
workspace = models.ForeignKey(
"db.Workspace", on_delete=models.CASCADE, related_name="workspace_webhooks"
)
url = models.URLField(
validators=[validate_schema, validate_domain], max_length=1024
)
workspace = models.ForeignKey("db.Workspace", on_delete=models.CASCADE, related_name="workspace_webhooks")
url = models.URLField(validators=[validate_schema, validate_domain], max_length=1024)
is_active = models.BooleanField(default=True)
secret_key = models.CharField(max_length=255, default=generate_token)
project = models.BooleanField(default=False)
@ -62,9 +58,7 @@ class Webhook(BaseModel):
class WebhookLog(BaseModel):
workspace = models.ForeignKey(
"db.Workspace", on_delete=models.CASCADE, related_name="webhook_logs"
)
workspace = models.ForeignKey("db.Workspace", on_delete=models.CASCADE, related_name="webhook_logs")
# Associated webhook
webhook = models.UUIDField()
@ -92,11 +86,8 @@ class WebhookLog(BaseModel):
return f"{self.event_type} {str(self.webhook)}"
class ProjectWebhook(ProjectBaseModel):
webhook = models.ForeignKey(
"db.Webhook", on_delete=models.CASCADE, related_name="project_webhooks"
)
webhook = models.ForeignKey("db.Webhook", on_delete=models.CASCADE, related_name="project_webhooks")
class Meta:
unique_together = ["project", "webhook", "deleted_at"]
@ -110,4 +101,4 @@ class ProjectWebhook(ProjectBaseModel):
verbose_name = "Project Webhook"
verbose_name_plural = "Project Webhooks"
db_table = "project_webhooks"
ordering = ("-created_at",)
ordering = ("-created_at",)

View file

@ -129,9 +129,7 @@ class Workspace(BaseModel):
on_delete=models.CASCADE,
related_name="owner_workspace",
)
slug = models.SlugField(
max_length=48, db_index=True, unique=True, validators=[slug_validator]
)
slug = models.SlugField(max_length=48, db_index=True, unique=True, validators=[slug_validator])
organization_size = models.CharField(max_length=20, blank=True, null=True)
timezone = models.CharField(max_length=255, default="UTC", choices=TIMEZONE_CHOICES)
background_color = models.CharField(max_length=255, default=get_random_color)
@ -151,9 +149,7 @@ class Workspace(BaseModel):
return self.logo
return None
def delete(
self, using: Optional[str] = None, soft: bool = True, *args: Any, **kwargs: Any
):
def delete(self, using: Optional[str] = None, soft: bool = True, *args: Any, **kwargs: Any):
"""
Override the delete method to append epoch timestamp to the slug when soft deleting.
@ -183,12 +179,8 @@ class Workspace(BaseModel):
class WorkspaceBaseModel(BaseModel):
workspace = models.ForeignKey(
"db.Workspace", models.CASCADE, related_name="workspace_%(class)s"
)
project = models.ForeignKey(
"db.Project", models.CASCADE, related_name="project_%(class)s", null=True
)
workspace = models.ForeignKey("db.Workspace", models.CASCADE, related_name="workspace_%(class)s")
project = models.ForeignKey("db.Project", models.CASCADE, related_name="project_%(class)s", null=True)
class Meta:
abstract = True
@ -200,9 +192,7 @@ class WorkspaceBaseModel(BaseModel):
class WorkspaceMember(BaseModel):
workspace = models.ForeignKey(
"db.Workspace", on_delete=models.CASCADE, related_name="workspace_member"
)
workspace = models.ForeignKey("db.Workspace", on_delete=models.CASCADE, related_name="workspace_member")
member = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
@ -235,9 +225,7 @@ class WorkspaceMember(BaseModel):
class WorkspaceMemberInvite(BaseModel):
workspace = models.ForeignKey(
"db.Workspace", on_delete=models.CASCADE, related_name="workspace_member_invite"
)
workspace = models.ForeignKey("db.Workspace", on_delete=models.CASCADE, related_name="workspace_member_invite")
email = models.CharField(max_length=255)
accepted = models.BooleanField(default=False)
token = models.CharField(max_length=255)
@ -266,9 +254,7 @@ class WorkspaceMemberInvite(BaseModel):
class Team(BaseModel):
name = models.CharField(max_length=255, verbose_name="Team Name")
description = models.TextField(verbose_name="Team Description", blank=True)
workspace = models.ForeignKey(
Workspace, on_delete=models.CASCADE, related_name="workspace_team"
)
workspace = models.ForeignKey(Workspace, on_delete=models.CASCADE, related_name="workspace_team")
logo_props = models.JSONField(default=dict)
def __str__(self):
@ -291,13 +277,9 @@ class Team(BaseModel):
class WorkspaceTheme(BaseModel):
workspace = models.ForeignKey(
"db.Workspace", on_delete=models.CASCADE, related_name="themes"
)
workspace = models.ForeignKey("db.Workspace", on_delete=models.CASCADE, related_name="themes")
name = models.CharField(max_length=300)
actor = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="themes"
)
actor = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name="themes")
colors = models.JSONField(default=dict)
def __str__(self):