Skip to content

Customer deletion fails due to foreign key constraints and leaves orphaned Users #2395

@VincentTeresa

Description

@VincentTeresa

Context

I'm working on an e-commerce site using Lunar where users can register, make purchases, and manage their accounts. The platform needs to handle customer account deletion properly when requested by users or administrators.

What I'm Trying to Do

Delete customers from the admin panel (/admin/customers) either individually or through bulk actions, ensuring that all related data is properly cleaned up, including associated Users.

The Problem

When attempting to delete a Customer that has associated data (carts, orders, addresses), the deletion fails with foreign key constraint violations. Additionally, when deletion is forced through bulk actions, it only detaches the User relationship, leaving orphaned User records in the database that prevent email reuse for new registrations.

What I've Checked

  • Reviewed the CustomerObserver implementation
  • Analyzed database migrations and foreign key constraints
  • Checked for cascade delete configurations
  • Searched for existing issues related to customer deletion
  • Verified this affects both individual and bulk delete actions

Steps to Reproduce

  1. Register a new user in the frontend (creates both User and Customer)
  2. Add products to cart as that user
  3. Navigate to admin panel → Customers
  4. Attempt to delete the customer using bulk action
  5. Observe the foreign key constraint error
  6. If deletion succeeds (empty cart), check Users table - the User remains orphaned

Current Result

SQLSTATE[23000]: Integrity constraint violation: 1451 Cannot delete or update a parent row:
a foreign key constraint fails (`database`.`lunar_carts`, CONSTRAINT `lunar_carts_customer_id_foreign`
FOREIGN KEY (`customer_id`) REFERENCES `lunar_customers` (`id`))

Expected Result

Customer deletion should:

  1. Handle or cascade delete related records (carts, addresses, etc.)
  2. Either delete or properly handle associated Users
  3. Allow email addresses to be reused after account deletion

Technical Details

Affected File: packages/core/src/Observers/CustomerObserver.php

Current implementation:

public function deleting(CustomerContract $customer)
{
    $customer->customerGroups()->detach();
    $customer->discounts()->detach();
    $customer->users()->detach();  // Only detaches, doesn't delete
    // Missing: cart handling, address handling, user cleanup
}

Related Issues

  • Missing individual delete action in CustomerResource pages
  • No cascade delete in foreign key constraints
  • No user lifecycle management

Proposed Solution

Enhanced CustomerObserver that properly handles all relationships:

public function deleting(CustomerContract $customer)
{
    // Handle carts and their lines
    $customer->carts()->each(function ($cart) {
        $cart->lines()->delete();
        $cart->delete();
    });

    // Handle addresses
    $customer->addresses()->delete();

    // Handle users (delete if no other customers)
    $customer->users()->each(function ($user) {
        if ($user->customers()->count() === 1) {
            $user->delete();
        }
    });

    // Existing detachments
    $customer->customerGroups()->detach();
    $customer->discounts()->detach();
    $customer->users()->detach();
}

Additionally, add delete action to CustomerResource pages:

// In EditCustomer.php and ViewCustomer.php
protected function getDefaultHeaderActions(): array
{
    return [
        Actions\DeleteAction::make()
            ->requiresConfirmation(),
    ];
}

Environment

  • Lunar version: 1.0.0-rc.7
  • Laravel Version: 11.47.0
  • PHP Version: 8.4.15
  • Database Driver & Version: MySQL 8.0

Why This Matters

This is a critical issue for any production e-commerce site because:

  1. GDPR Compliance: Users have the right to deletion of their data
  2. Data Integrity: Orphaned records accumulate over time
  3. User Experience: Customers cannot re-register with the same email
  4. Admin Operations: Basic customer management is broken

Additional Notes

  • This issue is similar to Unable to delete a brand #2030 (brand deletion constraints)
  • The pattern affects multiple entities in Lunar (brands, products, customers)
  • A comprehensive solution for cascade deletion strategy would benefit the entire framework

I'm already working on implementing this solution and will submit a PR shortly once the approach is confirmed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions