> ## Documentation Index
> Fetch the complete documentation index at: https://alphaconsultings.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Soft Deletes and Restore

> When delete is soft vs hard, how restore works, and safe usage patterns.

# Soft Deletes and Restore

Use this page when records should be recoverable instead of permanently removed.

## When `delete()` is soft

`delete()` behaves as a soft delete when the model has a `deleted_at` soft-delete field in its schema.

Valid schema patterns:

```ts theme={null}
deleted_at: column("softDeletes")
```

For PostgreSQL-focused apps, prefer the explicit timezone-aware form:

```ts theme={null}
deleted_at: column("softDeletes", undefined, { useTz: true })
```

or:

```ts theme={null}
softDeletes: mixin("SoftDeletes")
```

Do not define both at once.

## What soft delete does

Soft delete updates `deleted_at` instead of permanently removing the record.

Typical service call:

```ts theme={null}
const user = await User.find(1);
if (user) {
  await user.delete();
}
```

## How `restore()` works

`restore()` clears `deleted_at` and makes the record visible again to normal reads.

```ts theme={null}
const user = await User.find(1);
if (user) {
  await user.restore();
}
```

## Hard delete after soft delete

Use `forceDelete()` only when the record should be permanently removed:

```ts theme={null}
const model = new User() as User & { forceDelete?: (id: number | string) => Promise<void> };
await model.forceDelete?.(1);
```

After `forceDelete()`, do not assume `restore()` can recover the record.

## Querying deleted records

```ts theme={null}
const model = new User() as User & {
  withTrashed?: () => Promise<unknown[]>;
  onlyTrashed?: () => Promise<unknown[]>;
};

const allRows = await model.withTrashed?.();
const deletedRows = await model.onlyTrashed?.();
```

## Recommended controller and service split

* controllers expose `restore` routes when recovery is part of the API
* services own `restore`, `onlyTrashed`, `withTrashed`, and `forceDelete`
* models define the schema requirement

## Safe usage notes

* use soft delete for recoverable business entities
* use `forceDelete` only in admin or cleanup paths
* do not document restore as guaranteed after force delete
* keep restore paths covered in tests
