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

# Realizacja przez plugin

> Kontrakt Socket.IO, atomowy claim i bezpieczne potwierdzanie realizacji.

Oficjalny plugin korzysta z namespace Socket.IO `/plugin` na publicznym originie aplikacji/API. Połączenie zawsze inicjuje serwer gry; nie wystawia on portu przychodzącego.

<Warning>
  Stare endpointy pollingu REST `GET /orders/plugin/.../pending` i `POST /orders/plugin/.../complete` zostały wycofane. Nie zapewniały bezpiecznego atomowego claimu przy wielu instancjach ani ochrony niejednoznacznego okna awarii. Używaj aktualnego pluginu i protokołu poniżej.
</Warning>

## Uwierzytelnianie

Handshake namespace przekazuje:

```json theme={null}
{ "apiKey": "isk_<64 znaki hex>", "serverId": "<24 znaki hex>" }
```

Backend akceptuje wyłącznie aktywny klucz typu `plugin` z `orders:write`. Klucz musi być związany ze sklepem, `serverId` należeć do tego samego sklepu, a właściciel klucza nadal mieć do niego dostęp. Niepoprawne połączenie kończy się ogólnym `unauthorized`, bez ujawniania, który warunek zawiódł.

## Zdarzenia protokołu v1

| Kierunek     | Event             | Dane / ACK                                                                              |
| ------------ | ----------------- | --------------------------------------------------------------------------------------- |
| plugin → app | `hello`           | `{ platform, version }`                                                                 |
| app → plugin | `ready`           | `{ serverId, serverName }`                                                              |
| app → plugin | `order:deliver`   | `{ v: 1, id, player, status, commands[], requireOnline }`                               |
| plugin → app | `order:claim`     | `{ orderId }`; ACK zwraca świeży snapshot komend zwycięzcy                              |
| plugin → app | `order:release`   | dobrowolne oddanie claimu, gdy świeży warunek dostawy nie jest spełniony                |
| plugin → app | `order:verify`    | ponowna weryfikacja bieżącego statusu dostawy, która długo czekała                      |
| plugin → app | `order:complete`  | `{ orderId }`; ACK pozwala usunąć wpis `AWAITING_ACK`                                   |
| plugin → app | `order:uncertain` | zgłoszenie odzyskanego `EXECUTING`; odpowiedź: `manual-review`, `retry` albo `complete` |
| plugin → app | `orders:pull`     | limitowana prośba o pełny replay zaległości                                             |
| plugin → app | `players:update`  | `{ online, max, players?[] }`; backend filtruje i limituje wartości                     |
| plugin → app | `ping:app`        | diagnostyczny ACK z czasem aplikacji                                                    |

Backend wysyła pełny replay po każdym połączeniu oraz push po opłaceniu lub zmianie statusu. Powtórzone `order:deliver` jest oczekiwane — o prawie wykonania decyduje atomowy claim i lokalny journal, a nie samo otrzymanie eventu.

## Stany bezpieczeństwa

1. `paid` lub `dispute` → `processing`: tylko jedna instancja wygrywa warunkową zmianę w bazie.
2. Plugin zapisuje i fsyncuje `EXECUTING` **przed** pierwszą komendą.
3. Po ostatniej komendzie zapisuje i fsyncuje `AWAITING_ACK`.
4. `order:complete` przełącza zamówienie na `completed`; dopiero ACK usuwa lokalny wpis.
5. Restart z `AWAITING_ACK` ponawia tylko ACK. Restart z `EXECUTING` nie powtarza komend i uruchamia ręczną weryfikację.

<Info>
  Nie usuwaj journalu, aby „odblokować” zamówienie. W panelu sprawdź faktyczny stan gracza i rozstrzygnij wpis ręcznie. Decyzja `retry` czyści claim po stronie aplikacji i pozwala na nowy push; `complete` uznaje dostawę bez powtórzenia komend.
</Info>

## Formatowanie komend

Komendy produktu są formatowane przez API przed wysłaniem świeżego snapshotu zwycięzcy claimu:

| Placeholder           | Zastępowane przez                                         |
| --------------------- | --------------------------------------------------------- |
| `{PLAYER}` / `{NICK}` | zweryfikowany nick zamówienia                             |
| `{QUANTITY}`          | ilość                                                     |
| `{PRODUCT}`           | nazwa produktu                                            |
| `{QUANTITY*1.5:2}`    | dozwolone wyrażenie matematyczne, zaokrąglone do 2 miejsc |

Wyrażenia matematyczne korzystają z ograniczonego parsera; nie są wykonywane jako kod. Progi `quantityTiers`, wariant komend i bonus pakietu są rozstrzygane po stronie API. Plugin dodatkowo odrzuca komendy, których pierwsze słowo znajduje się w `blockedCommands`.

Jeżeli produkt wymaga gracza online, instancja wykonuje komendy dopiero po wykryciu właściwego nicku na dozwolonym serwerze. Długo oczekująca lokalna kopia jest sprawdzana przez `order:verify`, aby anulowane lub zwrócone zamówienie nie zostało wykonane ze starego eventu.
