feat: Introduce structured table definitions in convex/tables for various entities and remove the todos example table.
This commit is contained in:
@@ -4,7 +4,7 @@ import { v } from 'convex/values';
|
||||
import { getCurrentUserFunction } from './auth';
|
||||
import type { Id, Doc } from './_generated/dataModel';
|
||||
import type { MutationCtx, QueryCtx } from './_generated/server';
|
||||
import { flowTemplateStatus, flowInstanceStatus, flowInstanceStepStatus } from './schema';
|
||||
import { flowInstanceStatus, flowInstanceStepStatus, flowTemplateStatus } from './tables/flows';
|
||||
|
||||
// ============================================
|
||||
// HELPER FUNCTIONS
|
||||
@@ -852,7 +852,7 @@ export const getInstanceWithSteps = query({
|
||||
|
||||
// Verificar permissão de visualização
|
||||
const temPermissaoVerTodas = await verificarPermissaoVerTodasFluxos(ctx);
|
||||
|
||||
|
||||
if (!temPermissaoVerTodas) {
|
||||
// Verificar se usuário pertence a algum setor do fluxo ou é o manager
|
||||
const pertenceAoSetor = await usuarioPertenceAAlgumSetorDoFluxo(
|
||||
@@ -860,7 +860,7 @@ export const getInstanceWithSteps = query({
|
||||
usuario._id,
|
||||
instance._id
|
||||
);
|
||||
|
||||
|
||||
if (!pertenceAoSetor && instance.managerId !== usuario._id) {
|
||||
return null; // Usuário não tem acesso
|
||||
}
|
||||
@@ -1066,7 +1066,8 @@ export const instantiateFlow = mutation({
|
||||
|
||||
for (let i = 0; i < templateSteps.length; i++) {
|
||||
const step = templateSteps[i];
|
||||
const dueDate = now + cumulativeDays * 24 * 60 * 60 * 1000 + step.expectedDuration * 24 * 60 * 60 * 1000;
|
||||
const dueDate =
|
||||
now + cumulativeDays * 24 * 60 * 60 * 1000 + step.expectedDuration * 24 * 60 * 60 * 1000;
|
||||
cumulativeDays += step.expectedDuration;
|
||||
|
||||
const instanceStepId = await ctx.db.insert('flowInstanceSteps', {
|
||||
@@ -1202,7 +1203,12 @@ export const completeStep = mutation({
|
||||
if (nextSetor && nextFlowStep) {
|
||||
const tituloProximoSetor = 'Nova Etapa de Fluxo Disponível';
|
||||
const descricaoProximoSetor = `A etapa "${nextFlowStep.name}" do fluxo "${template?.name ?? 'Fluxo'}" está pronta para ser iniciada.`;
|
||||
await criarNotificacaoParaSetor(ctx, nextStepData.setorId, tituloProximoSetor, descricaoProximoSetor);
|
||||
await criarNotificacaoParaSetor(
|
||||
ctx,
|
||||
nextStepData.setorId,
|
||||
tituloProximoSetor,
|
||||
descricaoProximoSetor
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1303,7 +1309,9 @@ export const alterarGestorFluxo = mutation({
|
||||
const eCriador = template?.createdBy === usuario._id;
|
||||
|
||||
if (!eGestor && !temPermissao && !eCriador) {
|
||||
throw new Error('Somente o gestor atual, criador do template ou usuário com permissão pode alterar o gestor');
|
||||
throw new Error(
|
||||
'Somente o gestor atual, criador do template ou usuário com permissão pode alterar o gestor'
|
||||
);
|
||||
}
|
||||
|
||||
// Verificar se novo gestor existe
|
||||
@@ -1371,7 +1379,7 @@ export const reassignStep = mutation({
|
||||
if (!eCriador) {
|
||||
// Se não for criador, verificar regra normal
|
||||
const etapaAnterior = await obterEtapaAnterior(ctx, args.instanceStepId);
|
||||
|
||||
|
||||
if (etapaAnterior) {
|
||||
// Se há etapa anterior, verificar se o usuário atual é a pessoa atribuída
|
||||
if (etapaAnterior.assignedToId) {
|
||||
@@ -1386,7 +1394,9 @@ export const reassignStep = mutation({
|
||||
if (instance.managerId !== usuario._id) {
|
||||
const temPermissao = await verificarPermissaoVerTodasFluxos(ctx);
|
||||
if (!temPermissao) {
|
||||
throw new Error('Somente o gerente do fluxo ou pessoa da etapa anterior pode atribuir esta etapa');
|
||||
throw new Error(
|
||||
'Somente o gerente do fluxo ou pessoa da etapa anterior pode atribuir esta etapa'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1408,9 +1418,7 @@ export const reassignStep = mutation({
|
||||
}
|
||||
|
||||
// Verificar se o usuário atribuído corresponde a um funcionário do setor
|
||||
const funcionarioDoUsuario = funcionariosDoSetor.find(
|
||||
(f) => f.email === assignee.email
|
||||
);
|
||||
const funcionarioDoUsuario = funcionariosDoSetor.find((f) => f.email === assignee.email);
|
||||
|
||||
if (!funcionarioDoUsuario) {
|
||||
throw new Error('O funcionário atribuído não pertence ao setor deste passo');
|
||||
@@ -1441,7 +1449,7 @@ export const updateStepNotes = mutation({
|
||||
throw new Error('Passo não encontrado');
|
||||
}
|
||||
|
||||
await ctx.db.patch(args.instanceStepId, {
|
||||
await ctx.db.patch(args.instanceStepId, {
|
||||
notes: args.notes,
|
||||
notesUpdatedBy: usuario._id,
|
||||
notesUpdatedAt: Date.now()
|
||||
@@ -1526,7 +1534,9 @@ export const listarSubEtapas = query({
|
||||
} else if (args.flowInstanceStepId) {
|
||||
subEtapas = await ctx.db
|
||||
.query('flowSubSteps')
|
||||
.withIndex('by_flowInstanceStepId', (q) => q.eq('flowInstanceStepId', args.flowInstanceStepId))
|
||||
.withIndex('by_flowInstanceStepId', (q) =>
|
||||
q.eq('flowInstanceStepId', args.flowInstanceStepId)
|
||||
)
|
||||
.collect();
|
||||
} else {
|
||||
return [];
|
||||
@@ -1607,7 +1617,9 @@ export const criarSubEtapa = mutation({
|
||||
} else if (args.flowInstanceStepId) {
|
||||
const existingSubEtapas = await ctx.db
|
||||
.query('flowSubSteps')
|
||||
.withIndex('by_flowInstanceStepId', (q) => q.eq('flowInstanceStepId', args.flowInstanceStepId))
|
||||
.withIndex('by_flowInstanceStepId', (q) =>
|
||||
q.eq('flowInstanceStepId', args.flowInstanceStepId)
|
||||
)
|
||||
.collect();
|
||||
if (existingSubEtapas.length > 0) {
|
||||
maxPosition = Math.max(...existingSubEtapas.map((s) => s.position));
|
||||
@@ -1766,7 +1778,9 @@ export const listarNotas = query({
|
||||
} else if (args.flowInstanceStepId) {
|
||||
notas = await ctx.db
|
||||
.query('flowStepNotes')
|
||||
.withIndex('by_flowInstanceStepId', (q) => q.eq('flowInstanceStepId', args.flowInstanceStepId))
|
||||
.withIndex('by_flowInstanceStepId', (q) =>
|
||||
q.eq('flowInstanceStepId', args.flowInstanceStepId)
|
||||
)
|
||||
.collect();
|
||||
} else if (args.flowSubStepId) {
|
||||
notas = await ctx.db
|
||||
@@ -1784,17 +1798,15 @@ export const listarNotas = query({
|
||||
const notasComDetalhes = await Promise.all(
|
||||
notas.map(async (nota) => {
|
||||
const criador = await ctx.db.get(nota.criadoPor);
|
||||
|
||||
|
||||
// Obter informações dos arquivos
|
||||
const arquivosComNome = await Promise.all(
|
||||
nota.arquivos.map(async (storageId) => {
|
||||
// Buscar documento que referencia este storageId
|
||||
// Como não temos uma tabela direta, vamos buscar nos flowInstanceDocuments
|
||||
const documentos = await ctx.db
|
||||
.query('flowInstanceDocuments')
|
||||
.collect();
|
||||
const documentos = await ctx.db.query('flowInstanceDocuments').collect();
|
||||
const documento = documentos.find((d) => d.storageId === storageId);
|
||||
|
||||
|
||||
return {
|
||||
storageId,
|
||||
name: documento?.name ?? 'Arquivo'
|
||||
@@ -2003,7 +2015,9 @@ export const listDocumentsByStep = query({
|
||||
handler: async (ctx, args) => {
|
||||
const documents = await ctx.db
|
||||
.query('flowInstanceDocuments')
|
||||
.withIndex('by_flowInstanceStepId', (q) => q.eq('flowInstanceStepId', args.flowInstanceStepId))
|
||||
.withIndex('by_flowInstanceStepId', (q) =>
|
||||
q.eq('flowInstanceStepId', args.flowInstanceStepId)
|
||||
)
|
||||
.collect();
|
||||
|
||||
const result: Array<{
|
||||
@@ -2158,4 +2172,3 @@ export const getUsuariosBySetorForAssignment = query({
|
||||
return usuarios;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user