> ## 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.

# Notifications (OneSignal)

> Queue-based user notifications (push, in-app, SMS, live activities) delivered through OneSignal with per-user preference gating, idempotency and retries.

<Info>
  This section documents the **B Brands notification platform** — how any
  business action notifies a user (push, in-app, SMS, live activity) by
  enqueueing a message that a central consumer dispatches to
  [OneSignal](https://onesignal.com).
</Info>

## What this is

Any business action that needs to notify a user (failed charge, signed
contract, campaign) **enqueues** a notification instead of calling OneSignal
directly. A single Vercel queue (`notification`) feeds a central consumer that
dispatches each message to the handler of the corresponding channel.

<CardGroup cols={2}>
  <Card title="No lost notifications" icon="shield-check">
    Retries with backoff, dead-letter queue and replay inherited from the
    shared `queue_event` infrastructure absorb spikes and transient outages.
  </Card>

  <Card title="Idempotent" icon="fingerprint">
    Each message carries a `queue_event_id`; a duplicate redelivery is a no-op.
  </Card>

  <Card title="Preference gating" icon="sliders">
    Per-user opt-out is applied before enqueueing, without touching producers.
  </Card>

  <Card title="Single entry point" icon="arrow-right-to-bracket">
    Producers only call `notificationDispatcher`; the channel plumbing is
    hidden behind it.
  </Card>
</CardGroup>

## Channels

| Channel         | Delivery                                             |
| --------------- | ---------------------------------------------------- |
| `push`          | Standard push notification with title + body.        |
| `in_app`        | Data-only push so the app renders an in-app message. |
| `sms`           | SMS to the user's E.164 phone.                       |
| `live_activity` | iOS Live Activity `start` / `update`.                |

## How the signal flows

```mermaid theme={null}
flowchart TD
  prod["Business producer"] --> disp["notificationDispatcher"]
  disp --> gate{"Preference gating"}
  gate -- suppressed --> skip["Log + no enqueue"]
  gate -- allowed --> q["Vercel Queue (notification)"]
  q --> consumer["POST /api/queue/notification"]
  consumer --> handler["Channel handler"]
  handler --> os["OneSignal REST v11"]
  consumer --> qe["queue_event (received → processed / DLQ)"]
```

## Where to go next

<CardGroup cols={2}>
  <Card title="Architecture" icon="sitemap" href="/notifications/architecture">
    The dispatcher, the unified consumer, handlers and the queue payload.
  </Card>

  <Card title="Channels & Targeting" icon="crosshairs" href="/notifications/channels-and-targeting">
    Channel semantics, categories and how users are targeted.
  </Card>

  <Card title="Preferences & Inbox" icon="inbox" href="/notifications/preferences-and-inbox">
    The opt-out matrix and the user-facing notification inbox.
  </Card>

  <Card title="Operations" icon="book" href="/notifications/operations">
    Environment variables, DLQ/replay runbook and health.
  </Card>
</CardGroup>
