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

# Push notifications

> Lala writes first. Register the OneSignal alias so the message can arrive.

Lala is proactive. It schedules a message during a conversation, and a background job delivers the
message later. There is no API endpoint for this. Delivery is a OneSignal push, plus an append to
the conversation history.

## Register the alias

The server targets a student by the OneSignal `external_id` alias. That alias must be the Supabase
`auth.users.id`, which is the same value as `id` in the `GET /api/me` response.

```dart theme={null}
await OneSignal.login(studentId); // studentId == the `id` from GET /api/me
```

Call `OneSignal.login` after every sign-in. Call `OneSignal.logout` on sign-out. A student with no
alias gets no proactive message. The chat still works.

## What arrives

Every notification has the title `Lala`. The body is the message text, in Turkish. The `data`
object identifies the source:

| `data.type`       | `data.messageType`                   | Source                                                   |
| ----------------- | ------------------------------------ | -------------------------------------------------------- |
| `scheduled`       | `reminder`, `checkin`, or `followup` | A message that Lala scheduled in a conversation.         |
| `silence_checkin` | absent                               | The daily job, when the student was silent for 48 hours. |

Route every one of these to the chat screen. They are chat messages, not system alerts.

## The two jobs

<Steps>
  <Step title="Scheduled messages, every minute">
    A job drains the due rows of `scheduled_messages`. Each row is claimed with
    `FOR UPDATE SKIP LOCKED`, so two server replicas cannot send the same message twice.
  </Step>

  <Step title="Silence check-in, 07:00 Europe/Istanbul">
    A daily job finds students who have been silent for 48 hours. It generates one short message
    for each, and sends it once.
  </Step>
</Steps>

## The history is the source of truth

The server appends every delivered message to the conversation history with the role `assistant`.
The push is only the announcement. A push that fails to deliver does not remove the message.

Call `GET /api/chat/history` when the student opens the notification, and when the application
returns to the foreground. Do not build the chat list from notification payloads.

<Note>
  Push delivery failures never break chat. The server logs a failed push and continues.
</Note>

## Times

Lala schedules in Turkey time (UTC+3). Timestamps in the API are UTC, ISO 8601. Convert to
`Europe/Istanbul` for display.
