# Redmine

## Co robi

Dzięki integracji z Redmine Speedwave czyta i aktualizuje zgłoszenia, czas pracy, dzienniki zmian oraz użytkowników w twojej instancji Redmine. Obsługuje instancje samodzielnie hostowane i on-premise, w tym te pod adresami prywatnymi i w zakresach CGNAT Tailscale. Kiedy podczas konfiguracji wskażesz projekt, Speedwave zawęża do niego swoje działania, przez co integracja dobrze łączy się z [planowaniem i przekładaniem wymagań na user story](/pl/docs/features/planning-and-user-stories/).

## Z czego się składa

Speedwave uruchamia Redmine jako kontener typu worker i przekazuje mu wywołania narzędzi. Worker podłącza w trybie tylko do odczytu plik `/tokens/api_key` z kluczem API, a z tego samego folderu wczytuje `config.json`, w którym znajdzie adres URL Redmine, opcjonalne ID i nazwę projektu oraz numeryczne odwzorowania statusu, priorytetu, trackera i aktywności. Na hoście oba pliki leżą w `~/.speedwave/tokens/<project>/redmine/`.

- ~/.speedwave/tokens/&lt;project&gt;/redmine/
  - api_key
  - config.json

## Jak to działa

Z Redmine łączysz się kluczem API, a nie przez OAuth ani przez login i hasło. Kreator konfiguracji w aplikacji Desktop najpierw sprawdza poprawność klucza, a potem pobiera twoje projekty, statusy, trackery, priorytety i aktywności, żebyś mógł potwierdzić odwzorowania ID. Nazwy stara się dopasować sam: z każdego klucza odcina przedrostek kategorii, a resztę zestawia z nazwami w Redmine bez rozróżniania wielkości liter. Instancja Redmine w innym języku niż angielski nie dopasuje się automatycznie, więc te odwzorowania trzeba wskazać ręcznie.

Odwzorowania wiążą czytelne klucze, takie jak `status_new` czy `priority_high`, z numerycznymi ID Redmine właściwymi dla danego projektu, bo ta sama nazwa może w każdej instancji wskazywać inne ID. Możesz też dodać własne klucze; plik konfiguracyjny przyjmuje dowolną parę `kategoria_nazwa`. Zanim Speedwave utworzy albo zaktualizuje zgłoszenie, wczytuje odwzorowania narzędziem `getMappings`, a `getConfig` podaje ID, nazwę i adres URL aktywnego projektu. Czytelna nazwa bez odwzorowania zwraca błąd, który wylicza dostępne wartości danego pola.

Opisy zgłoszeń, notatki, dzienniki zmian i komentarze zapisuje się w składni Textile, a nie w Markdownie, i Speedwave czyści je przed wysłaniem: wycina niebezpieczne znaczniki HTML oraz schematy URI przypominające skrypty, a zostawia bezpieczny zestaw znaczników formatujących.

Ustawienie `project_id` zawęża nie tylko listę narzędzi. Odczyty zostają przypięte do tego projektu, zmiany są wobec niego wcześniej weryfikowane, a próba przeniesienia zgłoszenia gdzie indziej przez `updateIssue` kończy się błędem zakresu. Gdy w `config.json` brakuje `host_url`, Speedwave sięga po zmienną środowiskową `REDMINE_URL`.

Błędy API są opisane wprost: `401` to zły klucz, `403` to za małe uprawnienia, `404` to brakujący element, `422` to błędy walidacji pól po stronie Redmine, a jeszcze inny komunikat dostajesz, kiedy żądanie w ogóle nie dochodzi do serwera. Nieudane żądania ponawiają się automatycznie do 3 razy, z odstępem 2, 4, a potem 8 sekund.

### Klucze odwzorowań ID

| Kategoria | Klucze |
|---|---|
| Status | `status_new`, `status_in_progress`, `status_resolved`, `status_feedback`, `status_closed`, `status_rejected` |
| Priorytet | `priority_low`, `priority_normal`, `priority_high`, `priority_urgent`, `priority_immediate` |
| Tracker | `tracker_bug`, `tracker_feature`, `tracker_task`, `tracker_support` |
| Aktywność | `activity_design`, `activity_development`, `activity_testing`, `activity_documentation`, `activity_support`, `activity_management`, `activity_devops`, `activity_review` |

### Co potrafi Speedwave

23 narzędzia w siedmiu obszarach. Usunięć nie da się cofnąć.

