chore: squashed migration

This commit is contained in:
NarayanBavisetti 2024-05-28 20:06:27 +05:30
parent 67a33c1352
commit 1a9cd35176
19 changed files with 365 additions and 54 deletions

View File

@ -22,7 +22,7 @@ from plane.db.models import (
IssueProperty,
Module,
Project,
ProjectDeployBoard,
DeployBoard,
ProjectMember,
State,
Workspace,
@ -99,7 +99,7 @@ class ProjectAPIEndpoint(BaseAPIView):
)
.annotate(
is_deployed=Exists(
ProjectDeployBoard.objects.filter(
DeployBoard.objects.filter(
project_id=OuterRef("pk"),
workspace__slug=self.kwargs.get("slug"),
)

View File

@ -30,7 +30,7 @@ from .project import (
ProjectIdentifierSerializer,
ProjectLiteSerializer,
ProjectMemberLiteSerializer,
ProjectDeployBoardSerializer,
DeployBoardSerializer,
ProjectMemberAdminSerializer,
ProjectPublicMemberSerializer,
ProjectMemberRoleSerializer,

View File

@ -13,7 +13,7 @@ from plane.db.models import (
ProjectMember,
ProjectMemberInvite,
ProjectIdentifier,
ProjectDeployBoard,
DeployBoard,
ProjectPublicMember,
)
@ -206,14 +206,14 @@ class ProjectMemberLiteSerializer(BaseSerializer):
read_only_fields = fields
class ProjectDeployBoardSerializer(BaseSerializer):
class DeployBoardSerializer(BaseSerializer):
project_details = ProjectLiteSerializer(read_only=True, source="project")
workspace_detail = WorkspaceLiteSerializer(
read_only=True, source="workspace"
)
class Meta:
model = ProjectDeployBoard
model = DeployBoard
fields = "__all__"
read_only_fields = [
"workspace",

View File

@ -12,7 +12,7 @@ from plane.app.views import (
ProjectFavoritesViewSet,
UserProjectInvitationsViewset,
ProjectPublicCoverImagesEndpoint,
ProjectDeployBoardViewSet,
DeployBoardViewSet,
UserProjectRolesEndpoint,
ProjectArchiveUnarchiveEndpoint,
)
@ -157,7 +157,7 @@ urlpatterns = [
),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/project-deploy-boards/",
ProjectDeployBoardViewSet.as_view(
DeployBoardViewSet.as_view(
{
"get": "list",
"post": "create",
@ -167,7 +167,7 @@ urlpatterns = [
),
path(
"workspaces/<str:slug>/projects/<uuid:project_id>/project-deploy-boards/<uuid:pk>/",
ProjectDeployBoardViewSet.as_view(
DeployBoardViewSet.as_view(
{
"get": "retrieve",
"patch": "partial_update",

View File

@ -4,7 +4,7 @@ from .project.base import (
ProjectUserViewsEndpoint,
ProjectFavoritesViewSet,
ProjectPublicCoverImagesEndpoint,
ProjectDeployBoardViewSet,
DeployBoardViewSet,
ProjectArchiveUnarchiveEndpoint,
)

View File

@ -28,7 +28,7 @@ from plane.app.views.base import BaseViewSet, BaseAPIView
from plane.app.serializers import (
ProjectSerializer,
ProjectListSerializer,
ProjectDeployBoardSerializer,
DeployBoardSerializer,
)
from plane.app.permissions import (
@ -46,7 +46,7 @@ from plane.db.models import (
Module,
Cycle,
Inbox,
ProjectDeployBoard,
DeployBoard,
IssueProperty,
Issue,
)
@ -138,7 +138,7 @@ class ProjectViewSet(BaseViewSet):
)
.annotate(
is_deployed=Exists(
ProjectDeployBoard.objects.filter(
DeployBoard.objects.filter(
project_id=OuterRef("pk"),
workspace__slug=self.kwargs.get("slug"),
)
@ -639,12 +639,12 @@ class ProjectPublicCoverImagesEndpoint(BaseAPIView):
return Response(files, status=status.HTTP_200_OK)
class ProjectDeployBoardViewSet(BaseViewSet):
class DeployBoardViewSet(BaseViewSet):
permission_classes = [
ProjectMemberPermission,
]
serializer_class = ProjectDeployBoardSerializer
model = ProjectDeployBoard
serializer_class = DeployBoardSerializer
model = DeployBoard
def get_queryset(self):
return (
@ -673,7 +673,7 @@ class ProjectDeployBoardViewSet(BaseViewSet):
},
)
project_deploy_board, _ = ProjectDeployBoard.objects.get_or_create(
project_deploy_board, _ = DeployBoard.objects.get_or_create(
anchor=f"{slug}/{project_id}",
project_id=project_id,
)
@ -685,5 +685,5 @@ class ProjectDeployBoardViewSet(BaseViewSet):
project_deploy_board.save()
serializer = ProjectDeployBoardSerializer(project_deploy_board)
serializer = DeployBoardSerializer(project_deploy_board)
return Response(serializer.data, status=status.HTTP_200_OK)

View File

@ -0,0 +1,221 @@
# # Generated by Django 4.2.7 on 2024-05-24 09:47
import uuid
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
import plane.db.models.deploy_board
def issue_estimate_point(apps, schema_editor):
Project = apps.get_model("db", "Project")
EstimatePoint = apps.get_model("db", "EstimatePoint")
Issue = apps.get_model("db", "Issue")
updated_estimate_point = []
# loop through all the projects
for project in Project.objects.filter(estimate__isnull=False):
estimate_points = EstimatePoint.objects.filter(
estimate=project.estimate, project=project
)
for issue in Issue.objects.filter(
point__isnull=False, project=project
):
# get the estimate id for the corresponding estimate point in the issue
estimate = estimate_points.filter(key=issue.point).first()
issue.estimate_point = estimate
updated_estimate_point.append(issue)
Issue.objects.bulk_update(
updated_estimate_point, ["estimate_point"], batch_size=1000
)
def last_used_estimate(apps, schema_editor):
Project = apps.get_model("db", "Project")
Estimate = apps.get_model("db", "Estimate")
# Get all estimate ids used in projects
estimate_ids = Project.objects.filter(estimate__isnull=False).values_list(
"estimate", flat=True
)
# Update all matching estimates
Estimate.objects.filter(id__in=estimate_ids).update(last_used=True)
def populate_deploy_board(apps, schema_editor):
DeployBoard = apps.get_model("db", "DeployBoard")
ProjectDeployBoard = apps.get_model("db", "ProjectDeployBoard")
DeployBoard.objects.bulk_create(
[
DeployBoard(
entity_identifier=deploy_board.project_id,
project_id=deploy_board.project_id,
entity_name="project",
anchor=deploy_board.anchor,
comments=deploy_board.comments,
reactions=deploy_board.reactions,
inbox=deploy_board.inbox,
votes=deploy_board.votes,
views=deploy_board.views,
workspace_id=deploy_board.workspace_id,
created_at=deploy_board.created_at,
updated_at=deploy_board.updated_at,
created_by_id=deploy_board.created_by_id,
updated_by_id=deploy_board.updated_by_id,
)
for deploy_board in ProjectDeployBoard.objects.all()
],
batch_size=100,
)
class Migration(migrations.Migration):
dependencies = [
("db", "0066_account_id_token_cycle_logo_props_module_logo_props"),
]
operations = [
migrations.CreateModel(
name="DeployBoard",
fields=[
(
"created_at",
models.DateTimeField(
auto_now_add=True, verbose_name="Created At"
),
),
(
"updated_at",
models.DateTimeField(
auto_now=True, verbose_name="Last Modified At"
),
),
(
"id",
models.UUIDField(
db_index=True,
default=uuid.uuid4,
editable=False,
primary_key=True,
serialize=False,
unique=True,
),
),
("entity_identifier", models.UUIDField(null=True)),
(
"entity_name",
models.CharField(
choices=[
("project", "Project"),
("issue", "Issue"),
("module", "Module"),
("cycle", "Task"),
("page", "Page"),
("view", "View"),
],
max_length=30,
),
),
(
"anchor",
models.CharField(
db_index=True,
default=plane.db.models.deploy_board.get_anchor,
max_length=255,
unique=True,
),
),
("comments", models.BooleanField(default=False)),
("reactions", models.BooleanField(default=False)),
("votes", models.BooleanField(default=False)),
("views", models.JSONField(default=dict)),
(
"created_by",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="%(class)s_created_by",
to=settings.AUTH_USER_MODEL,
verbose_name="Created By",
),
),
(
"inbox",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="board_inbox",
to="db.inbox",
),
),
(
"project",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="project_%(class)s",
to="db.project",
),
),
(
"updated_by",
models.ForeignKey(
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="%(class)s_updated_by",
to=settings.AUTH_USER_MODEL,
verbose_name="Last Modified By",
),
),
(
"workspace",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="workspace_%(class)s",
to="db.workspace",
),
),
],
options={
"verbose_name": "Deploy Board",
"verbose_name_plural": "Deploy Boards",
"db_table": "deploy_boards",
"ordering": ("-created_at",),
"unique_together": {("entity_name", "entity_identifier")},
},
),
migrations.AddField(
model_name="estimate",
name="last_used",
field=models.BooleanField(default=False),
),
# Rename the existing field
migrations.RenameField(
model_name="issue",
old_name="estimate_point",
new_name="point",
),
# Add a new field with the original name as a foreign key
migrations.AddField(
model_name="issue",
name="estimate_point",
field=models.ForeignKey(
on_delete=django.db.models.deletion.SET_NULL,
related_name="issue_estimate",
to="db.EstimatePoint",
blank=True,
null=True,
),
),
migrations.AlterField(
model_name="estimate",
name="type",
field=models.CharField(default="categories", max_length=255),
),
migrations.RunPython(issue_estimate_point),
migrations.RunPython(last_used_estimate),
migrations.RunPython(populate_deploy_board),
]

View File

@ -4,6 +4,7 @@ from .asset import FileAsset
from .base import BaseModel
from .cycle import Cycle, CycleFavorite, CycleIssue, CycleUserProperties
from .dashboard import Dashboard, DashboardWidget, Widget
from .deploy_board import DeployBoard
from .estimate import Estimate, EstimatePoint
from .exporter import ExporterHistory
from .importer import Importer
@ -53,7 +54,6 @@ from .page import Page, PageFavorite, PageLabel, PageLog
from .project import (
Project,
ProjectBaseModel,
ProjectDeployBoard,
ProjectFavorite,
ProjectIdentifier,
ProjectMember,

View File

@ -0,0 +1,52 @@
# Python imports
from uuid import uuid4
# Django imports
from django.db import models
# Module imports
from .workspace import WorkspaceBaseModel
def get_anchor():
return uuid4().hex
class DeployBoard(WorkspaceBaseModel):
TYPE_CHOICES = (
("project", "Project"),
("issue", "Issue"),
("module", "Module"),
("cycle", "Task"),
("page", "Page"),
("view", "View"),
)
entity_identifier = models.UUIDField(null=True)
entity_name = models.CharField(
max_length=30,
choices=TYPE_CHOICES,
)
anchor = models.CharField(
max_length=255, default=get_anchor, unique=True, db_index=True
)
comments = models.BooleanField(default=False)
reactions = models.BooleanField(default=False)
inbox = models.ForeignKey(
"db.Inbox",
related_name="board_inbox",
on_delete=models.SET_NULL,
null=True,
)
votes = models.BooleanField(default=False)
views = models.JSONField(default=dict)
def __str__(self):
"""Return name of the deploy board"""
return f"{self.entity_identifier} <{self.entity_name}>"
class Meta:
unique_together = ["entity_name", "entity_identifier"]
verbose_name = "Deploy Board"
verbose_name_plural = "Deploy Boards"
db_table = "deploy_boards"
ordering = ("-created_at",)

View File

@ -11,7 +11,8 @@ class Estimate(ProjectBaseModel):
description = models.TextField(
verbose_name="Estimate Description", blank=True
)
type = models.CharField(max_length=255, default="Categories")
type = models.CharField(max_length=255, default="categories")
last_used = models.BooleanField(default=False)
def __str__(self):
"""Return name of the estimate"""

View File

@ -119,11 +119,18 @@ class Issue(ProjectBaseModel):
blank=True,
related_name="state_issue",
)
estimate_point = models.IntegerField(
point = models.IntegerField(
validators=[MinValueValidator(0), MaxValueValidator(12)],
null=True,
blank=True,
)
estimate_point = models.ForeignKey(
"db.EstimatePoint",
on_delete=models.SET_NULL,
related_name="issue_estimate",
null=True,
blank=True,
)
name = models.CharField(max_length=255, verbose_name="Issue Name")
description = models.JSONField(blank=True, default=dict)
description_html = models.TextField(blank=True, default="<p></p>")

View File

@ -260,6 +260,7 @@ def get_default_views():
}
# DEPRECATED TODO: - Remove in next release
class ProjectDeployBoard(ProjectBaseModel):
anchor = models.CharField(
max_length=255, default=get_anchor, unique=True, db_index=True

View File

@ -14,7 +14,6 @@ class InstanceSerializer(BaseSerializer):
exclude = [
"license_key",
"api_key",
"version",
]
read_only_fields = [
"id",

View File

@ -50,7 +50,7 @@ class Command(BaseCommand):
instance_id=secrets.token_hex(12),
license_key=None,
api_key=secrets.token_hex(8),
version=payload.get("version"),
current_version=payload.get("version"),
last_checked_at=timezone.now(),
user_count=payload.get("user_count", 0),
)

View File

@ -0,0 +1,28 @@
# Generated by Django 4.2.7 on 2024-05-28 09:25
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('license', '0001_initial'),
]
operations = [
migrations.RenameField(
model_name='instance',
old_name='version',
new_name='current_version',
),
migrations.AddField(
model_name='instance',
name='new_version',
field=models.CharField(blank=True, max_length=10, null=True),
),
migrations.AddField(
model_name='instance',
name='product',
field=models.CharField(blank=True, max_length=50, null=True),
),
]

View File

@ -15,8 +15,10 @@ class Instance(BaseModel):
instance_id = models.CharField(max_length=25, unique=True)
license_key = models.CharField(max_length=256, null=True, blank=True)
api_key = models.CharField(max_length=16)
version = models.CharField(max_length=10)
# Instnace specifics
current_version = models.CharField(max_length=10)
new_version = models.CharField(max_length=10, blank=True, null=True)
product = models.CharField(max_length=50, blank=True, null=True)
# Instance specifics
last_checked_at = models.DateTimeField()
namespace = models.CharField(max_length=50, blank=True, null=True)
# telemetry and support

View File

@ -18,7 +18,7 @@ from plane.db.models import (
State,
IssueLink,
IssueAttachment,
ProjectDeployBoard,
DeployBoard,
)
from plane.app.serializers import (
IssueSerializer,
@ -39,7 +39,7 @@ class InboxIssuePublicViewSet(BaseViewSet):
]
def get_queryset(self):
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=self.kwargs.get("slug"),
project_id=self.kwargs.get("project_id"),
)
@ -59,7 +59,7 @@ class InboxIssuePublicViewSet(BaseViewSet):
return InboxIssue.objects.none()
def list(self, request, slug, project_id, inbox_id):
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=slug, project_id=project_id
)
if project_deploy_board.inbox is None:
@ -118,7 +118,7 @@ class InboxIssuePublicViewSet(BaseViewSet):
)
def create(self, request, slug, project_id, inbox_id):
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=slug, project_id=project_id
)
if project_deploy_board.inbox is None:
@ -189,7 +189,7 @@ class InboxIssuePublicViewSet(BaseViewSet):
return Response(serializer.data, status=status.HTTP_200_OK)
def partial_update(self, request, slug, project_id, inbox_id, pk):
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=slug, project_id=project_id
)
if project_deploy_board.inbox is None:
@ -256,7 +256,7 @@ class InboxIssuePublicViewSet(BaseViewSet):
)
def retrieve(self, request, slug, project_id, inbox_id, pk):
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=slug, project_id=project_id
)
if project_deploy_board.inbox is None:
@ -280,7 +280,7 @@ class InboxIssuePublicViewSet(BaseViewSet):
return Response(serializer.data, status=status.HTTP_200_OK)
def destroy(self, request, slug, project_id, inbox_id, pk):
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=slug, project_id=project_id
)
if project_deploy_board.inbox is None:

View File

@ -44,7 +44,7 @@ from plane.db.models import (
ProjectMember,
IssueReaction,
CommentReaction,
ProjectDeployBoard,
DeployBoard,
IssueVote,
ProjectPublicMember,
)
@ -76,7 +76,7 @@ class IssueCommentPublicViewSet(BaseViewSet):
def get_queryset(self):
try:
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=self.kwargs.get("slug"),
project_id=self.kwargs.get("project_id"),
)
@ -103,11 +103,11 @@ class IssueCommentPublicViewSet(BaseViewSet):
.distinct()
).order_by("created_at")
return IssueComment.objects.none()
except ProjectDeployBoard.DoesNotExist:
except DeployBoard.DoesNotExist:
return IssueComment.objects.none()
def create(self, request, slug, project_id, issue_id):
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=slug, project_id=project_id
)
@ -151,7 +151,7 @@ class IssueCommentPublicViewSet(BaseViewSet):
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def partial_update(self, request, slug, project_id, issue_id, pk):
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=slug, project_id=project_id
)
@ -184,7 +184,7 @@ class IssueCommentPublicViewSet(BaseViewSet):
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def destroy(self, request, slug, project_id, issue_id, pk):
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=slug, project_id=project_id
)
@ -221,7 +221,7 @@ class IssueReactionPublicViewSet(BaseViewSet):
def get_queryset(self):
try:
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=self.kwargs.get("slug"),
project_id=self.kwargs.get("project_id"),
)
@ -236,11 +236,11 @@ class IssueReactionPublicViewSet(BaseViewSet):
.distinct()
)
return IssueReaction.objects.none()
except ProjectDeployBoard.DoesNotExist:
except DeployBoard.DoesNotExist:
return IssueReaction.objects.none()
def create(self, request, slug, project_id, issue_id):
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=slug, project_id=project_id
)
@ -280,7 +280,7 @@ class IssueReactionPublicViewSet(BaseViewSet):
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def destroy(self, request, slug, project_id, issue_id, reaction_code):
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=slug, project_id=project_id
)
@ -319,7 +319,7 @@ class CommentReactionPublicViewSet(BaseViewSet):
def get_queryset(self):
try:
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=self.kwargs.get("slug"),
project_id=self.kwargs.get("project_id"),
)
@ -334,11 +334,11 @@ class CommentReactionPublicViewSet(BaseViewSet):
.distinct()
)
return CommentReaction.objects.none()
except ProjectDeployBoard.DoesNotExist:
except DeployBoard.DoesNotExist:
return CommentReaction.objects.none()
def create(self, request, slug, project_id, comment_id):
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=slug, project_id=project_id
)
@ -380,7 +380,7 @@ class CommentReactionPublicViewSet(BaseViewSet):
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def destroy(self, request, slug, project_id, comment_id, reaction_code):
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=slug, project_id=project_id
)
if not project_deploy_board.reactions:
@ -421,7 +421,7 @@ class IssueVotePublicViewSet(BaseViewSet):
def get_queryset(self):
try:
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=self.kwargs.get("slug"),
project_id=self.kwargs.get("project_id"),
)
@ -434,7 +434,7 @@ class IssueVotePublicViewSet(BaseViewSet):
.filter(project_id=self.kwargs.get("project_id"))
)
return IssueVote.objects.none()
except ProjectDeployBoard.DoesNotExist:
except DeployBoard.DoesNotExist:
return IssueVote.objects.none()
def create(self, request, slug, project_id, issue_id):
@ -513,7 +513,7 @@ class ProjectIssuesPublicEndpoint(BaseAPIView):
]
def get(self, request, slug, project_id):
if not ProjectDeployBoard.objects.filter(
if not DeployBoard.objects.filter(
workspace__slug=slug, project_id=project_id
).exists():
return Response(

View File

@ -11,10 +11,10 @@ from rest_framework.permissions import AllowAny
# Module imports
from .base import BaseAPIView
from plane.app.serializers import ProjectDeployBoardSerializer
from plane.app.serializers import DeployBoardSerializer
from plane.db.models import (
Project,
ProjectDeployBoard,
DeployBoard,
)
@ -24,10 +24,10 @@ class ProjectDeployBoardPublicSettingsEndpoint(BaseAPIView):
]
def get(self, request, slug, project_id):
project_deploy_board = ProjectDeployBoard.objects.get(
project_deploy_board = DeployBoard.objects.get(
workspace__slug=slug, project_id=project_id
)
serializer = ProjectDeployBoardSerializer(project_deploy_board)
serializer = DeployBoardSerializer(project_deploy_board)
return Response(serializer.data, status=status.HTTP_200_OK)
@ -41,7 +41,7 @@ class WorkspaceProjectDeployBoardEndpoint(BaseAPIView):
Project.objects.filter(workspace__slug=slug)
.annotate(
is_public=Exists(
ProjectDeployBoard.objects.filter(
DeployBoard.objects.filter(
workspace__slug=slug, project_id=OuterRef("pk")
)
)