Soft-delete by default: no silent loss
Every business entity is restorable, and only super-admins can do it.
When a user deletes a contact, a deal, a page or a comment, two things must never happen: (1) the data vanishes from disk with no recourse, (2) the data is still visible in listings after deletion.
Jul6art applies the soft-delete pattern to every business entity:
- The
SoftDeletableTraittrait adds thedeleted_atcolumn and thesoftDelete()/restore()methods. - A global Doctrine
soft_deletefilter automatically excludesdeleted_at IS NOT NULLrows from every query — except forROLE_SUPER_ADMINwho sees the full picture. - The restore route
/admin/.../{id}/restoreis gated byROLE_SUPER_ADMIN: no tenant admin can restore. - On UNIQUE columns (a Contact email), the value is suffixed with
_DELETED_<timestamp>at soft-delete time to free the constraint while preserving the trace. - The event pairs
BEFORE_SOFT_DELETED/AFTER_SOFT_DELETED+BEFORE_RESTORED/AFTER_RESTOREDare dispatched on every operation, with anabort()contract that lets a listener block the deletion.
Result: an accidental delete is recoverable in two super-admin clicks, and no trace is ever lost.