Organizations

Workspaces, convites por email e gerenciamento de membros.

Visao geral

O modulo de Organizations (ou Workspaces) permite que usuarios criem espacos de trabalho, convidem membros por email e gerenciem roles dentro da organizacao. E a base para qualquer SaaS multi-usuario.

Rotas da API

MetodoRotaDescricao
POST/api/organizationsCriar organizacao
GET/api/organizationsListar organizacoes do usuario
GET/api/organizations/:orgIdDetalhes da organizacao
PUT/api/organizations/:orgIdAtualizar organizacao
DELETE/api/organizations/:orgIdDeletar organizacao (owner)
POST/api/organizations/:orgId/inviteConvidar membro por email
POST/api/organizations/invite/:token/acceptAceitar convite
GET/api/organizations/:orgId/membersListar membros
DELETE/api/organizations/:orgId/members/:idRemover membro
PUT/api/organizations/:orgId/members/:id/roleAlterar role do membro

Fluxo de convite

  1. Owner/admin chama POST /api/organizations/:orgId/invite com { email, role }
  2. Um token de convite e gerado
  3. Um link e criado: http://localhost:3000/invite/<token>
  4. O email e enviado ao convidado (via SMTP se configurado)
  5. O convidado clica no link e chama POST /api/organizations/invite/:token/accept
  6. O usuario e adicionado como membro da organizacao

Roles de organizacao

RolePermissoes
ownerControle total. Pode deletar a org, mudar roles de membros, convidar.
adminPode convidar e remover membros, gerenciar recursos.
memberAcesso basico aos recursos da organizacao.

Schema do banco

Se Prisma estiver habilitado, adicione estes models ao schema.prisma:

model Organization {
  id          String      @id @default(cuid())
  name        String
  slug        String      @unique
  description String?
  members     OrgMember[]
  createdAt   DateTime    @default(now())
  updatedAt   DateTime    @updatedAt
  @@map("organizations")
}

model OrgMember {
  id             String       @id @default(cuid())
  userId         String
  email          String
  role           String       @default("member")
  organizationId String
  organization   Organization @relation(fields: [organizationId], references: [id])
  joinedAt       DateTime     @default(now())
  @@unique([userId, organizationId])
  @@map("org_members")
}

model OrgInvite {
  id             String       @id @default(cuid())
  email          String
  role           String       @default("member")
  token          String       @unique
  organizationId String
  invitedBy      String
  expiresAt      DateTime
  acceptedAt     DateTime?
  @@map("org_invites")
}

Variavel de ambiente

# Base URL para gerar links de convite
APP_URL=http://localhost:3000