Przejdź do treści

Pielęgnacja — przebieg integracji

Ścieżki są względne wobec /partner/v1/pets. Uwierzytelnienie jak w pozostałych modułach: x-client-id, x-api-key, x-user-id.

Zakres tego modułu

Dokument opisuje pielęgnację — powtarzalne czynności planowane samodzielnie, bez związku z wizytą: kąpiel, obcinanie pazurów, czyszczenie uszu i podobne.

Pozostałe rodzaje zabiegów — badania, szczepienia, odrobaczanie i profilaktykę przeciwpasożytniczą — dodaje się inaczej, w powiązaniu z wizytą. Opisuje to dokumentacja wizyt zewnętrznych.

Podział jest odzwierciedlony w API — każdy moduł ma własny katalog, więc nie trzeba niczego filtrować po swojej stronie:

Katalog Zawiera
GET /{petId}/cyclic-treatments/available pielęgnację — ten moduł
GET /{petId}/external-appointments/available-treatments badania, szczepienia, odrobaczanie, profilaktykę

Zasada ogólna

Pielęgnacja opiera się na katalogu czynności przygotowanym dla danego gatunku. Użytkownik wybiera pozycję z katalogu i planuje jej wykonanie, opcjonalnie z cyklem powtarzania.

Zaplanowana czynność żyje dalej sama: po oznaczeniu jako wykonana automatycznie przesuwa się na kolejny termin, zgodnie z ustawionym interwałem.

Krok 1 — katalog

GET /{petId}/cyclic-treatments/available

Zwraca wyłącznie czynności pielęgnacyjne, dobrane do gatunku zwierzaka, w języku żądania:

{ "cyclicTrreatmentsContents": [
    { "name": "Obcinanie pazurów", "description": "…", "frequency": "…",
      "cyclicTreatment": {
        "id": "…", "treatmentType": "CARE", "interval": "MONTHLY", "icon": "…",
        "petCyclicTreatments": [ ] } } ] }

Zagnieżdżone petCyclicTreatments mówi, czy czynność jest już zaplanowana dla tego zwierzaka — pusta tablica oznacza, że jeszcze nie. To najprostszy sposób oddzielenia dostępnych od zaplanowanych bez dodatkowego zapytania.

Nazwa pola cyclicTrreatmentsContents zawiera literówkę. Jest częścią istniejącego kontraktu i nie zmieniamy jej, żeby nie łamać zgodności.

Krok 2 — zaplanowanie

POST /{petId}/cyclic-treatments
{ "cyclicTreatmentId": "…",
  "date": "2026-11-15",
  "lastTimeTreatmentDate": "2026-08-15",
  "reminderInterval": "MONTHLY",
  "comment": "Tylko przednie łapy" }
Pole Wymagane Uwagi
cyclicTreatmentId tak pozycja z katalogu
date tak planowany termin; nie może być w przeszłości
lastTimeTreatmentDate tak kiedy wykonano poprzednio
reminderInterval nie DAILY, WEEKLY, MONTHLY, QUARTERLY, YEARLY
comment nie

petId pochodzi ze ścieżki i nie podaje się go w ciele.

lastTimeTreatmentDate jest wymagane. Przy pierwszym planowaniu, gdy czynności nigdy wcześniej nie wykonywano, należy podać datę, od której liczy się obserwacja — w naszej aplikacji użytkownik wskazuje ją w formularzu, a pole jest ograniczone do dat nie późniejszych niż dzisiaj.

Brak reminderInterval oznacza czynność jednorazową — po wykonaniu nie zostanie zaplanowana ponownie.

Krok 3 — lista zaplanowanych

GET /{petId}/cyclic-treatments?skip=0&take=50

Zwraca { petCyclicTreatments: [...], count: 12 }, gdzie count to pełna liczba pozycji niezależna od stronicowania. take domyślnie 50, maksymalnie 100.

Krok 4 — szczegóły przypomnienia

GET /cyclic-treatment-reminders/{reminderId}

Identyfikator przypomnienia przychodzi w powiadomieniu webhook (pet.cyclic_treatment.reminder). Endpoint zwraca komplet potrzebny do wyświetlenia ekranu przypomnienia: dane zwierzaka, zaplanowaną czynność i pozycję katalogową z opisem.

Zwróć uwagę, że reminderId to inny byt niż treatmentId — przypomnienie dotyczy jednego wystąpienia, a czynność powtarza się w czasie.

Krok 5 — edycja, wykonanie, usunięcie

