Skip to content

Feature: Soft Delete Groups and Events instead of Hard Deleting#47

Open
ardelato wants to merge 9 commits intohermesfrom
feat--soft-delete-events-groups
Open

Feature: Soft Delete Groups and Events instead of Hard Deleting#47
ardelato wants to merge 9 commits intohermesfrom
feat--soft-delete-events-groups

Conversation

@ardelato
Copy link
Collaborator

Description

This replaces destructive hard-deletes of groups and events with Laravel soft-deletes, preserving devices, volunteer associations, and audit records for potential restoration.

CR Notes

Admins were unable to delete groups that had an event with a linked device to said event. However, we already allowed cascading deletes if we deleted an event.

Overall, we don't actually want to delete any repair data generated from events, but we'd still want to be able to delete events and groups.

Thus, we will use soft-deletes to preserve this data and not have to deal with the hassle of dropping the foreign keys between devices <--> events <--> groups.

To do that, we will add a new deleted_at column to be able to hide groups and events from the UI. We will also add the ability to restore groups and events if we had accidentally deleted them.

QA Notes

I had already tested this locally, but we will need to test this on the test cluster.

Reference: https://ifixit.slack.com/archives/C08D1D48FJ5/p1771374854552569

ardelato and others added 9 commits February 18, 2026 15:05
Add a `deleted_at` timestamp column (with index) to the `groups` table
to support Laravel's SoftDeletes functionality.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Enable soft-delete support on the Group model by adding Laravel's
SoftDeletes trait. Also update raw SQL queries in findAllGroups(),
findAll(), and findAllByUserId() to filter out soft-deleted groups
with `WHERE g.deleted_at IS NULL`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Simplify deleteGroup() to use Laravel's soft-delete instead of manually
hard-deleting events, event-users, and the group. Now soft-deletes all
group events first, then soft-deletes the group itself — preserving
devices and volunteer data for potential restoration.

Also remove the canDelete() gate from the group view blade template so
admins can always delete groups regardless of whether events have devices.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ations

Stop hard-deleting audit records, devices, and event-user associations
when an event is deleted. Since Party already uses SoftDeletes, calling
$event->delete() is sufficient — it soft-deletes the event while
preserving all related data for potential restoration.

Also remove the canDelete() gate from the event view blade template so
authorized users can delete events regardless of whether they have devices.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…in API

Update the groups admin API to support soft-delete workflows:
- Add `deleted` query parameter (active/only/all) to filter groups
- Use withTrashed() when performing single/bulk actions so soft-deleted
  groups can be targeted
- Replace hard-delete with soft-delete in the `delete` action, cascading
  to group events
- Add `restore` action that restores a group and its soft-deleted events
- Include `deleted_at` in the group API response
- Add admin events API routes for event listing and restore

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a new admin API controller for events that supports:
- Listing events with search, sorting, pagination, and deleted filter
- Restoring soft-deleted events with a guard that prevents restoring
  an event whose parent group is still deleted (returns 409)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… Vue components

Update the admin groups management UI to support soft-delete workflows:
- GroupsManagement: add a dropdown filter for Active/Deleted/All groups,
  pass deleted filter state to child components
- GroupsTable: show "Deleted" badge on soft-deleted groups, disable edit
  link for deleted groups, conditionally show delete/restore in dropdown
- GroupsBulkAction: show Restore button when viewing deleted groups,
  hide Delete button when viewing only deleted groups
- ConfirmationModal: add restore action with success styling and text

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update GroupDeleteTest to verify soft-delete behavior:
- testCanDeleteGroup now asserts assertSoftDeleted
- testCantDeleteWithDevice renamed to testCanDeleteWithDevice since
  soft-delete works regardless of devices
- Fix a malformed date in testCanDeleteWithDeletedEvent

Add GroupSoftDeleteTest with comprehensive coverage:
- Event soft-delete retains devices
- Group soft-delete cascades to events
- Admin API group soft-delete and restore
- Event restore blocked when parent group is deleted (409)
- Deleted groups hidden from default queries
- Admin API deleted filter (active/only/all)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tsValue

Change Math.ceil to Math.round for waste_total display in StatsImpact
for more accurate rounding. Add null checks in StatsValue computed
properties (translatedTitle, translatedSubtitle, translatedDescription)
to prevent errors when optional props are not provided.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ardelato
Copy link
Collaborator Author

QA 👍

  • I confirmed regular users still do not have the ability to delete groups or events.
  • I confirmed admins are now able to delete groups that had events and linked device data from said events
  • I confirmed any data from the events was not deleted, so it still shows up on the /fixometer page.
  • I confirmed that a deleted group can be restored, as well as its events, from the group management page.

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

Comments