# Notification Queue

The `notification_queue` table stores rows of pending alerts that will be
processed by background jobs or external services. Each entry tracks the tenant,
branch and user that triggered the event along with the affected entity.

Fields:

- `tenant_id` – Tenant owning the record
- `branch_id` – Branch context or `NULL`
- `user_id` – User who performed the action
- `entity` – Table or entity name
- `record_id` – Related record primary key
- `event_type` – Operation such as `insert`, `update` or `delete`
- `payload` – Optional JSON payload
- `status` – Processing status (`queued`, `sent`, etc.)

For `update` or `patch` events triggered via `SyncController`, the `payload`
contains only the columns that were modified. Each key corresponds to the field
name with its new value, allowing consumers to perform partial updates.

`NotificationQueueService->enqueue()` inserts into this table. `GenericController`
automatically enqueues a row whenever a record is created, updated or deleted.
Workflows may enqueue custom notifications via a `queue_notification` step or by
passing a `queue_notification` array when emitting events.

### Placeholder Tokens

`queue_notification` step configurations can include tokens like `{user_id}` or
`{record_id}` in the payload or other fields. These placeholders are substituted
with values from the workflow context when the workflow runs, allowing dynamic
notifications without additional code.

## Processing

Run the Node listener to publish queued notifications via PostgreSQL's
`LISTEN/NOTIFY` mechanism:

```bash
node websocket-server/pgListener.js
```

The script uses `PG_HOST`, `PG_USER`, `PG_PASS` and `PG_DB` to connect to the
database and forwards each payload to Redis using `REDIS_URL` and
`REDIS_CHANNEL`.
