# Notifications — ALGA ARENA Esports Platform

**Date:** 2026-07-20

## Overview

Database notifications via Laravel's `Notifiable` trait on `User`. All app notifications extend `ArenaDatabaseNotification` (queued, database channel only).

**Table:** `notifications` (uuid PK, morphs notifiable, `data` json text, `read_at`)

---

## User-Facing UI

**Routes:**

| Route | Controller | Purpose |
|-------|------------|---------|
| GET `/notifications` | `NotificationController@index` | Paginated list (20/page) |
| GET `/notifications/{id}/read` | `markRead` | Mark read + redirect to `data.url` |
| POST `/notifications/read-all` | `markAllRead` | Mark all unread read |

**Middleware:** `auth`, `verified`, `active`

---

## Base Class

**`ArenaDatabaseNotification`**

- Implements `ShouldQueue` (async if queue worker running)
- Channel: `database` only (no mail/push in MVP)
- Payload helper: `title`, `message`, `url`, `icon` (translated strings)

---

## Notification Classes

### Registration

| Class | Trigger | Recipient |
|-------|---------|-----------|
| `EventRegistrationReceivedNotification` | New registration | Participant |
| `EventRegistrationWaitlistedNotification` | Waitlisted | Participant |
| `EventRegistrationConfirmedNotification` | Confirmed | Participant |
| `EventRegistrationRejectedNotification` | Rejected | Participant |
| `WaitlistPromotedNotification` | Promoted from waitlist | Participant |
| `ManualPaymentRequiredNotification` | Status → pending_payment | Participant |

**Event:** `RegistrationStatusChanged`  
**Listener:** `SendRegistrationStatusNotification` (`afterCommit = true`)

### Payments

| Class | Trigger |
|-------|---------|
| `PaymentProofSubmittedNotification` | Proof uploaded |
| `PaymentConfirmedNotification` | Admin confirmed payment |
| `PaymentRejectedNotification` | Admin rejected (+ re-upload URL) |

**Event:** `PaymentProofReviewed`  
**Listener:** `SendPaymentProofNotification`

Actions: `submitted`, `confirmed`, `rejected`

### Content moderation

| Class | Trigger |
|-------|---------|
| `RecordModerationResultNotification` | Record moderated |
| `VideoModerationResultNotification` | Video moderated |

**Event:** `ContentModerated`  
**Listener:** `SendContentModerationNotification`

---

## Event → Listener Registration

Configured in `AppServiceProvider::boot()`:

```php
Event::listen(RegistrationStatusChanged::class, SendRegistrationStatusNotification::class);
Event::listen(PaymentProofReviewed::class, SendPaymentProofNotification::class);
Event::listen(ContentModerated::class, SendContentModerationNotification::class);
```

---

## Payload Structure

Stored in `notifications.data`:

```json
{
  "title": "Translated title",
  "message": "Translated message body",
  "url": "/event-registrations/{uuid}",
  "icon": "optional-icon-key"
}
```

Translation keys live in `lang/en/notifications.php` and `lang/ar/notifications.php`.

---

## Registration Notification Logic

**`SendRegistrationStatusNotification`** decision tree:

1. If `wasPromotedFromWaitlist` → `WaitlistPromotedNotification` only
2. If `isNewRegistration`:
   - Always `EventRegistrationReceivedNotification`
   - Plus `ManualPaymentRequiredNotification` if pending_payment
   - Plus `EventRegistrationWaitlistedNotification` if waitlisted
3. Else match on final status:
   - `confirmed` → confirmed notification
   - `rejected` → rejected (includes reason)
   - `waitlisted` → waitlisted
   - `pending_payment` → manual payment required

---

## Localization

Notifications use `__()` at send time — locale from `SetLocale` middleware / user `preferred_locale`.

Arabic strings in `lang/ar/notifications.php`.

---

## Queue Configuration

| Environment | `QUEUE_CONNECTION` | Behavior |
|-------------|-------------------|----------|
| Testing | `sync` | Immediate |
| Production | Should configure `database` or `redis` | Requires worker |

If no worker, queued notifications may not send in production — verify deployment config.

---

## Not Implemented

- Email notifications
- Push / SMS
- Admin notifications (e.g. alert admin on new proof — participant-only notifications exist)
- Real-time WebSocket broadcast
- Notification preferences UI (settings tab exists but not wired to filter types)

---

## Diagram

```mermaid
flowchart LR
    subgraph Domain Events
        RSC[RegistrationStatusChanged]
        PPR[PaymentProofReviewed]
        CM[ContentModerated]
    end

    subgraph Listeners
        L1[SendRegistrationStatusNotification]
        L2[SendPaymentProofNotification]
        L3[SendContentModerationNotification]
    end

    subgraph Storage
        DB[(notifications table)]
    end

    RSC --> L1 --> DB
    PPR --> L2 --> DB
    CM --> L3 --> DB
```
