Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions apiserver/plane/app/views/issue/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
from plane.bgtasks.recent_visited_task import recent_visited_task
from plane.utils.global_paginator import paginate
from plane.bgtasks.webhook_task import model_activity
from plane.bgtasks.issue_description_version_task import issue_description_version_task


class IssueListEndpoint(BaseAPIView):
Expand Down Expand Up @@ -428,6 +429,13 @@ def create(self, request, slug, project_id):
slug=slug,
origin=request.META.get("HTTP_ORIGIN"),
)
# updated issue description version
issue_description_version_task.delay(
updated_issue=json.dumps(request.data, cls=DjangoJSONEncoder),
issue_id=str(serializer.data["id"]),
user_id=request.user.id,
is_creating=True,
)
return Response(issue, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Expand Down Expand Up @@ -649,6 +657,12 @@ def partial_update(self, request, slug, project_id, pk=None):
slug=slug,
origin=request.META.get("HTTP_ORIGIN"),
)
# updated issue description version
issue_description_version_task.delay(
updated_issue=current_instance,
issue_id=str(serializer.data.get("id", None)),
user_id=request.user.id,
)
return Response(status=status.HTTP_204_NO_CONTENT)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Expand Down
84 changes: 84 additions & 0 deletions apiserver/plane/bgtasks/issue_description_version_task.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from celery import shared_task
from django.db import transaction
from django.utils import timezone
from typing import Optional, Dict
import json

from plane.db.models import Issue, IssueDescriptionVersion
from plane.utils.exception_logger import log_exception


def should_update_existing_version(
version: IssueDescriptionVersion, user_id: str, max_time_difference: int = 600
) -> bool:
if not version:
return

time_difference = (timezone.now() - version.last_saved_at).total_seconds()
return (
str(version.owned_by_id) == str(user_id)
and time_difference <= max_time_difference
)


def update_existing_version(version: IssueDescriptionVersion, issue) -> None:
version.description_json = issue.description
version.description_html = issue.description_html
version.description_binary = issue.description_binary
version.description_stripped = issue.description_stripped
version.last_saved_at = timezone.now()

version.save(
update_fields=[
"description_json",
"description_html",
"description_binary",
"description_stripped",
"last_saved_at",
]
)


@shared_task
def issue_description_version_task(
updated_issue, issue_id, user_id, is_creating=False
) -> Optional[bool]:
try:
# Parse updated issue data
current_issue: Dict = json.loads(updated_issue) if updated_issue else {}

# Get current issue
issue = Issue.objects.get(id=issue_id)

# Check if description has changed
if (
current_issue.get("description_html") == issue.description_html
and not is_creating
):
return

with transaction.atomic():
# Get latest version
latest_version = (
IssueDescriptionVersion.objects.filter(issue_id=issue_id)
.order_by("-last_saved_at")
.first()
)

# Determine whether to update existing or create new version
if should_update_existing_version(version=latest_version, user_id=user_id):
update_existing_version(latest_version, issue)
else:
IssueDescriptionVersion.log_issue_description_version(issue, user_id)

return

except Issue.DoesNotExist:
# Issue no longer exists, skip processing
return
except json.JSONDecodeError as e:
log_exception(f"Invalid JSON for updated_issue: {e}")
return
except Exception as e:
log_exception(f"Error processing issue description version: {e}")
return
10 changes: 7 additions & 3 deletions apiserver/plane/db/models/issue.py
Original file line number Diff line number Diff line change
Expand Up @@ -804,13 +804,17 @@ def log_issue_description_version(cls, issue, user):
Log the issue description version
"""
cls.objects.create(
issue=issue,
workspace_id=issue.workspace_id,
project_id=issue.project_id,
created_by_id=issue.created_by_id,
updated_by_id=issue.updated_by_id,
owned_by_id=user,
last_saved_at=timezone.now(),
issue_id=issue.id,
description_binary=issue.description_binary,
description_html=issue.description_html,
description_stripped=issue.description_stripped,
description_json=issue.description,
last_saved_at=timezone.now(),
owned_by=user,
)
return True
except Exception as e:
Expand Down
3 changes: 3 additions & 0 deletions apiserver/plane/settings/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,9 @@
"plane.license.bgtasks.tracer",
# management tasks
"plane.bgtasks.dummy_data_task",
# issue version tasks
"plane.bgtasks.issue_version_sync",
"plane.bgtasks.issue_description_version_sync",
)

# Sentry Settings
Expand Down