feat: Add 'atas' (minutes/records) management feature, and implement various improvements across UI, backend logic, and authentication.

This commit is contained in:
2025-12-02 16:37:48 -03:00
parent 05e7f1181d
commit 4bd9e21748
265 changed files with 29156 additions and 26460 deletions

View File

@@ -1,8 +1,8 @@
import { v } from 'convex/values';
import { mutation, query, internalMutation } from './_generated/server';
import { Doc, Id } from './_generated/dataModel';
import type { QueryCtx, MutationCtx } from './_generated/server';
import { internal, api } from './_generated/api';
import { api, internal } from './_generated/api';
import type { Doc, Id } from './_generated/dataModel';
import type { MutationCtx, QueryCtx } from './_generated/server';
import { internalMutation, mutation, query } from './_generated/server';
import { getCurrentUserFunction } from './auth';
// ========== HELPERS ==========
@@ -917,22 +917,34 @@ export const editarMensagem = mutation({
// Verificar se usuário é o remetente
if (mensagem.remetenteId !== usuarioAtual._id) {
return { sucesso: false, erro: 'Você só pode editar suas próprias mensagens' };
return {
sucesso: false,
erro: 'Você só pode editar suas próprias mensagens'
};
}
// Verificar se mensagem não foi deletada
if (mensagem.deletada) {
return { sucesso: false, erro: 'Não é possível editar uma mensagem deletada' };
return {
sucesso: false,
erro: 'Não é possível editar uma mensagem deletada'
};
}
// Verificar se não é mensagem agendada
if (mensagem.agendadaPara) {
return { sucesso: false, erro: 'Não é possível editar mensagens agendadas' };
return {
sucesso: false,
erro: 'Não é possível editar mensagens agendadas'
};
}
// Validar novo conteúdo
if (!args.novoConteudo || args.novoConteudo.trim().length === 0) {
return { sucesso: false, erro: 'O conteúdo da mensagem não pode estar vazio' };
return {
sucesso: false,
erro: 'O conteúdo da mensagem não pode estar vazio'
};
}
// Normalizar conteúdo para busca
@@ -1104,13 +1116,19 @@ export const adicionarParticipanteSala = mutation({
// Verificar se é sala de reunião
if (conversa.tipo !== 'sala_reuniao') {
return { sucesso: false, erro: 'Esta funcionalidade é apenas para salas de reunião' };
return {
sucesso: false,
erro: 'Esta funcionalidade é apenas para salas de reunião'
};
}
// Verificar se usuário é administrador
const isAdmin = await verificarPermissaoAdmin(ctx, args.conversaId, usuarioAtual._id);
if (!isAdmin) {
return { sucesso: false, erro: 'Apenas administradores podem adicionar participantes' };
return {
sucesso: false,
erro: 'Apenas administradores podem adicionar participantes'
};
}
// Verificar se participante já está na sala
@@ -1168,13 +1186,19 @@ export const removerParticipanteSala = mutation({
// Verificar se é sala de reunião
if (conversa.tipo !== 'sala_reuniao') {
return { sucesso: false, erro: 'Esta funcionalidade é apenas para salas de reunião' };
return {
sucesso: false,
erro: 'Esta funcionalidade é apenas para salas de reunião'
};
}
// Verificar se usuário é administrador
const isAdmin = await verificarPermissaoAdmin(ctx, args.conversaId, usuarioAtual._id);
if (!isAdmin) {
return { sucesso: false, erro: 'Apenas administradores podem remover participantes' };
return {
sucesso: false,
erro: 'Apenas administradores podem remover participantes'
};
}
// Verificar se participante está na sala
@@ -1189,7 +1213,10 @@ export const removerParticipanteSala = mutation({
args.participanteId
);
if (isParticipanteAdmin) {
return { sucesso: false, erro: 'Não é possível remover outros administradores' };
return {
sucesso: false,
erro: 'Não é possível remover outros administradores'
};
}
// Remover participante
@@ -1239,7 +1266,10 @@ export const promoverAdministrador = mutation({
// Verificar se é sala de reunião
if (conversa.tipo !== 'sala_reuniao') {
return { sucesso: false, erro: 'Esta funcionalidade é apenas para salas de reunião' };
return {
sucesso: false,
erro: 'Esta funcionalidade é apenas para salas de reunião'
};
}
// Verificar se usuário é administrador
@@ -1314,7 +1344,10 @@ export const rebaixarAdministrador = mutation({
// Verificar se é sala de reunião
if (conversa.tipo !== 'sala_reuniao') {
return { sucesso: false, erro: 'Esta funcionalidade é apenas para salas de reunião' };
return {
sucesso: false,
erro: 'Esta funcionalidade é apenas para salas de reunião'
};
}
// Verificar se usuário é administrador
@@ -1343,7 +1376,10 @@ export const rebaixarAdministrador = mutation({
// Não permitir rebaixar o criador da sala
if (conversa.criadoPor === args.participanteId) {
return { sucesso: false, erro: 'Não é possível rebaixar o criador da sala' };
return {
sucesso: false,
erro: 'Não é possível rebaixar o criador da sala'
};
}
// Remover da lista de administradores
@@ -1465,13 +1501,19 @@ export const encerrarReuniao = mutation({
// Verificar se é sala de reunião
if (conversa.tipo !== 'sala_reuniao') {
return { sucesso: false, erro: 'Esta funcionalidade é apenas para salas de reunião' };
return {
sucesso: false,
erro: 'Esta funcionalidade é apenas para salas de reunião'
};
}
// Verificar se usuário é administrador
const isAdmin = await verificarPermissaoAdmin(ctx, args.conversaId, usuarioAtual._id);
if (!isAdmin) {
return { sucesso: false, erro: 'Apenas administradores podem encerrar a reunião' };
return {
sucesso: false,
erro: 'Apenas administradores podem encerrar a reunião'
};
}
// Criar notificação para todos os participantes informando que a reunião foi encerrada
@@ -1524,13 +1566,19 @@ export const enviarNotificacaoReuniao = mutation({
// Verificar se é sala de reunião
if (conversa.tipo !== 'sala_reuniao') {
return { sucesso: false, erro: 'Esta funcionalidade é apenas para salas de reunião' };
return {
sucesso: false,
erro: 'Esta funcionalidade é apenas para salas de reunião'
};
}
// Verificar se usuário é administrador
const isAdmin = await verificarPermissaoAdmin(ctx, args.conversaId, usuarioAtual._id);
if (!isAdmin) {
return { sucesso: false, erro: 'Apenas administradores podem enviar notificações' };
return {
sucesso: false,
erro: 'Apenas administradores podem enviar notificações'
};
}
// Criar notificação para todos os participantes
@@ -2033,7 +2081,7 @@ export const listarTodosUsuarios = query({
usuarios
.filter((u) => u._id !== usuarioAtual._id)
.map(async (u) => {
let matricula: string | undefined = undefined;
let matricula: string | undefined;
if (u.funcionarioId) {
const funcionario = await ctx.db.get(u.funcionarioId);
matricula = funcionario?.matricula;