| Narzędzie | Co robi |
|---|---|
| `listIssueIds` | Podaje ID zgłoszeń, z filtrami po projekcie, statusie, przypisanej osobie, trackerze i priorytecie. |
| `getIssueFull` | Pobiera pełne dane zgłoszenia, wraz z polami niestandardowymi, dziennikiem zmian, załącznikami i relacjami. |
| `searchIssueIds` | Szuka zgłoszeń po treści zapytania, opcjonalnie w obrębie projektu. |
| `createIssue` | Zakłada nowe zgłoszenie, z trackerem, statusem, priorytetem, osobą przypisaną i zgłoszeniem nadrzędnym po ID albo nazwie. |
| `updateIssue` | Zmienia pola istniejącego zgłoszenia i w tym samym wywołaniu dopisuje notatkę. |
| `commentIssue` | Dodaje do zgłoszenia komentarz (wpis dziennika). |
| `listJournals` | Podaje wpisy dziennika zgłoszenia (komentarze i historię). |
| `updateJournal` | Zmienia treść istniejącego wpisu dziennika. |
| `deleteJournal` (destrukcyjne) | Trwale kasuje wpis dziennika. |
| `listTimeEntries` | Podaje zarejestrowany czas pracy, z filtrami po zgłoszeniu, projekcie, użytkowniku i zakresie dat. |
| `createTimeEntry` | Rejestruje czas pracy przy zgłoszeniu albo projekcie. |
| `updateTimeEntry` | Zmienia liczbę godzin, aktywność albo komentarz przy istniejącym wpisie czasu pracy. |
| `listUsers` | Podaje użytkowników, opcjonalnie zawężonych do członków projektu. |
| `resolveUser` | Zamienia `me`, ID użytkownika albo nazwę użytkownika na ID użytkownika. |
| `getCurrentUser` | Zwraca profil zalogowanego użytkownika. |
| `listProjectIds` | Podaje ID projektów, z filtrem statusu. |
| `getProjectFull` | Pobiera pełne dane projektu, wraz z trackerami, kategoriami i modułami. |
| `searchProjectIds` | Szuka projektów po nazwie, identyfikatorze albo opisie. |
| `listRelations` | Podaje relacje zgłoszenia z innymi zgłoszeniami. |
| `createRelation` | Łączy dwa zgłoszenia relacją danego typu, a przy `precedes` albo `follows` dodaje jeszcze opóźnienie w dniach. |
| `deleteRelation` (destrukcyjne) | Trwale kasuje relację. |
| `getMappings` | Zwraca odwzorowania ID projektu dla statusu, priorytetu, trackera i aktywności. |
| `getConfig` | Zwraca ID, nazwę i adres URL aktywnego projektu. |

Typy relacji: `relates`, `duplicates`, `duplicated`, `blocks`, `blocked`, `precedes`, `follows`, `copied_to`, `copied_from`.

## Skonfiguruj to

1. W Redmine otwórz **My account** i skopiuj **API access key**.
2. W aplikacji Desktop otwórz kartę integracji Redmine i uruchom kreatora. Wpisz swój **Redmine URL** oraz **API Key**, a następnie kliknij **Validate**.
3. Po walidacji wybierz projekt (albo **All projects**) i potwierdź odwzorowania ID dla statusu, priorytetu, trackera i aktywności.
4. Zapisz. Jeśli zobaczysz taką prośbę, zrestartuj kontenery projektu, żeby worker wczytał nową konfigurację.

<DesktopFrame screen="integrations" />
**Więcej niż 100 projektów:** Kreator pobiera do 100 projektów. Jeśli twojego nie ma na liście, otwórz go w webowym interfejsie Redmine, odczytaj jego slug i wpisz `project_id` z tym slugiem wprost w `config.json`.

## Granice bezpieczeństwa

Worker Redmine podłącza wyłącznie własny klucz API, w trybie tylko do odczytu, i nie sięga po tokeny ani dane logowania innych usług. Zajrzyj do opisu tego, [jak obsługiwane są dane uwierzytelniające](/pl/docs/security/credentials/), żeby zobaczyć, jak Speedwave odgradza sekrety każdego workera od reszty systemu. Kiedy `project_id` pozostaje pusty, Speedwave może podać go osobno przy każdym wywołaniu, zamiast być przypięty na stałe do jednego projektu.
**Firmowe CA albo proxy HTTP:** Aplikacja Desktop korzysta z wbudowanych certyfikatów CA, a nie z systemowego magazynu certyfikatów, i nie wykrywa systemowego proxy. Firmowy certyfikat CA może wywołać błąd TLS w trakcie walidacji, a proxy HTTP może sprawić, że połączenie przekroczy limit czasu.