From 3e7d6db43bc70d3c7b727230fba7f44dd1a28fdc Mon Sep 17 00:00:00 2001 From: NarayanBavisetti Date: Tue, 23 Dec 2025 19:18:44 +0530 Subject: [PATCH 1/5] chore: updated the logic for page version task --- apps/api/plane/app/views/page/base.py | 12 +++-- apps/api/plane/bgtasks/page_version_task.py | 55 ++++++++++++++++----- 2 files changed, 49 insertions(+), 18 deletions(-) diff --git a/apps/api/plane/app/views/page/base.py b/apps/api/plane/app/views/page/base.py index d3ad49b5fda..1442b15ac75 100644 --- a/apps/api/plane/app/views/page/base.py +++ b/apps/api/plane/app/views/page/base.py @@ -541,26 +541,28 @@ def partial_update(self, request, slug, project_id, page_id): status=status.HTTP_400_BAD_REQUEST, ) + # Store the old description_html before saving (needed for both tasks) + old_description_html = page.description_html + # Serialize the existing instance existing_instance = json.dumps({"description_html": page.description_html}, cls=DjangoJSONEncoder) # Use serializer for validation and update serializer = PageBinaryUpdateSerializer(page, data=request.data, partial=True) if serializer.is_valid(): + serializer.save() + # Capture the page transaction if request.data.get("description_html"): page_transaction.delay( new_description_html=request.data.get("description_html", "

