Skip to content

feat(workspace): add delete workspace with cascade delete#285

Merged
l1ttps merged 6 commits intomainfrom
delete-workspace
Feb 26, 2026
Merged

feat(workspace): add delete workspace with cascade delete#285
l1ttps merged 6 commits intomainfrom
delete-workspace

Conversation

@l1ttps
Copy link
Copy Markdown
Member

@l1ttps l1ttps commented Feb 26, 2026

No description provided.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @l1ttps, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a critical feature allowing users to delete workspaces, along with all their dependent data, through a cascade deletion mechanism. The changes span both the backend API, where database entity relationships were updated for cascade deletion, and the frontend console, which now includes a dedicated UI component for initiating and confirming workspace deletions. This ensures data consistency and provides users with full control over their workspace lifecycle.

Highlights

  • Workspace Deletion with Cascade: Implemented the functionality to delete a workspace, ensuring that all associated data (assets, asset groups, issues, notifications, statistics, targets, templates, tools, workers, and workflows) are automatically removed due to cascade delete configurations in the database entities.
  • Frontend UI for Workspace Deletion: Introduced a new DeleteWorkspace component in the console, providing a confirmation dialog for users before permanently deleting a workspace. This component is integrated into the workspace settings table.
  • Database Schema Updates: Modified numerous TypeORM entity relations across the core-api to include onDelete: 'CASCADE', ensuring referential integrity and automatic cleanup of related records when a parent workspace is deleted.
  • Workspace Creation Enhancements: Updated the workspace creation process to explicitly generate a UUID for new workspaces and include the workspaceId when sending workspace creation notifications.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • console/src/pages/asset-group/asset-groups.tsx
    • Removed conditional rendering for an error message when asset groups data is not available, simplifying the initial loading state.
  • console/src/pages/assets/list-assets.tsx
    • Adjusted whitespace by adding a blank line for formatting consistency.
  • console/src/pages/settings/components/delete-workspace.tsx
    • Added a new component DeleteWorkspace to handle the deletion of a workspace, including a confirmation dialog and API integration for the delete operation.
  • console/src/pages/settings/components/edit-workspace-dialog.tsx
    • Removed the TooltipProvider and Tooltip components wrapping the edit button, simplifying the UI structure.
    • Updated the DialogContent class name for styling adjustments.
  • console/src/pages/settings/components/workspace-columns.tsx
    • Replaced the ArchivedWorkspace component with the new DeleteWorkspace component in the actions column for workspace management.
  • core-api/src/modules/asset-group/entities/asset-groups-assets.entity.ts
    • Configured onDelete: 'CASCADE' for the assetGroup and asset ManyToOne relations, ensuring associated records are deleted when the parent is removed.
  • core-api/src/modules/asset-group/entities/asset-groups-workflows.entity.ts
    • Configured onDelete: 'CASCADE' for the assetGroup and workflow ManyToOne relations, ensuring associated records are deleted when the parent is removed.
  • core-api/src/modules/asset-group/entities/asset-groups.entity.ts
    • Configured onDelete: 'CASCADE' for the workspace ManyToOne relation, ensuring associated records are deleted when the parent is removed.
  • core-api/src/modules/issues/entities/issue-comment.entity.ts
    • Configured onDelete: 'CASCADE' for the issue ManyToOne relation, ensuring associated records are deleted when the parent is removed.
  • core-api/src/modules/issues/entities/issue.entity.ts
    • Configured onDelete: 'CASCADE' for the workspace ManyToOne relation, ensuring associated records are deleted when the parent is removed.
  • core-api/src/modules/notifications/dto/create-notification.dto.ts
    • Added an optional workspaceId property to the CreateNotificationDto.
  • core-api/src/modules/notifications/processors/notifications.processor.ts
    • Updated the notification processing logic to include the workspaceId when saving new notifications.
  • core-api/src/modules/statistic/entities/statistic.entity.ts
    • Configured onDelete: 'CASCADE' for the workspace ManyToOne relation, ensuring associated records are deleted when the parent is removed.
  • core-api/src/modules/targets/entities/workspace-target.entity.ts
    • Changed WorkspaceTarget to extend BaseEntity, inheriting common entity properties.
    • Removed the explicit id primary generated column as it is now inherited from BaseEntity.
  • core-api/src/modules/templates/entities/templates.entity.ts
    • Replaced cascade: true with onDelete: 'CASCADE' for the workspace ManyToOne relation, explicitly defining cascade deletion behavior.
  • core-api/src/modules/tools/entities/workspace_tools.entity.ts
    • Configured onDelete: 'CASCADE' for the workspace ManyToOne relation, ensuring associated records are deleted when the parent is removed.
  • core-api/src/modules/workers/entities/worker.entity.ts
    • Configured onDelete: 'CASCADE' for the workspace ManyToOne relation, ensuring associated records are deleted when the parent is removed.
  • core-api/src/modules/workflows/entities/workflow.entity.ts
    • Configured onDelete: 'CASCADE' for the workspace ManyToOne relation, ensuring associated records are deleted when the parent is removed.
    • Updated the workspace ManyToOne relation to correctly reference workspace.workflows.
  • core-api/src/modules/workspaces/entities/workspace.entity.ts
    • Imported the Workflow entity.
    • Removed a redundant Workflow import statement.
    • Configured onDelete: 'CASCADE' for the workspaceTargets OneToMany relation, ensuring associated records are deleted when the parent is removed.
  • core-api/src/modules/workspaces/workspaces.service.ts
    • Imported randomUUID for generating unique identifiers.
    • Removed empty onModuleInit method implementations.
    • Introduced newWorkspaceId using randomUUID before saving a new workspace.
    • Assigned the generated newWorkspaceId to the new workspace.
    • Included the workspaceId in the notification created upon workspace creation.
    • Changed the workspace deletion method from softDelete to delete, enabling permanent removal and triggering cascade operations.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request implements cascade deletion for workspaces, so that when a workspace is deleted, all its related data is also removed from the database. This is achieved by adding onDelete: 'CASCADE' to various entity relationships in the backend and replacing the soft delete with a hard delete. On the frontend, the 'Archive' action is replaced with a 'Delete' action.

