Не удалять, а помечать
deleted_at и deleted_by вместо DELETE - и одно место, где удалять обязательно по-настоящему.
Удаленная строка не оставляет следов. Журнал скажет «заказ удален», но какой это был заказ, на какую сумму и за каким столом - уже нигде. Поэтому в рабочих системах вместо DELETE - пометка:
ALTER TABLE orders
ADD COLUMN deleted_at timestamptz,
ADD COLUMN deleted_by bigint REFERENCES staff (id);
-- вместо DELETE
UPDATE orders
SET deleted_at = now(), deleted_by = :staff_id
WHERE id = :id;
-- живые строки ищутся по частичному индексу и не платят за удаленные
CREATE INDEX orders_alive_idx ON orders (created_at) WHERE deleted_at IS NULL;
deleted_by важен не меньше даты: «удалено» без «кем» - половина ответа.
Где удалять нужно по-настоящему
Аккаунт пользователя, который сам попросил его удалить. App Store требует, чтобы удаление было настоящим, и «пометка вместо удаления» там - прямой отказ на ревью. Компромисс такой: перед удалением пишем в журнал сам факт - кто и когда удалил свой аккаунт, без персональных данных, - и только потом удаляем.