"), - old_description_html=page.description_html, + old_description_html=old_description_html, page_id=page_id, ) - # Update the page using serializer - updated_page = serializer.save() - # Run background tasks page_version.delay( - page_id=updated_page.id, + page_id=page_id, existing_instance=existing_instance, user_id=request.user.id, ) diff --git a/apps/api/plane/bgtasks/page_version_task.py b/apps/api/plane/bgtasks/page_version_task.py index 4de2387becf..2f31aa36410 100644 --- a/apps/api/plane/bgtasks/page_version_task.py +++ b/apps/api/plane/bgtasks/page_version_task.py @@ -1,9 +1,13 @@ # Python imports import json + # Third party imports from celery import shared_task +# Django imports +from django.utils import timezone + # Module imports from plane.db.models import Page, PageVersion from plane.utils.exception_logger import log_exception @@ -17,28 +21,53 @@ def page_version(page_id, existing_instance, user_id): # Get the current instance current_instance = json.loads(existing_instance) if existing_instance is not None else {} + sub_pages = {} + # Create a version if description_html is updated if current_instance.get("description_html") != page.description_html: - # Create a new page version - PageVersion.objects.create( - page_id=page_id, - workspace_id=page.workspace_id, - description_html=page.description_html, - description_binary=page.description_binary, - owned_by_id=user_id, - last_saved_at=page.updated_at, - description_json=page.description, - description_stripped=page.description_stripped, - ) + # Fetch the latest page version + page_version = PageVersion.objects.filter(page_id=page_id).order_by("-last_saved_at").first() + # Get the latest page version if it exists and is owned by the user + if ( + page_version + and str(page_version.owned_by_id) == str(user_id) + and (timezone.now() - page_version.last_saved_at).total_seconds() <= 600 + ): + + page_version.description_html = page.description_html + page_version.description_binary = page.description_binary + page_version.description_json = page.description + page_version.description_stripped = page.description_stripped + page_version.sub_pages_data = sub_pages + page_version.save( + update_fields=[ + "description_html", + "description_binary", + "description_json", + "description_stripped", + "sub_pages_data", + ] + ) + else: + # Create a new page version + PageVersion.objects.create( + page_id=page_id, + workspace_id=page.workspace_id, + description_json=page.description, + description_html=page.description_html, + description_binary=page.description_binary, + description_stripped=page.description_stripped, + owned_by_id=user_id, + last_saved_at=timezone.now(), + sub_pages_data=sub_pages, + ) # If page versions are greater than 20 delete the oldest one if PageVersion.objects.filter(page_id=page_id).count() > 20: # Delete the old page version PageVersion.objects.filter(page_id=page_id).order_by("last_saved_at").first().delete() - return - except Page.DoesNotExist: return except Exception as e: log_exception(e) From 2c22e55b129b0286df6454c15fb45e2dd98e3611 Mon Sep 17 00:00:00 2001 From: NarayanBavisetti Date: Tue, 23 Dec 2025 19:22:54 +0530 Subject: [PATCH 2/5] chore: updated the html variable --- apps/api/plane/app/views/page/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/api/plane/app/views/page/base.py b/apps/api/plane/app/views/page/base.py index 1442b15ac75..0f35f2a7639 100644 --- a/apps/api/plane/app/views/page/base.py +++ b/apps/api/plane/app/views/page/base.py @@ -545,7 +545,7 @@ def partial_update(self, request, slug, project_id, page_id): old_description_html = page.description_html # Serialize the existing instance - existing_instance = json.dumps({"description_html": page.description_html}, cls=DjangoJSONEncoder) + existing_instance = json.dumps({"description_html": old_description_html}, cls=DjangoJSONEncoder) # Use serializer for validation and update serializer = PageBinaryUpdateSerializer(page, data=request.data, partial=True) From 9eda8ba5cd020e2f16c3728847304ba34db04d5a Mon Sep 17 00:00:00 2001 From: NarayanBavisetti Date: Tue, 23 Dec 2025 19:26:33 +0530 Subject: [PATCH 3/5] chore: handled the exception --- apps/api/plane/bgtasks/page_version_task.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/api/plane/bgtasks/page_version_task.py b/apps/api/plane/bgtasks/page_version_task.py index 2f31aa36410..c9939a16ae1 100644 --- a/apps/api/plane/bgtasks/page_version_task.py +++ b/apps/api/plane/bgtasks/page_version_task.py @@ -68,6 +68,8 @@ def page_version(page_id, existing_instance, user_id): # Delete the old page version PageVersion.objects.filter(page_id=page_id).order_by("last_saved_at").first().delete() + return + except Page.DoesNotExist: return except Exception as e: log_exception(e) From 8a42affe754abd6643641b49717f81147d982656 Mon Sep 17 00:00:00 2001 From: NarayanBavisetti Date: Wed, 24 Dec 2025 15:12:59 +0530 Subject: [PATCH 4/5] chore: changed the function name --- apps/api/plane/app/views/page/base.py | 4 ++-- apps/api/plane/bgtasks/page_version_task.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/api/plane/app/views/page/base.py b/apps/api/plane/app/views/page/base.py index 0f35f2a7639..820f982f6bd 100644 --- a/apps/api/plane/app/views/page/base.py +++ b/apps/api/plane/app/views/page/base.py @@ -46,7 +46,7 @@ # Local imports from ..base import BaseAPIView, BaseViewSet from plane.bgtasks.page_transaction_task import page_transaction -from plane.bgtasks.page_version_task import page_version +from plane.bgtasks.page_version_task import track_page_version from plane.bgtasks.recent_visited_task import recent_visited_task from plane.bgtasks.copy_s3_object import copy_s3_objects_of_description_and_assets from plane.app.permissions import ProjectPagePermission @@ -561,7 +561,7 @@ def partial_update(self, request, slug, project_id, page_id): ) # Run background tasks - page_version.delay( + track_page_version.delay( page_id=page_id, existing_instance=existing_instance, user_id=request.user.id, diff --git a/apps/api/plane/bgtasks/page_version_task.py b/apps/api/plane/bgtasks/page_version_task.py index c9939a16ae1..3ca50bde6da 100644 --- a/apps/api/plane/bgtasks/page_version_task.py +++ b/apps/api/plane/bgtasks/page_version_task.py @@ -14,7 +14,7 @@ @shared_task -def page_version(page_id, existing_instance, user_id): +def track_page_version(page_id, existing_instance, user_id): try: # Get the page page = Page.objects.get(id=page_id) @@ -48,6 +48,7 @@ def page_version(page_id, existing_instance, user_id): "description_json", "description_stripped", "sub_pages_data", + "updated_at" ] ) else: From aece92183da9dff3fe7e88e9c2c14559a7e496ad Mon Sep 17 00:00:00 2001 From: NarayanBavisetti Date: Wed, 24 Dec 2025 15:19:48 +0530 Subject: [PATCH 5/5] chore: added a custom variable --- apps/api/plane/bgtasks/page_version_task.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/api/plane/bgtasks/page_version_task.py b/apps/api/plane/bgtasks/page_version_task.py index 3ca50bde6da..dd825987484 100644 --- a/apps/api/plane/bgtasks/page_version_task.py +++ b/apps/api/plane/bgtasks/page_version_task.py @@ -12,6 +12,7 @@ from plane.db.models import Page, PageVersion from plane.utils.exception_logger import log_exception +PAGE_VERSION_TASK_TIMEOUT = 600 @shared_task def track_page_version(page_id, existing_instance, user_id): @@ -33,7 +34,7 @@ def track_page_version(page_id, existing_instance, user_id): if ( page_version and str(page_version.owned_by_id) == str(user_id) - and (timezone.now() - page_version.last_saved_at).total_seconds() <= 600 + and (timezone.now() - page_version.last_saved_at).total_seconds() <= PAGE_VERSION_TASK_TIMEOUT ): page_version.description_html = page.description_html