Isn't this something your application solves with just another column? How can Postgres help you with this?
- should soft-deleted rows move to another partition to avoid bloat?
- what’s the column name and type (boolean, timestamp, tstzrange)?
- what’s the syntax for a soft delete versus hard delete?
- what’s the behavior of updating a soft deleted row?
- do soft deleted keys prevent inserts with the same key?
Bitemporal tables mentioned in the thread are a more general solution. Alternately, you could use a statement-based trigger to prevent deletes to the table.