Skip to content

[WEB-3744] Append the deleted_at timestamp to workspace slug when it is deleted#6862

Merged
sriramveeraghanta merged 1 commit intopreviewfrom
fix-workspace-softdeleted-slug
Apr 2, 2025
Merged

[WEB-3744] Append the deleted_at timestamp to workspace slug when it is deleted#6862
sriramveeraghanta merged 1 commit intopreviewfrom
fix-workspace-softdeleted-slug

Conversation

@dheeru0198
Copy link
Member

@dheeru0198 dheeru0198 commented Apr 2, 2025

Description

This releases the slug of a soft deleted workspace to be used again.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Feature (non-breaking change which adds functionality)
  • Improvement (change that would cause existing functionality to not work as expected)
  • Code refactoring
  • Performance improvements
  • Documentation update

Screenshots and Media (if applicable)

Test Scenarios

References

@makeplane
Copy link

makeplane bot commented Apr 2, 2025

Pull Request Linked with Plane Work Items

Comment Automatically Generated by Plane

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 2, 2025

Walkthrough

This pull request introduces a new management command that updates the slug of a soft-deleted workspace by appending its deletion epoch timestamp. The command accepts a workspace slug and an optional dry-run flag to simulate the update. In addition, the Workspace model now overrides its delete method to append the timestamp to the slug during soft deletion and updates its user preferences by adding two new keys. Error handling has been improved to provide detailed feedback in different execution scenarios.

Changes

File(s) Change Summary
apiserver/.../update_deleted_workspace_slug.py Adds a management command that updates a soft-deleted workspace's slug with an epoch timestamp, including a --dry-run option and comprehensive error handling for various cases.
apiserver/.../workspace.py Overrides the Workspace delete method to append an epoch timestamp to the slug on soft deletion, and extends the user preference keys with DRAFTS and YOUR_WORK; includes new imports and type annotations.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Command
    participant WorkspaceModel
    participant DB
    User->>Command: Execute command with slug and optional --dry-run flag
    Command->>WorkspaceModel: Retrieve workspace by slug
    alt Workspace not found or not soft-deleted
        WorkspaceModel--)Command: Return error/warning
        Command->>User: Display error/warning message
    else Valid soft-deleted workspace
        Command->>WorkspaceModel: Get deletion timestamp
        alt --dry-run enabled
            Command->>User: Display simulated new slug
        else
            Command->>DB: Begin transaction
            DB->>WorkspaceModel: Update slug with appended timestamp
            Command->>DB: Commit transaction
            Command->>User: Display success message
        end
    end
Loading
sequenceDiagram
    participant Caller
    participant WorkspaceInstance
    participant DB
    Caller->>WorkspaceInstance: Call delete(soft=True)
    WorkspaceInstance->>WorkspaceInstance: Invoke parent delete method
    WorkspaceInstance->>WorkspaceInstance: Check for soft delete condition (presence of deleted_at)
    WorkspaceInstance->>WorkspaceInstance: Append epoch timestamp to slug
    WorkspaceInstance->>DB: Save updated workspace
    DB->>Caller: Return deletion result
Loading

Possibly related PRs

Suggested labels

🐛bug, ⚙️backend

Suggested reviewers

  • sriramveeraghanta
  • SatishGandham
  • rahulramesha

Poem

I'm a rabbit with hops so fleet,
In code meanderings, I found a treat.
Slugs get a timestamp, a magical twist,
Soft-deleted woes now cease to exist.
Leap and bound with joy—code's a sweet feat!
🐰🚀

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (6)
apiserver/plane/db/models/workspace.py (2)

4-6: Clean up unused imports

Several imports are added but not used in the code:

  • time module
  • django.utils.timezone
  • typing.Tuple and typing.Dict
-import time
-from django.utils import timezone
-from typing import Optional, Any, Tuple, Dict
+from typing import Optional, Any
🧰 Tools
🪛 Ruff (0.8.2)

4-4: time imported but unused

Remove unused import: time

(F401)


5-5: django.utils.timezone imported but unused

Remove unused import: django.utils.timezone

(F401)


6-6: typing.Tuple imported but unused

Remove unused import

(F401)


6-6: typing.Dict imported but unused

Remove unused import

(F401)


155-181: LGTM! Overriding delete to preserve unique slugs

This implementation correctly modifies the workspace slug during soft deletion by appending a timestamp, ensuring that the slug remains unique. This is essential for allowing new workspaces to be created later with previously used slugs.

Consider shortening line 163 to comply with the line length limit:

-        Override the delete method to append epoch timestamp to the slug when soft deleting.
+        Override the delete method to append epoch timestamp to the slug when soft deleting.
+        This ensures slug uniqueness after deletion.
🧰 Tools
🪛 Ruff (0.8.2)

163-163: Line too long (92 > 88)