PATCH  /{petId}/cyclic-treatments/{treatmentId}
PUT    /{petId}/cyclic-treatments/{treatmentId}/completed
DELETE /{petId}/cyclic-treatments/{treatmentId}

Wszystkie trzy operują na identyfikatorze czynności, nie przypomnienia.

Edycja nie jest częściowa — wysyła się komplet

PATCH nie zachowuje pól, których nie prześlesz. Serwis odtwarza cały wiersz z ciała żądania, więc edycja jednego pola to w praktyce nadpisanie całej czynności. Dlatego wymagamy kompletu wartości i odrzucamy niepełne żądanie, zamiast pozwolić mu po cichu wyzerować cykl.

PATCH /{petId}/cyclic-treatments/{treatmentId}
{ "date": "2026-12-15",
  "lastTimeTreatmentDate": "2026-11-15",
  "reminderInterval": "MONTHLY",
  "comment": "Tylko przednie łapy" }
Pole Wymagane Uwagi
date tak planowany termin
lastTimeTreatmentDate tak
reminderInterval tak wartość albo jawne null — patrz niżej
comment nie jedyne pole, które można pominąć; pominięty lub pusty zachowuje dotychczasową wartość, więc komentarza nie da się skasować

reminderInterval trzeba podać przy każdej edycji. Pominięcie go kończy się 400, i jest to zamierzone: po naszej stronie brak interwału jest nieodróżnialny od świadomego wyłączenia cyklu, więc pominięcie zapisałoby null i zamieniło czynność powtarzalną w jednorazową. Żeby cykl faktycznie wyłączyć, przesyła się null wprost.

Najprostszy sposób pracy z tym endpointem to pobranie aktualnej czynności (GET /{petId}/cyclic-treatments), podmiana zmienianych pól i odesłanie kompletu.

Oznaczenie jako wykonane przesuwa termin

To najważniejsze zachowanie tego modułu. PUT .../completed:

  1. zamyka bieżące przypomnienie,
  2. jeśli ustawiono reminderInterval — wylicza kolejny termin z interwału, zapisuje go jako nowy date, przenosi poprzedni termin do lastTimeTreatmentDate i tworzy nowe przypomnienie.

Czynność nie znika po wykonaniu — przechodzi do następnego cyklu. Zakończyć ją na dobre można wyłącznie przez DELETE.

Odpowiedź mówi, czy to wywołanie coś zmieniło — tak samo jak przy przypomnieniach o lekach:

Odpowiedź Znaczenie
{ "completed": true } przypomnienie zostało zamknięte, a czynność przeszła do kolejnego cyklu
{ "completed": false } nie było czego oznaczać — czynność nie miała otwartego przypomnienia

Drugi przypadek nie jest błędem: wywołanie jest idempotentne, powtórzenie po prostu nic nie robi.

Najczęstsze przyczyny błędów

Objaw Przyczyna
Odrzucone planowanie mimo kompletnego formularza Brak lastTimeTreatmentDate — jest wymagane
Invalid date przy planowaniu date wskazuje przeszłość; planowany termin musi być dzisiejszy lub późniejszy
Zabieg wraca na listę po oznaczeniu jako wykonany Zachowanie zamierzone — ustawiony reminderInterval przesuwa go na kolejny termin
{ "completed": false } mimo poprawnego identyfikatora Czynność nie miała otwartego przypomnienia — np. oznaczono ją już wcześniej
Nie znaleziono czynności przy edycji Użyto reminderId zamiast treatmentId
400 przy edycji Pominięto date, lastTimeTreatmentDate albo reminderInterval — edycja wymaga kompletu
Czynność przestała się powtarzać po edycji reminderInterval przesłany jako null — to wyłącza cykl
W katalogu nie ma szukanego zabiegu Badania, szczepienia i odrobaczanie mają własny katalog w module wizyt zewnętrznych

Przykładowa sekwencja

GET  /partner/v1/pets/{petId}/cyclic-treatments/available    → katalog pielęgnacji
POST /partner/v1/pets/{petId}/cyclic-treatments              → zaplanowanie
GET  /partner/v1/pets/{petId}/cyclic-treatments?take=50      → lista zaplanowanych

po nadejściu webhooka pet.cyclic_treatment.reminder:
GET  /partner/v1/pets/cyclic-treatment-reminders/{reminderId}
PUT  /partner/v1/pets/{petId}/cyclic-treatments/{treatmentId}/completed