Soft delete
What it changes
Section titled “What it changes”With softDelete on, a delete stamps a column instead of removing the row,
and every read filters the stamped rows out. Nothing else about the operation
moves: the same permission is required, beforeDelete can still veto it and
afterDelete still fires. From the caller’s point of view the row was deleted;
how the table records that is this flag’s business.
import { defineCollection } from "@rebasepro/cms-types";
const invoices = defineCollection({ slug: "invoices", name: "Invoices", table: "invoices", softDelete: true, properties: { reference: { name: "Reference", type: "string" }, deletedAt: { name: "Deleted at", type: "date", admin: { readOnly: true } } }});true uses deletedAt (column deleted_at). The object form renames it:
softDelete: { field: "archivedAt" }.
Postgres only, like search and indexes.
What a read sees
Section titled “What a read sees”Stamped rows are hidden by default from find, findById, count, the
aggregates, the realtime refetch, and from this collection loaded through a
relation. That default is the point: code written before the flag existed keeps
working, and nobody has to remember to filter.
Two query parameters open it up:
| Parameter | Answers |
|---|---|
?deleted=include |
Live rows and stamped ones |
?deleted=only |
Stamped rows alone — the trash view |
Anything else is a 400 rather than a silent fallback. ?deleted=true quietly
hiding every deleted row would look like it worked and answer the opposite
question.
Restoring, and really deleting
Section titled “Restoring, and really deleting”A restore is an ordinary update setting the field back to null. There is
no special verb, because there is no special state — the row never went anywhere.
A real DELETE is ?hard=true on the delete call. It needs exactly the
same permission an ordinary delete does: it is the same verb, and gating it
separately would be a second access-control surface for one operation. What it
changes is whether the row can come back. Only the literal true or 1 means
yes; a typo is a 400, because a caller who asked to purge and got a soft delete
believes the data is gone.
Next Steps
Section titled “Next Steps”- Defining Collections — where
softDeleteis declared - REST API — the delete and query endpoints these parameters belong to
- Security Rules (RLS) — who may delete a row at all