TomaszKK 88bd48c1f7 add final app 2 kuukautta sitten
..
.mvn 88bd48c1f7 add final app 2 kuukautta sitten
src 88bd48c1f7 add final app 2 kuukautta sitten
.env.docker 88bd48c1f7 add final app 2 kuukautta sitten
.gitattributes 88bd48c1f7 add final app 2 kuukautta sitten
.gitignore 88bd48c1f7 add final app 2 kuukautta sitten
Dockerfile 88bd48c1f7 add final app 2 kuukautta sitten
README.md 88bd48c1f7 add final app 2 kuukautta sitten
mvnw 88bd48c1f7 add final app 2 kuukautta sitten
mvnw.cmd 88bd48c1f7 add final app 2 kuukautta sitten
pom.xml 88bd48c1f7 add final app 2 kuukautta sitten

README.md

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):

    [
    {
    "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).