Another interesting idea, making restore easy. A reddit comment argues with this tho:
I HATE (!!!) soft deletes. Can't express how much I loathe them. You end up with every view and every query needing to remember the "WHERE revoked_at IS NULL" clause or you end up with messed up results. Instead, you make a history table that matches your main table and create a delete trigger that copies the deleted row to the history. Just UNION ALL (or JOIN) to get the history results too. And on Postgres, updating a single revoked_at column writes a whole new row; it does NOT just update the one part of the row, so it ain't even a cheap update.
Separate history tables are so much better. Along with that, it's good to have multiple roles/users in the database so you can track not just what was deleted but who deleted it. Doesn't have to the Postgres user. Could be the app user.