Canais
Os canais levam as conversas da equipe ao Libre WebUI: salas públicas e privadas, além de mensagens diretas, com tópicos, reações, itens fixados, acompanhamento de não lidas, anexos de arquivo e respostas de @model — tudo sobre as mesmas bases persistentes e criptografadas do chat.
Tipos de canal e participação
| Tipo | Quem pode ver | Quem participa |
|---|---|---|
public | Todos podem navegar | Qualquer pessoa pode entrar por conta própria |
private | Somente membros | O proprietário convida os membros |
dm | Somente os dois participantes | Aberta automaticamente; sempre exatamente duas pessoas |
A participação é a única autoridade sobre o conteúdo do canal: toda leitura e gravação — inclusive downloads de anexos e entrega de eventos ao vivo — verifica primeiro se quem chamou é membro, e quem não é membro recebe um 404 que não revela a existência do recurso. A função de administrador global não concede deliberadamente acesso ao conteúdo dos canais.
Quem cria um canal público ou privado é seu proprietário. Proprietários podem renomear, arquivar, convidar (em canais privados), remover membros, moderar mensagens e excluir o canal; para sair, um proprietário exclui o canal, nunca o abandona. Mensagens diretas são desduplicadas por par: abrir uma DM com a mesma pessoa sempre leva à mesma conversa.
A linha do tempo
As mensagens formam uma linha do tempo persistente e ordenada, lida com cursores keyset (created_at mais o ID da mensagem) em qualquer direção, para que a paginação nunca pule nem duplique entradas.
- Publicações idempotentes. O cliente fornece a identidade da mensagem; uma solicitação repetida chega à mesma entrada da linha do tempo exatamente uma vez.
- Exclusão com marcador. Excluir uma mensagem limpa seu conteúdo, mas mantém a entrada na linha do tempo, para que os tópicos nunca fiquem sem referência e a ordem nunca mude. Autores excluem as próprias mensagens; proprietários do canal podem moderar qualquer uma.
- Edições são exclusivas do autor e recebem um marcador
editedAt. - Tópicos têm apenas um nível. Qualquer mensagem raiz pode conter um tópico; respostas a respostas são rejeitadas. Mensagens raiz exibem contagens de respostas em tempo real.
- Reações são únicas por usuário e por emoji, contadas sem duplicatas.
- Itens fixados são organizados pelos membros e listados por canal.
Nomes e descrições de canais e o conteúdo das mensagens são criptografados em repouso com o mesmo limite aplicado às mensagens de chat.
Estado de não lidas
Cada participação mantém um cursor monotônico de leitura. As contagens de não lidas são calculadas no servidor por canal (suas próprias mensagens nunca são consideradas não lidas), e POST /api/channels/:channelId/read avança o cursor — ele nunca retrocede, portanto um cliente desatualizado não pode ressuscitar mensagens já lidas.
Entrega em tempo real
Toda alteração da linha do tempo é acrescentada ao fluxo persistente de eventos channel:<id> e distribuída por GET /api/channels/:channelId/events (SSE). A participação é verificada novamente antes de cada entrega; assim, remover um membro encerra de forma segura seu fluxo ao vivo. A linha do tempo SQL continua sendo a fonte definitiva: quem perdeu eventos simplesmente relê a linha do tempo — o registro serve para entrega, não como fonte da verdade.
Anexos
Os arquivos são enviados primeiro (POST /api/channels/:channelId/attachments), ficam brevemente em um cache compartilhado de reivindicações e são anexados quando a mensagem é publicada; uma reivindicação de upload é de uso único e expira após 15 minutos se não for usada. Os bytes do blob pertencem a quem fez o upload (e consomem sua cota), e cada solicitação de download verifica novamente a participação no canal.
Respostas de @model
O campo de composição pode direcionar uma mensagem a um modelo. A resposta aparece imediatamente como uma mensagem pendente de autoria do modelo e é concluída por uma tarefa persistente executada estritamente sob a identidade do membro que a iniciou: o acesso a modelos, as credenciais de provedor e o roteamento dessa pessoa — nunca os do proprietário do canal nem de outro membro. Um membro removido enquanto uma menção está na fila não pode mantê-la ativa: a tarefa verifica novamente a participação antes de gerar e registra uma falha visível. Falhas do modelo aparecem na própria resposta, em vez de desaparecerem em uma fila.
As respostas do modelo usam como contexto a conversa recente do canal (até 30 mensagens). Elas são executadas como conclusões únicas: ferramentas de chat, recuperação de conhecimento e pesquisa na web ainda não estão conectadas às menções de canal.
Limites
| Limite | Valor |
|---|---|
| Canais criados por usuário | 50 |
| Membros por canal | 200 |
| Mensagens por canal | 50.000 |
| Tamanho da mensagem | 8.000 caracteres |
| Anexos por mensagem | 5 × 10 MB |
| Reações por mensagem | 200 |
Limites funcionais
- Indicadores de presença e estado de digitação não estão implementados.
- A exportação do conteúdo dos canais e as políticas de retenção seguem o procedimento de backup da instância; ainda não há exportação por canal.
- Menções geram avisos pelo serviço de notificações do aplicativo; ainda não há uma preferência de notificação por canal além de sair do canal.