Logotipo Hedhog

Receba novidades do Hedhog no seu e-mail

Novos lançamentos, receitas e breaking changes — sem spam.

Submódulo inbox

accounts

Gerencia as caixas de correio do inbox (inbox_account) às quais threads, mensagens, rascunhos e labels pertencem, incluindo a propriedade da conta e o acesso de membros compartilhados.

Caminho de origem: libraries/inbox/src/account

Arquivo do módulo: account.module.ts

Introdução

O submódulo Accounts é dono de `inbox_account`, a entidade raiz da qual todas as outras tabelas do Inbox dependem por meio de `account_id`. Cada conta representa uma única caixa de correio no provedor Resend (a coluna `provider` é um enum atualmente fixado no único valor `RESEND`), identificada por um `email` único e normalizado para minúsculas e por um `display_name` legível. Os campos opcionais `provider_domain_id` / `provider_region` permitem que a conta referencie um domínio de envio verificado específico quando a plataforma gerencia múltiplos domínios Resend, e `signature_html` armazena a assinatura HTML anexada ao compor a partir daquela conta.

O acesso à conta não é exclusivamente de proprietário único: `inbox_account_user` é uma tabela de junção com um `role` de `owner` ou `member`, então uma caixa de correio pode ser compartilhada com vários usuários. `AccountService.create` sempre faz upsert do usuário criador como `owner` e depois faz upsert de quaisquer `users` adicionais passados no corpo da requisição (deduplicados por `userId`) com o papel solicitado, tendo `member` como padrão. `AccountService.update` trata o array `users` como autoritativo quando presente: ele exclui todas as linhas de membership existentes da conta e as recria do zero, sempre mantendo o chamador como `owner` independentemente do que foi passado, o que impede que um membro remova acidentalmente o próprio acesso por meio de uma atualização parcial.

Apenas uma conta por usuário pode ser a padrão por vez. Definir `isDefault: true` na criação ou atualização executa dentro de uma transação que primeiro coloca `is_default` como `false` em todas as outras contas pertencentes àquele `user_id` e então aplica a nova padrão — trata-se de uma restrição por proprietário (espelhada pelo índice parcial único `user_id, is_default` em `inbox_account.yaml`), não global, de modo que dois usuários diferentes podem ter cada um a sua própria conta padrão. A exclusão de uma conta é um soft delete: `deleted_at` é carimbado, e `is_active`/`is_default` são ambos forçados para `false`, de modo que uma caixa de correio removida sai imediatamente da resolução de conta padrão e dos filtros de contas ativas sem precisar de uma segunda escrita.

O controle de acesso aqui é intencionalmente diferente do restante do módulo. `InboxAccessService.assertAccountAccess` (usado por update/delete) verifica se o chamador é o criador original da conta, uma linha em `inbox_account_user` ou detentor do papel `admin`/`admin-inbox` — mas `AccountService.list` não realiza nenhuma filtragem por usuário: ele retorna todas as contas não excluídas que correspondem ao termo de busca, apoiando-se inteiramente no gate de papel em nível de rota (`admin`, `admin-inbox` ou `inbox-owner`) para restringir quem pode chamar o endpoint. Em outras palavras, qualquer usuário que detenha um desses três papéis vê o diretório completo de contas, não apenas as contas às quais pertence — diferentemente de Threads, Messages, Drafts e Labels, que restringem suas consultas por meio de `InboxAccessService.listAccessibleAccountIds(userId)` e só retornam registros que o chamador pode ver. A verificação de e-mail duplicado ao criar e atualizar uma conta (`ConflictException` em caso de colisão) também é executada de forma case-insensitive após o trim, de modo que `[email protected]` e `[email protected]` são tratados como a mesma caixa de correio.

Endpoints HTTP

4 endpoints

Lista paginada de contas de inbox (ordenadas com a padrão primeiro, depois as mais recentes), com os membros compartilhados de cada conta (id, role, name, photoId). Não é restrita ao chamador — qualquer usuário com um dos três papéis permitidos vê todas as contas não excluídas.

Query
page, pageSize, search

Cria uma nova conta de inbox (caixa de correio). O provider é fixado em RESEND.

Body

FieldTypeRequiredNotes
emailstring (email, max 255)yesNormalized to lowercase; must be globally unique among active accounts
displayNamestring (max 180)yes
providerDomainIdstring (max 255)no
providerRegionstring (max 127)no
isDefaultbooleannoUnsets is_default on the caller's other accounts when true
isActivebooleannoDefault: true
signatureHtmlstringno
usersAccountMemberDto[] ({ userId, role? })noAdditional shared members; creator is always upserted as owner

Atualiza uma conta de inbox (atualização parcial, com os mesmos campos da criação). Se "users" for informado, ele substitui integralmente a lista de membros da conta (o chamador é sempre mantido como owner).

Params
id (int)

Faz soft delete de uma conta de inbox (define deleted_at, is_active: false, is_default: false). Não exclui em cascata as threads/mensagens.

Params
id (int)