(E501)

apiserver/plane/db/management/commands/update_deleted_workspace_slug.py (4)

1-5: Remove unused import

The time module is imported but not used in this file.

-import time
from django.core.management.base import BaseCommand
from django.db import transaction
from plane.db.models import Workspace
🧰 Tools
🪛 Ruff (0.8.2)

1-1: time imported but unused

Remove unused import: time

(F401)


7-21: Well-structured management command with clear help text and arguments

The command provides a clear description of its purpose and properly defines the required arguments. The dry-run option is a good practice for potentially destructive operations.

Shorten the help text to comply with line length limits:

-    help = "Updates the slug of a soft-deleted workspace by appending the epoch timestamp"
+    help = "Update soft-deleted workspace slugs by adding timestamp"
🧰 Tools
🪛 Ruff (0.8.2)

8-8: Line too long (90 > 88)

(E501)


27-52: Good error handling with informative messages

The command includes comprehensive validation checks:

  1. Verifies the workspace exists
  2. Confirms the workspace is actually soft-deleted
  3. Checks if the slug already has a timestamp appended

These checks prevent unnecessary operations and provide clear feedback to the user.

Consider shortening the longer lines to comply with the style guide:

-                    f"Workspace '{workspace.name}' (slug: {workspace.slug}) is not deleted."
+                    f"Workspace '{workspace.name}' is not deleted."
-                    f"Workspace '{workspace.name}' (slug: {workspace.slug}) already has a timestamp appended."
+                    f"Workspace '{workspace.name}' already has a timestamp appended."
🧰 Tools
🪛 Ruff (0.8.2)

39-39: Line too long (92 > 88)

(E501)


48-48: Line too long (110 > 88)

(E501)


53-78: Transaction-based approach with proper success/error handling

The implementation correctly uses a database transaction to ensure atomicity when updating the workspace slug. The dry-run option provides a safe way to preview changes before applying them.

The success message on line 70 needs correction - it's showing the old slug as both the original and new value:

-                            f"Updated workspace '{workspace.name}' slug from '{workspace.slug}' to '{new_slug}'"
+                            f"Updated workspace '{workspace.name}' slug to '{new_slug}'"

Also, consider shortening line 61 to comply with the style guide:

-                f"Would update workspace '{workspace.name}' slug from '{workspace.slug}' to '{new_slug}'"
+                f"Would update workspace '{workspace.name}' slug to '{new_slug}'"
🧰 Tools
🪛 Ruff (0.8.2)

61-61: Line too long (105 > 88)

(E501)


70-70: Line too long (112 > 88)

(E501)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 16aa1d7 and 03834d4.

📒 Files selected for processing (2)
  • apiserver/plane/db/management/commands/update_deleted_workspace_slug.py (1 hunks)
  • apiserver/plane/db/models/workspace.py (3 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
apiserver/plane/db/management/commands/update_deleted_workspace_slug.py (1)
apiserver/plane/db/models/workspace.py (2)
  • Workspace (117-187)
  • save (201-204)
🪛 Ruff (0.8.2)
apiserver/plane/db/management/commands/update_deleted_workspace_slug.py

1-1: time imported but unused

Remove unused import: time

(F401)


8-8: Line too long (90 > 88)

(E501)


39-39: Line too long (92 > 88)

(E501)


48-48: Line too long (110 > 88)

(E501)


61-61: Line too long (105 > 88)

(E501)


70-70: Line too long (112 > 88)

(E501)

apiserver/plane/db/models/workspace.py

4-4: time imported but unused

Remove unused import: time

(F401)


5-5: django.utils.timezone imported but unused

Remove unused import: django.utils.timezone

(F401)


6-6: typing.Tuple imported but unused

Remove unused import

(F401)


6-6: typing.Dict imported but unused

Remove unused import

(F401)


163-163: Line too long (92 > 88)

(E501)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: Analyze (python)
🔇 Additional comments (1)
apiserver/plane/db/models/workspace.py (1)

425-431: LGTM! Added new user preference keys

The new DRAFTS and YOUR_WORK keys have been added to the UserPreferenceKeys enum, which expands the options for user preferences.

@plane-bot plane-bot changed the title [WEB-3744] Append the deleted_at timestamp to workspcace slug when it's soft deleted [WEB-3744] Append the deleted_at timestamp to workspace slug when it is deleted Apr 2, 2025
@sriramveeraghanta sriramveeraghanta merged commit 81fae36 into preview Apr 2, 2025
5 of 6 checks passed
@sriramveeraghanta sriramveeraghanta deleted the fix-workspace-softdeleted-slug branch April 2, 2025 17:37
lifeiscontent pushed a commit that referenced this pull request Aug 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[bug]: Soft-deleted workspaces still prevent creation of new workspaces with same slug

3 participants