# AMPER Channels – powiadomienia w czasie rzeczywistym

AMPER Channels to usługa powiadomień w czasie rzeczywistym, zbudowana na [Socket.IO](https://socket.io/docs/v4/). Serwer AMPER WS publikuje w niej zdarzenia (nowe zamówienie, ruch magazynowy, nowy post na ścianie, rekomendacje produktów), a aplikacje AMPER – panel administracyjny, sklep B2B, aplikacje mobilne – nasłuchują ich i odświeżają widok bez przeładowania.

Adres usługi: `https://channels.ampli-solutions.com` (w instalacjach dedykowanych adres może być inny – ustawienie `CHANNELS_URL` serwera AMPER WS).

> Usługa nie ma API HTTP. Cała komunikacja odbywa się przez połączenie Socket.IO.

## Przestrzenie (namespaces)

| Przestrzeń | Przeznaczenie | Zdarzenia |
|------------|---------------|-----------|
| `/document` | zamówienia i magazyn | `new-order`, `adding-an-item`, `item-stock-movement` |
| `/kb-feed` | ściana / baza wiedzy | `new-post`, `new-comment`, `new-reaction` |
| `/amper-live` | powiadomienia dla jednego użytkownika sklepu | `product-recommendations`, `item-applied-promotion` |
| `/delivery` | automaty paczkowe (skrytki) | komunikacja z urządzeniami – poza zakresem tego artykułu |

## Połączenie

Klient łączy się z wybraną przestrzenią i w danych uwierzytelniających (`auth`) przekazuje:

| Pole | Opis |
|------|------|
| `token` | token dostępowy (JWT) zalogowanego użytkownika AMPER – ten sam, którego aplikacja używa w zapytaniach do AMPER WS |
| `amperCompanyAssigned` | identyfikator instalacji AMPER – wartość pola `amper-company-assigned` z odpowiedzi logowania `POST /auth/`. Opcjonalne – bez niego instalacja jest ustalana z tokena |

Przykład (przeglądarka, pakiet `socket.io-client` w wersji 4):

```javascript
import { io } from 'socket.io-client';

const socket = io('https://channels.ampli-solutions.com/document', {
  auth: {
    token: accessToken,                  // access_token z POST /auth/
    amperCompanyAssigned: companyName,   // amper-company-assigned z POST /auth/
  },
});

socket.on('connect', () => {
  // dołączenie do pokoju z nowymi zamówieniami instalacji
  socket.emit('room', `${companyName}:new-orders`);
});

socket.on('hello', (message) => console.log(message)); // potwierdzenie dołączenia do pokoju

socket.on('new-order', (data) => {
  console.log(data.title, data.message, data.url);
});
```

Token jest sprawdzany przy nawiązywaniu połączenia. Przy każdym ponownym łączeniu (np. po zerwaniu połączenia) przekaż aktualny, nieprzeterminowany token.

## Pokoje

Zdarzenia trafiają do pokoi (rooms). Nazwa pokoju zaczyna się od identyfikatora instalacji (`<firma>` = `amperCompanyAssigned`), a klient może dołączyć tylko do pokoi własnej instalacji – zdarzeniem `room` z nazwą pokoju. Serwer potwierdza dołączenie zdarzeniem `hello`.

| Przestrzeń | Pokój | Co w nim trafia |
|------------|-------|-----------------|
| `/document` | `<firma>:new-orders` | nowe zamówienia |
| `/document` | `<firma>:stock:location:<id magazynu>` | zmiany stanów w magazynie |
| `/kb-feed` | `<firma>:kb-wall` | posty, komentarze i reakcje na ścianie |
| `/amper-live` | `<firma>:user:<keycloak_id użytkownika>` | powiadomienia dla jednego użytkownika – klient dołącza do niego automatycznie przy połączeniu |

W przestrzeni `/amper-live` klient może dołączyć wyłącznie do własnego pokoju użytkownika – prośby o inne pokoje są ignorowane.

## Zdarzenia

### `/document`

**`new-order`** – nowe zamówienie w instalacji:

```json
{ "title": "Nowe zamówienie", "message": "Klient ABC złożył zamówienie nr 12345", "url": "https://..." }
```

**`adding-an-item`** – produkt dodany do dokumentu sprzedaży (np. w punkcie sprzedaży) i **`item-stock-movement`** – zmiana stanu po imporcie stanów z ERP:

```json
{ "product_id": 101, "quantity": 5.0, "location_id": 3 }
```

Oba zdarzenia trafiają do pokoju magazynu `<firma>:stock:location:<location_id>`.

### `/kb-feed`

```json
{ "post_id": 15 }                                    // new-post
{ "post_id": 15, "comment_id": 87 }                  // new-comment
{ "post_id": 15, "reaction_id": 4, "comment_id": 87 } // new-reaction
```

Zdarzenia zawierają tylko identyfikatory – treść posta, komentarza lub reakcji aplikacja pobiera z AMPER WS.

### `/amper-live`

**`item-applied-promotion`** – do produktu w koszyku użytkownika została zastosowana promocja:

```json
{
  "user_keycloak_id": "26259ede-...",
  "cart_line_id": 5521,
  "product": { "id": 101, "name": "...", "short_code": "426684" },
  "promotion": { "id": 999, "name": "Letnia wyprzedaż", "description": "...", "default_image": null }
}
```

**`product-recommendations`** – rekomendacje produktów po dodaniu produktu do koszyka:

```json
{
  "user_keycloak_id": "26259ede-...",
  "added_product": { ... },
  "recommendations": [ { ... }, { ... } ]
}
```

Produkty mają format listy produktów sklepu B2B.

## Kto publikuje zdarzenia

Zdarzenia publikuje serwer AMPER WS, korzystając z własnego konta technicznego. Aplikacje klienckie tylko ich nasłuchują.

Po stronie serwera AMPER WS usługę włącza ustawienie `AMPER_CHANNELS_ENABLED`.