# Soft Deletion

When you remove a resource in Apiera, it is **soft-deleted**, not permanently destroyed. The resource is preserved
in the database with a `removedAt` timestamp and excluded from standard queries. It can be restored later.

## How it works

1. You invoke the `remove` transition on a resource.
2. The resource's state changes to `removed` and `removedAt` is set to the current timestamp.
3. The resource no longer appears in standard list queries.
4. A webhook event is fired (e.g. `product.removed`).


The resource and all its data remain intact.

## Querying removed resources

By default, removed resources are hidden from list endpoints. To include them, use the `isRemoved` filter:


```bash
# List only removed products
curl "https://api.apiera.io/v1/products?isRemoved[eq]=true" \
  -H "Authorization: Bearer {token}"

# You can also filter by the removed stage directly
curl "https://api.apiera.io/v1/products?stages[eq]=removed" \
  -H "Authorization: Bearer {token}"
```

Getting a specific resource by UUID still works regardless of its state:


```bash
curl https://api.apiera.io/v1/products/{uuid} \
  -H "Authorization: Bearer {token}"
```

## Restoring removed resources

Invoke the `restore` transition to recover a soft-deleted resource:


```bash
curl -X PATCH https://api.apiera.io/v1/products/{uuid}/actions/lifecycle \
  -H "Authorization: Bearer {token}" \
  -H "Content-Type: application/json" \
  -d '{ "transition": "restore" }'
```

The resource returns to a safe state after restoration:

| Resource type | State after restore |
|  --- | --- |
| Product, Attribute, Category, Tag, Brand | Unpublished |
| Product Family | Inactive |
| Locale | Inactive |
| Channel | Inactive |


Restored resources never return directly to a published or active state. This prevents accidentally making
previously-removed content visible without review.

## Cascading effects

Removing a resource can affect related resources:

- **Removing a product family** unpublishes all products that belong to that family. Child families are also removed
recursively.
- **Removing a product** does not affect its sub-resources (attributes, tags, assets, etc.) since those are
associations, not independent entities.


## Visibility during hydration

When you use `include[]` or `expand[]` to hydrate related data, soft-deleted items are excluded from the hydrated
collections. For example, if a product has three linked categories and one is removed, the hydrated response only
includes the two active categories.

## Operations on removed resources

Most operations are blocked on removed resources. Attempting to update, publish, or otherwise modify a removed
resource returns a `422 Unprocessable Entity` error. The only allowed transition from the removed state is `restore`.