My review has identified a few areas for improvement:

  • A regression in error handling in the asset groups page.
  • An incorrect Tailwind CSS class in the edit workspace dialog.
  • A redundant TypeORM option in the workspace entity.
  • An opportunity to simplify code in the workspace service by removing unnecessary manual ID generation.

Overall, the changes are in the right direction to implement the desired feature.

const assetGroups = data?.data ?? [];
const total = data?.total ?? 0;

if (!data && !isLoading) return <div>Error loading asset groups.</div>;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The explicit error handling for the case where data fetching fails has been removed. Now, if there's an error, the page will just show an empty table which might be confusing for the user. It would be better to restore some form of error handling to inform the user when something goes wrong. You can achieve this by using the isError flag from the useAssetGroupControllerGetAll hook.

</Button>
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent className="sm:max-w-[425px]">
<DialogContent className="sm:max-w-106.25">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The Tailwind CSS class sm:max-w-106.25 is not a standard Tailwind class and is likely a typo. The original value was sm:max-w-[425px]. To ensure consistent styling, please revert to the previous value or use a corresponding rem value like sm:max-w-[26.5rem].

Suggested change
<DialogContent className="sm:max-w-106.25">
<DialogContent className="sm:max-w-[425px]">

@OneToMany(
() => WorkspaceTarget,
(workspaceTarget) => workspaceTarget.workspace,
{ onDelete: 'CASCADE' },
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The onDelete: 'CASCADE' option on a @OneToMany relationship has no effect on the database schema and can be misleading. The cascade behavior for deletions is defined on the @ManyToOne side of the relationship, which is correctly set in workspace-target.entity.ts. This option should be removed to avoid confusion.

Comment on lines +80 to +81
const newWorkspaceId = randomUUID();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Part 1 of 3: Manually generating the UUID is unnecessary as the database is configured to do this automatically. This can be removed. Please see the subsequent comments for the rest of this refactoring.

const newWorkspaceId = randomUUID();

const newWorkspace = await this.repo.save({
id: newWorkspaceId,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Part 2 of 3: This line can be removed as the database will generate the ID.

await this.notificationsService.createNotification({
recipients: [id],
scope: NotificationScope.USER,
workspaceId: newWorkspaceId,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Part 3 of 3: Since the manually generated ID is removed, you should use the ID from the created workspace object (newWorkspace.id).

Suggested change
workspaceId: newWorkspaceId,
workspaceId: newWorkspace.id,

@l1ttps l1ttps merged commit 0b79a63 into main Feb 26, 2026
9 checks passed
@l1ttps l1ttps deleted the delete-workspace branch March 4, 2026 07:36
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.

1 participant