Soft Delete
Global Default + Entity Override
// Global: Default fuer alle EntitiescreateApp({ features: [...], softDelete: true, // Default: true});
// Entity Override: in beide Richtungenr.entity("order", { fields: { ... }, // softDelete nicht angegeben → nutzt Global Default});
r.entity("tempToken", { fields: { ... }, softDelete: false, // Kein Soft Delete fuer dieses Entity});
r.entity("auditEntry", { fields: { ... }, softDelete: true, // Auch wenn Global aus — dieses Entity soft-deletes});Was das Framework automatisch macht
| Operation | Verhalten |
|---|---|
| Delete | Setzt isDeleted: true, deletedAt, deletedById |
| Alle Queries | Automatisch WHERE isDeleted = false |
| Search | Geloeschte Entities aus Meilisearch entfernt |
| Cache | Cache invalidiert bei Delete |
| Relations | Cascading Deletes respektieren Soft Delete |
Restore
// Automatisch generiert wenn softDelete: true:r.writeHandler("order.restore", ...);// → Setzt isDeleted: false, deletedAt: nullPapierkorb (geloeschte Daten abfragen)
// Queries koennen explizit geloeschte einschliessen:r.queryHandler("order.list", schema, async (query, ctx) => { // ctx.includeDeleted = true wenn Admin den Papierkorb oeffnet});
// Oder als eigener Handler:r.queryHandler("order.trash", ...); // Nur geloeschteHard Delete: Cleanup Job
// Framework liefert automatisch wenn softDelete aktiv:r.scheduledJob("softDelete.cleanup", { cron: "0 3 * * *", // Taeglich 3 Uhr // Loescht Entities die laenger als gracePeriod geloescht sind});Grace Period konfigurierbar via Config:
r.config({ keys: { softDeleteGraceDays: { type: "number", default: 30, access: { write: ["SystemAdmin"], read: ["Admin"] }, }, },});Felder (automatisch hinzugefuegt)
Wenn softDelete: true:
isDeleted(boolean, default false)deletedAt(date, nullable)deletedById(number, nullable)