Przejdź do głównej zawartości

API: Obszary robocze

GET /api/workspaces

Zwraca każdy obszar roboczy, którego jesteś członkiem, wraz z twoją rolą w każdym z nich.

[
{
"id": "019f7462-ac2a-73e3-ab40-be2e43f943f9",
"name": null,
"personal": true,
"ownerFirstName": "Greta",
"role": "OWNER"
},
{
"id": "019f7464-1617-7464-b8ef-7f34b631bdfa",
"name": "Lengl Family",
"personal": false,
"ownerFirstName": "Greta",
"role": "OWNER"
}
]
  • name jest null dla osobistych obszarów roboczych — klienci renderują zlokalizowaną etykietę na podstawie ownerFirstName.
POST /api/workspaces
{ "name": "Renovation" }

Zwraca 201 z { "id": "…" }. Błędy: 409, jeśli masz już obszar roboczy o tej nazwie (bez rozróżniania wielkości liter), 403, jeśli osiągnąłeś swój limit wspólnych obszarów roboczych.

DELETE /api/workspaces/{workspaceId}

Tylko właściciel. Zwraca 204. Trwale usuwa wszystkie zadania, listy, członkostwa i załączniki. Osobistych obszarów roboczych nie można usunąć.

Każdy obszar roboczy ma limit członków, który liczy wszystkich członków, łącznie z właścicielem; jest to uprawnienie właściciela obszaru roboczego (domyślny plan: 5).

GET /api/workspaces/{workspaceId}/members
[
{
"userId": "019f…",
"firstName": "Greta",
"lastName": "Lengl",
"avatarUrl": "/api/avatars/019f…?v=3",
"role": "OWNER"
}
]

Nowi członkowie są dodawani wyłącznie przez zaproszenia e-mailowe.

PUT /api/workspaces/{workspaceId}/members/{memberId}
{ "role": "ADMIN" }

Zwraca 204. Role: ADMIN lub MEMBER — własności nie można przenieść przez ten endpoint.

DELETE /api/workspaces/{workspaceId}/members/{memberId}

Zwraca 204. Właścicieli nie można usunąć.

POST /api/workspaces/{workspaceId}/leave

Zwraca 204. Opuszcza wspólny obszar roboczy, do którego dołączyłeś: zadania, których jesteś autorem, zostają przypisane do zarezerwowanego użytkownika „Nieaktywny użytkownik”, a twoje przypisania zostają wyczyszczone. Właściciel nie może opuścić obszaru (400) — najpierw przekaż własność. Osoby niebędące członkami dostają 404.

POST /api/workspaces/{workspaceId}/transfer-ownership
{ "newOwnerId": "019f…" }

Tylko dla właściciela. Zwraca 204: odbiorca zostaje właścicielem, a wywołujący pozostaje administratorem; limity przestrzeni i członków obszaru roboczego od tej chwili wynikają z planu nowego właściciela. Błędy: 404, gdy odbiorca nie jest członkiem, 400 dla osobistego obszaru roboczego lub przekazania samemu sobie, 403, gdy odbiorca osiągnął limit posiadanych wspólnych obszarów roboczych, 409, gdy odbiorca posiada już obszar roboczy o tej samej nazwie.

Zaproszenia są osobiste: każde jest powiązane z jednym adresem e-mail, ważne przez 7 dni i jednorazowe. Wygasłe zaproszenia są też usuwane przez codzienne zadanie porządkujące.

POST /api/workspaces/{workspaceId}/invites
{ "emails": ["person@example.com", "other@example.com"] }

Tylko właściciel/administrator, tylko wspólne obszary robocze, maksymalnie 20 adresów na żądanie. Każdy pomyślnie zaproszony adres otrzymuje e-mail z osobistym linkiem z zaproszeniem (token tdminv_…). Ponowne zaproszenie adresu wystawia nowy link i unieważnia poprzedni. Odpowiedź raportuje wynik dla każdego adresu:

{
"results": [
{ "email": "person@example.com", "outcome": "INVITED" },
{ "email": "other@example.com", "outcome": "ALREADY_MEMBER" }
]
}

Wyniki: INVITED, ALREADY_MEMBER, INVALID_ADDRESS. Błędy: 400 dla pustej lub zbyt dużej partii, 403 dla zwykłych członków lub gdy obszar roboczy osiągnął już swój limit członków, 404 dla osób niebędących członkami.

GET /api/workspaces/invites/{token}

Wymaga uwierzytelnienia, a zaproszenie musi być zaadresowane na adres e-mail zalogowanego konta. Zwraca informację, kto cię zaprosił:

{
"workspaceName": "Lengl Family",
"personal": false,
"ownerFirstName": "Greta",
"ownerLastName": "Lengl",
"ownerAvatarUrl": null
}

Nieznane, wygasłe i cudze tokeny są nieodróżnialne: wszystkie zwracają 404.

POST /api/workspaces/join
{ "token": "tdminv_…" }
{ "workspaceId": "019f…", "newlyJoined": true }

newlyJoined jest false, gdy konto było już członkiem.

Obowiązuje ta sama osobista zasada: token działa tylko dla konta z zaproszonym adresem e-mail i zostaje zużyty przy powodzeniu. Nieznane, wygasłe i cudze tokeny zwracają 404. Zwraca 403, gdy obszar roboczy osiągnął swój limit członków — zaproszenie pozostaje ważne i można spróbować ponownie, dopóki nie wygaśnie.

GET /api/workspaces/{workspaceId}/sync?since={cursor}

Pobiera wszystko, co zmieniło się po kursorze klienta — dla klientów działających offline: zmienione encje jako pełne obiekty w aktualnym stanie, usunięcia jako listy id oraz następny kursor. since=0 zwraca kompletny obszar roboczy (początkowe odbicie). Zastosowanie paczki to idempotentny upsert, więc powtarzane lub nakładające się pobrania są nieszkodliwe.

{
"cursor": 812,
"tasks": [ { "id": "019f…", "title": "…", "subtasks": [], "attachments": [] } ],
"deletedTaskIds": ["019f…"],
"lists": [],
"deletedListIds": [],
"members": [],
"deletedMemberIds": []
}
  • Obiekty zadań mają ten sam kształt co GET /api/workspaces/{id}/tasks; zmiany podzadań i załączników pojawiają się jako zmiany ich zadania nadrzędnego.
  • Gdy lista zostaje usunięta, jej zadania nie są wysyłane ponownie: klienci czyszczą to listId lokalnie, zgodnie z zachowaniem serwera.
  • Zmiany młodsze niż około sekunda są już zawarte w paczce, ale kursor zatrzymuje się przed nimi — następne pobranie dostarcza je ponownie, a idempotentny upsert pochłania powtórkę. Klient, który pobiera zaraz po własnym zapisie, zawsze go więc widzi.
GET /api/workspaces/{workspaceId}/events

Strumień server-sent events, który sygnalizuje, że zawartość obszaru roboczego się zmieniła — to dzwonek, nie kanał danych: gdy zadzwoni, pobierz ponownie to, czego potrzebujesz.