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

# Preferences & Inbox

> The per-user opt-out matrix (notification_preference) and the user-facing notification inbox.

## User preferences

`notification_preference` is an opt-out overrides table. The **absence of a row
means enabled by default**.

* Columns: `user` (FK `auth.users.id`), `channel`, `category`, `is_enabled`.
* Partial unique index `(user, channel, category) WHERE is_deleted = false`.
* The dispatcher checks it in `isSuppressed(...)` **before** enqueueing; on a
  read error it *fails open* (the notification is not lost).

### API v3

| Method    | Path                                      | Permission                         | Purpose                                  |
| --------- | ----------------------------------------- | ---------------------------------- | ---------------------------------------- |
| GET       | `/v3/notification/preference`             | `notification-preference:find-all` | Paginated listing (admin).               |
| POST      | `/v3/notification/preference`             | `notification-preference:create`   | Create override (admin; accepts `user`). |
| GET       | `/v3/notification/preference/{id}`        | `notification-preference:find-one` | Detail.                                  |
| PUT       | `/v3/notification/preference/{id}`        | `notification-preference:update`   | Update override.                         |
| DELETE    | `/v3/notification/preference/{id}`        | `notification-preference:delete`   | Soft-delete.                             |
| PATCH     | `/v3/notification/preference/{id}/active` | `notification-preference:active`   | Activate / deactivate.                   |
| GET       | `/v3/notification/preference/me`          | `notification-preference:find-all` | Effective channel×category matrix.       |
| PUT/PATCH | `/v3/notification/preference/me`          | `notification-preference:update`   | Upsert an override for the token's user. |

<Note>
  `/me` resolves the owner from the JWT and rejects disabling non-suppressible
  categories with a `400`. It never accepts a `user` field.
</Note>

## Notification inbox

The inbox is a locale-agnostic record of what was delivered, backed by two
tables:

| Table                        | Purpose                                             |
| ---------------------------- | --------------------------------------------------- |
| `user_notification`          | One row per logical notification shown to the user. |
| `user_notification_delivery` | Per-channel delivery record for that notification.  |

The `/me` read API returns the authenticated user's inbox for client rendering.
See the [Schemas](/schemas/notification/user-notification) tab for the full
column reference.
