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

# SDK Go: workspaces e membros

> Crie e gerencie workspaces, convide membros, defina cargos e compartilhe aplicações com c.Workspaces. Atue sobre uma aplicação compartilhada pelo id composto.

Um workspace compartilha aplicações com outros usuários da Square Cloud, cada um com um cargo. `c.Workspaces` gerencia os workspaces, `c.Workspaces.Members` seus membros e `c.Workspaces.Apps` as aplicações compartilhadas.

Criar workspaces requer um plano Standard, Pro ou Enterprise.

Cada trecho abaixo roda sozinho dentro deste programa: cole um de cada vez em `main` e execute o `goimports` (veja [Executando os exemplos](/pt-br/sdks/go/client#executando-os-exemplos)).

```go theme={"system"}
package main

import (
	"context"
	"os"

	"github.com/squarecloudofc/sdk-api-go/v3"
)

var (
	ctx         = context.Background()
	c           = squarecloud.New(os.Getenv("SQUARECLOUD_API_KEY"))
	workspaceID = "0123456789abcdef0123456789abcdef"
	appID       = "abc123def456abc123def456"
	memberID    = "1234567890" // a member's ID, from c.Workspaces.Get
)

func main() {
	// Paste one snippet here, then run goimports.
}
```

## Workspaces

```go theme={"system"}
created, err := c.Workspaces.Create(ctx, "My team")
if err != nil {
	log.Fatal(err)
}

workspace, err := c.Workspaces.Get(ctx, created.ID)
if err != nil {
	log.Fatal(err)
}

fmt.Println(workspace.Name, workspace.Owner, workspace.CreatedAt)

for _, member := range workspace.Members {
	name := "(unknown)"
	if member.Name != nil {
		name = *member.Name
	}
	fmt.Println(member.ID, name, member.Group, member.JoinedAt)
}
for _, app := range workspace.Applications {
	fmt.Println(app.ID, app.Name, app.Lang, app.RAM)
}
```

`Workspaces.List(ctx)` retorna todos os workspaces dos quais você é dono ou membro, com os mesmos campos:

```go theme={"system"}
workspaces, err := c.Workspaces.List(ctx)
if err != nil {
	log.Fatal(err)
}
for _, w := range workspaces {
	fmt.Println(w.ID, w.Name, len(w.Members))
}
```

Para sair de um workspace como membro, ou excluí-lo como dono:

```go theme={"system"}
if err := c.Workspaces.Leave(ctx, workspaceID); err != nil { // as a member
	log.Fatal(err)
}
if err := c.Workspaces.Delete(ctx, workspaceID); err != nil { // as the owner
	log.Fatal(err)
}
```

| Campo | Descrição |
| - | - |
| `ID` (`id`) | 32 caracteres hexadecimais (workspaces mais antigos mantêm um id de 40 caracteres) |
| `Name` (`name`) | Nome do workspace (de 1 a 32 caracteres) |
| `Owner` (`owner`) | Id do usuário dono |
| `Members` (`members`) | `ID`, `Name`, `Group`, `JoinedAt` (`joinedAt`). `Name` é um `*string`, `nil` quando não pode ser resolvido (uma conta excluída) |
| `Applications` (`applications`) | `ID`, `Name`, `Description` (`desc`), `RAM`, `Lang`, `Domain`, `Custom`. `Description`, `Domain` e `Custom` são `*string` |
| `CreatedAt` (`createdAt`) | Data de criação (`time.Time`) |

O dono não pode sair (400 `CANNOT_LEAVE_OWNER`): exclua o workspace em vez disso.

## Membros

Adicionar um membro requer um **código de convite** que o membro gera com `Members.InviteCode(ctx)`. O código é válido por **5 minutos**.

```go theme={"system"}
// The member runs this and sends you the code
code, err := c.Workspaces.Members.InviteCode(ctx)
if err != nil {
	log.Fatal(err)
}
fmt.Println(code)
```

```go theme={"system"}
// The owner adds them with a role
code := "5d8e1f2a3b4c4d6e9f0a1b2c3d4e5f6a" // the code the member sent you
if err := c.Workspaces.Members.Add(ctx, workspaceID, code, squarecloud.GroupMaintain); err != nil {
	log.Fatal(err)
}
```

Para alterar o cargo de um membro ou removê-lo, passe o `ID` dele obtido em `Workspaces.Get`:

```go theme={"system"}
if err := c.Workspaces.Members.Update(ctx, workspaceID, memberID, squarecloud.GroupView); err != nil {
	log.Fatal(err)
}
if err := c.Workspaces.Members.Remove(ctx, workspaceID, memberID); err != nil {
	log.Fatal(err)
}
```

Cargos (`WorkspaceGroup`): `GroupView` (`view`), `GroupManager` (`manager`), `GroupMaintain` (`maintain`) e `GroupAdmin` (`admin`). O `Group` de um membro é uma `string` simples, já que também pode ser `"owner"`. Chamar um método que seu cargo não permite resulta em 403 `PERMISSION_DENIED`.

## Aplicações compartilhadas

```go theme={"system"}
if err := c.Workspaces.Apps.Add(ctx, workspaceID, appID); err != nil {
	log.Fatal(err)
}
if err := c.Workspaces.Apps.Remove(ctx, workspaceID, appID); err != nil {
	log.Fatal(err)
}
```

Um workspace pode conter até 100 aplicações (400 `APPLICATIONS_LIMIT_REACHED`).

### Atuando sobre uma aplicação compartilhada

Para atuar sobre uma aplicação compartilhada com você, passe o id composto `<appId>-<workspaceId>` para qualquer método de `c.Apps`. `Workspaces.Get` e `Workspaces.List` retornam ids brutos, então monte-o você mesmo:

```go theme={"system"}
workspace, err := c.Workspaces.Get(ctx, workspaceID)
if err != nil {
	log.Fatal(err)
}

for _, app := range workspace.Applications {
	status, err := c.Apps.Status(ctx, app.ID+"-"+workspace.ID)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(app.Name, status.Running)
}

// Status of every app of the workspace in one request
statuses, err := c.Apps.StatusAll(ctx, workspaceID)
if err != nil {
	log.Fatal(err)
}
for _, s := range statuses {
	fmt.Println(s.ID, s.Running)
}
```

## Erros

As rotas de workspace, exceto `Get`, enviam os ids no corpo da requisição, então um id vazio nelas resulta em 400 `INVALID_ID` vindo do servidor (não é um erro local). `Get` envia o id no caminho, então um id vazio falha localmente com `INVALID_ID` (status `0`).

| Status | Código | Quando |
| - | - | - |
| 400 | `INVALID_NAME` | O nome não tem de 1 a 32 caracteres |
| 400 | `WORKSPACE_LIMIT_REACHED`, `MEMBERS_LIMIT_REACHED`, `APPLICATIONS_LIMIT_REACHED` | Um limite do plano ou do workspace foi atingido |
| 400 | `INVALID_CODE` | O código de convite está ausente, malformado ou expirado |
| 400 | `INVALID_GROUP` | O cargo não é `view`, `manager`, `maintain` nem `admin` |
| 400 | `CANNOT_INVITE_OWNER`, `CANNOT_EDIT_OWNER`, `CANNOT_LEAVE_OWNER` | A ação não se aplica ao dono |
| 400 | `MEMBER_ALREADY_ADDED`, `APP_ALREADY_IN_WORKSPACE` | Já está no workspace |
| 403 | `UPGRADE_REQUIRED` | O plano não permite criar workspaces |
| 403 | `PERMISSION_DENIED` | Seu cargo não permite a ação |
| 404 | `WORKSPACE_NOT_FOUND`, `MEMBER_NOT_FOUND`, `APP_NOT_FOUND` | Não encontrado |

## Próximos passos

<CardGroup cols={3}>
  <Card title="IA" icon="robot" href="/pt-br/sdks/go/ai">
    Chat completions pelo AI Gateway.
  </Card>

  <Card title="Referência da API de workspaces" icon="code" href="/pt-br/api-reference/endpoint/workspace/list">
    Os endpoints REST por trás destes métodos.
  </Card>

  <Card title="Workspaces pela CLI" icon="terminal" href="/pt-br/cli-reference/workspaces">
    As mesmas ações pelo terminal.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.