Skip to content

Add non-destructive user deletion: preserve, anonymize, or transfer links #1008

@soerendohmen

Description

@soerendohmen

Description

When an admin deletes a user, all links owned by that user are deleted as well. This is technically caused by the links.user_id foreign key using ON DELETE CASCADE.

While the delete confirmation dialog mentions that all user data including links will be deleted, this behavior is risky for production URL shortener instances: short links may already be published externally, embedded in documents, emails, QR codes, or websites. Deleting a user can therefore unexpectedly break public short URLs.

Current behavior

Deleting a user deletes their short links.

Example:

  1. User A creates short link https://example.com/abc12
  2. Admin deletes User A
  3. https://example.com/abc12 no longer works because the link record was deleted

Expected behavior

Kutt should provide a non-destructive offboarding option for users.

Possible options:

  • Preserve links and set user_id to NULL
  • Transfer all links to another user/admin
  • Explicitly delete links only when the admin chooses that option
  • Show link count in the confirmation dialog before deletion

A safer default could be:

  • Delete user account
  • Preserve existing links as unowned/anonymous links
  • Preserve link statistics if possible

Why this matters

In a URL shortener, links are production data. Deleting an account should not necessarily invalidate already published short URLs. Many administrators need to remove or offboard users while keeping existing short links alive.

Possible implementation

Change the foreign key behavior for links.user_id from ON DELETE CASCADE to ON DELETE SET NULL, or add an explicit user deletion flow that first transfers/anonymizes links before deleting the user.

Related tables such as visits/statistics may also need to be considered so statistics are not unintentionally removed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions