Salta ai contenuti

API: Spazi di lavoro

GET /api/workspaces

Restituisce tutti gli spazi di lavoro di cui sei membro, con il tuo ruolo in ciascuno.

[
{
"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 è null per gli spazi di lavoro personali — i client mostrano un’etichetta localizzata a partire da ownerFirstName.
POST /api/workspaces
{ "name": "Renovation" }

Restituisce 201 con { "id": "…" }. Errori: 409 se possiedi già uno spazio di lavoro con questo nome (senza distinzione tra maiuscole e minuscole), 403 se hai raggiunto il tuo limite di spazi di lavoro condivisi.

DELETE /api/workspaces/{workspaceId}

Solo per il proprietario. Restituisce 204. Elimina definitivamente tutte le attività, le liste, le appartenenze e gli allegati. Gli spazi di lavoro personali non possono essere eliminati.

Ogni spazio di lavoro ha un limite di membri che conta tutti i membri, proprietario incluso; è un entitlement del proprietario dello spazio di lavoro (piano predefinito: 5).

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

I nuovi membri vengono aggiunti esclusivamente tramite inviti via email.

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

Restituisce 204. Ruoli: ADMIN o MEMBER — la proprietà non è trasferibile tramite questo endpoint.

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

Restituisce 204. I proprietari non possono essere rimossi.

POST /api/workspaces/{workspaceId}/leave

Restituisce 204. Abbandona uno spazio di lavoro condiviso a cui ti sei unito: le attività di cui sei autore vengono riassegnate a un «Utente inattivo» riservato e le tue assegnazioni vengono azzerate. Il proprietario non può abbandonare (400) — trasferisci prima la proprietà. Chi non è membro riceve 404.

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

Solo il proprietario. Restituisce 204: il destinatario diventa il proprietario e chi effettua la chiamata resta come amministratore; da quel momento i limiti di archiviazione e di membri dello spazio di lavoro seguono il piano del nuovo proprietario. Errori: 404 quando il destinatario non è membro, 400 per uno spazio di lavoro personale o un trasferimento a te stesso, 403 quando il destinatario ha raggiunto il limite di spazi di lavoro condivisi che può possedere, 409 quando il destinatario possiede già uno spazio di lavoro con lo stesso nome.

Gli inviti sono personali: ognuno è legato a un singolo indirizzo email, valido per 7 giorni e monouso. Gli inviti scaduti vengono inoltre rimossi da un job di pulizia giornaliero.

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

Solo proprietario/admin, solo spazi di lavoro condivisi, al massimo 20 indirizzi per richiesta. Ogni indirizzo invitato con successo riceve un’email con un link di invito personale (token tdminv_…). Reinvitare un indirizzo emette un nuovo link e annulla il precedente. La risposta riporta l’esito per ogni indirizzo:

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

Esiti: INVITED, ALREADY_MEMBER, INVALID_ADDRESS. Errori: 400 per un batch vuoto o troppo grande, 403 per i membri semplici o quando lo spazio di lavoro ha già raggiunto il suo limite di membri, 404 per chi non è membro.

GET /api/workspaces/invites/{token}

Richiede l’autenticazione, e l’invito deve essere indirizzato all’email dell’account con cui hai effettuato l’accesso. Restituisce chi ti ha invitato:

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

I token sconosciuti, scaduti e di qualcun altro sono indistinguibili: tutti 404.

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

newlyJoined è false quando eri già membro.

Vale la stessa regola personale: il token funziona solo per l’account con l’indirizzo email invitato e viene consumato in caso di successo. I token sconosciuti, scaduti e di qualcun altro restituiscono tutti 404. Restituisce 403 quando lo spazio di lavoro ha raggiunto il suo limite di membri — l’invito sopravvive e può essere ritentato finché è valido.

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

Recupera tutto ciò che è cambiato dopo il cursore del client, per client capaci di funzionare offline: le entità modificate come oggetti completi nel loro stato attuale, le eliminazioni come liste di id e il cursore successivo. since=0 restituisce lo spazio di lavoro completo (lo specchio iniziale). Applicare un batch è un upsert idempotente, quindi ripetere i recuperi o sovrapporli è innocuo.

{
"cursor": 812,
"tasks": [ { "id": "019f…", "title": "…", "subtasks": [], "attachments": [] } ],
"deletedTaskIds": ["019f…"],
"lists": [],
"deletedListIds": [],
"members": [],
"deletedMemberIds": []
}
  • Gli oggetti attività hanno la stessa forma di GET /api/workspaces/{id}/tasks; le modifiche a sottoattività e allegati compaiono come modifiche della loro attività padre.
  • Quando una lista viene eliminata, le sue attività non vengono rinviate: i client azzerano quel listId localmente, in linea con il comportamento del server.
  • Le modifiche più recenti di circa un secondo sono già incluse nel batch, ma il cursore si ferma prima di esse — il recupero successivo le consegna di nuovo, e l’upsert idempotente assorbe la ripetizione. Un client che interroga subito dopo la propria scrittura la vede quindi sempre.
GET /api/workspaces/{workspaceId}/events

Uno stream di server-sent events che segnala quando il contenuto dello spazio di lavoro è cambiato — un campanello, non un feed di dati: quando scatta, richiedi di nuovo ciò che ti serve.