# Notification Service

Rozproszony układ wykonawczy do obsługi powiadomień asynchronicznych w architekturze mikroserwisów. Serwis nasłuchuje na zdarzenia z kolejki RabbitMQ i równolegle realizuje trzy zadania: wysyłkę e-maila do klienta, wypchnięcie powiadomienia real-time na frontend (SSE) oraz zapis logu audytowego w bazie PostgreSQL.

## ⚙️ Stack Technologiczny
* **Framework:** Spring Boot 4.x (WebFlux dla Gateway, domyślnie MVC dla notyfikacji)
* **Broker wiadomości:** RabbitMQ (AMQP)
* **Baza danych:** PostgreSQL (Spring Data JPA / Hibernate)
* **Powiadomienia Real-Time:** Server-Sent Events (SSE)
* **Protokół pocztowy:** Serwer SMTP (Mailtrap dla środowiska DEV)

## 🏗️ Architektura przepływu (Flow)
1. **Order Service** (Quarkus) publikuje zdarzenie na centralę `boatdelivery.exchange`.
2. **RabbitMQ** routuje paczkę (klucz `order.created`) do kolejki `notification.email.queue`.
3. `EmailNotificationListener` przechwytuje JSON-a i uruchamia obwód:
    * **Akcja 1:** Wysyłka e-maila przez `EmailSenderService`.
    * **Akcja 2:** Strumieniowanie do Reacta przez `NotificationController`.
    * **Akcja 3:** Twardy zapis statusu operacji w tabeli `notification_logs`.

##  Uruchomienie lokalne

Upewnij się, że infrastruktura Dockera (RabbitMQ, Postgres, API Gateway, Eureka) jest uruchomiona.

🛠## 🛠️ Testowanie systemu (Manual Override)

Aby przetestować obwód bez konieczności stawiania serwisu zamówień (Order Service), wykonaj bezpośrednie wstrzykiwanie danych do brokera:

### 1. Przez panel RabbitMQ
1. Wejdź na `http://localhost:15672` (admin / admin).
2. Przejdź do zakładki **Exchanges** -> `boatdelivery.exchange`.
3. Rozwiń sekcję **Publish message**.
4. Ustaw parametry:
    * **Routing key:** `order.created`
    * **Headers:** `content_type` = `application/json`
5. Wklej któryś PayLoad (zależny od statusu paczki jaki oczekujesz):

```json
[
  {
    "eventType": "ORDER_CREATED",
    "orderId": "123e4567-e89b-12d3-a456-426614174000",
    "trackingNumber": "BD-ABCD-001",
    "targetAudience": ["CUSTOMER"],
    "customerEmail": "klient@mail.pl",
    "firstName": "Jan",
    "lastName": "Kowalski"
  },
  
  {
    "eventType": "ROUTE_ASSIGNED_DELIVERY",
    "orderId": "123e4567-e89b-12d3-a456-426614174000",
    "trackingNumber": "BD-ABCD-001",
    "targetAudience": ["COURIER"],
    "courierEmail": "kurier.tomasz@boatdelivery.pl",
    "totalDistanceKm": 45.5,
    "estimatedDurationMin": 120
  },
  
  {
    "eventType": "IN_TRANSIT_FOR_PACKAGE",
    "orderId": "123e4567-e89b-12d3-a456-426614174000",
    "trackingNumber": "BD-ABCD-001",
    "targetAudience": ["CUSTOMER"],
    "customerEmail": "klient@mail.pl",
    "pickupAddress": "DwaJeden 37",
    "courierPhone": "48123456789",
    "firstName": "Jan"
  },
  
  {
    "eventType": "ORDER_RECEIVED_FROM_CUSTOMER",
    "orderId": "123e4567-e89b-12d3-a456-426614174000",
    "trackingNumber": "BD-ABCD-001",
    "targetAudience": ["CUSTOMER"],
    "customerEmail": "klient@mail.pl",
    "firstName": "Jan"
  },
 
  {
    "eventType": "IN_TRANSIT_TO_CUSTOMER",
    "orderId": "123e4567-e89b-12d3-a456-426614174000",
    "trackingNumber": "BD-ABCD-001",
    "targetAudience": ["CUSTOMER"],
    "customerEmail": "klient@mail.pl",
    "customerPhone": "+48123456789",
    "courierPhone": "+48321123321",
    "firstName": "Anna",
    "deliveryAddress": "ul. Piotrkowska 1, 90-000 Łódź"
  },
  
  {
    "eventType": "DELIVERY_COMPLETED",
    "orderId": "123e4567-e89b-12d3-a456-426614174000",
    "trackingNumber": "BD-ABCD-001",
    "targetAudience": ["CUSTOMER"],
    "customerEmail": "odbiorca@mail.pl",
    "firstName": "Anna"
  },
  
  {
    "eventType": "ORDER_CANCELED",
    "orderId": "UUID",
    "trackingNumber": "BD-ABCD-001",
    "targetAudience": ["CUSTOMER", "COURIER"],
    "courierEmail": "kurier@boatdelivery.pl",
    "customerEmail": "klient@mail.pl",
    "courierPhone": "+48123456789",
    "firstName": "Anna",
    "deliveryAddress": "ul. Piotrkowska 1, 90-000 Łódź"
  }

]
```
6. Kliknij Publish message.

### 2. Weryfikacja poprawności obwodu
Jeśli system działa poprawnie, powinieneś zaobserwować trzy rzeczy:

Frontend: Na odpalonej aplikacji React (podpiętej pod Gateway) wyskoczy "Toast" z informacją o nowym zamówieniu (nasłuch na http://localhost:8080/api/notifications/stream).

E-mail: W skrzynce Mailtrap pojawi się wygenerowana wiadomość dla klienta.

Baza Danych: W IntelliJ (Database Tool) lub pgAdmin w tabeli notification_logs pojawi się nowy wiersz ze statusem SUCCESS (lub ERROR wraz ze zrzutem stosu z serwera SMTP).

📡 Endpointy (API)
GET /api/notifications/stream - Otwarty kanał Server-Sent Events dla przeglądarek. Wymusza nagłówki CORS dla portu deweloperskiego Vite (localhost:5173).
