feat: Refactor order flow initiation logic and enhance UI button styles for better user experience

This commit is contained in:
2026-01-08 09:08:25 -03:00
parent e97bcfbd6a
commit 5a6d9069c9
5 changed files with 95 additions and 59 deletions

View File

@@ -37,6 +37,7 @@ import type * as contratos from "../contratos.js";
import type * as crons from "../crons.js";
import type * as cursos from "../cursos.js";
import type * as dashboard from "../dashboard.js";
import type * as debug from "../debug.js";
import type * as documentos from "../documentos.js";
import type * as email from "../email.js";
import type * as empresas from "../empresas.js";
@@ -138,6 +139,7 @@ declare const fullApi: ApiFromModules<{
crons: typeof crons;
cursos: typeof cursos;
dashboard: typeof dashboard;
debug: typeof debug;
documentos: typeof documentos;
email: typeof email;
empresas: typeof empresas;

View File

@@ -0,0 +1,23 @@
import { query } from './_generated/server';
import { v } from 'convex/values';
export const inspectOrder = query({
args: { pedidoId: v.id('pedidos') },
handler: async (ctx, args) => {
const pedido = await ctx.db.get(args.pedidoId);
const historicoEtapas = await ctx.db
.query('pedidoEtapasHistorico')
.withIndex('by_pedidoId', (q) => q.eq('pedidoId', args.pedidoId))
.collect();
const etapas = await ctx.db.query('pedidoFluxoEtapa').collect();
const transicoes = await ctx.db.query('pedidoFluxoTransicao').collect();
return {
pedido,
historicoEtapas,
etapasConfiguradas: etapas,
transicoesConfiguradas: transicoes
};
}
});

View File

@@ -20,6 +20,59 @@ async function getUsuarioAutenticado(ctx: QueryCtx | MutationCtx) {
return usuario;
}
export async function iniciarFluxoPedidoInternal(
ctx: MutationCtx,
pedidoId: Id<'pedidos'>,
usuarioId: Id<'usuarios'>
) {
const pedido = await ctx.db.get(pedidoId);
if (!pedido) {
throw new Error('Pedido não encontrado');
}
// Verificar se já tem histórico
const historicoExistente = await ctx.db
.query('pedidoEtapasHistorico')
.withIndex('by_pedidoId', (q) => q.eq('pedidoId', pedidoId))
.first();
if (historicoExistente) {
return historicoExistente._id;
}
// Buscar primeira etapa do fluxo
const primeiraEtapa = await ctx.db.query('pedidoFluxoEtapa').withIndex('by_ordem').first();
if (!primeiraEtapa) {
console.warn('Nenhuma etapa configurada no fluxo. Timeline ficará vazia.');
return null;
}
const now = Date.now();
// Criar primeiro registro
const historicoId = await ctx.db.insert('pedidoEtapasHistorico', {
pedidoId,
etapaId: primeiraEtapa._id,
inicioData: now,
atual: true
});
// Registrar no histórico
await ctx.db.insert('historicoPedidos', {
pedidoId,
usuarioId,
acao: 'inicio_fluxo',
detalhes: JSON.stringify({
etapa: primeiraEtapa.codigo,
etapaNome: primeiraEtapa.nome
}),
data: now
});
return historicoId;
}
async function getEtapaAtualDoPedido(ctx: QueryCtx | MutationCtx, pedidoId: Id<'pedidos'>) {
const etapaAtual = await ctx.db
.query('pedidoEtapasHistorico')
@@ -720,55 +773,10 @@ export const iniciarFluxoPedido = mutation({
args: {
pedidoId: v.id('pedidos')
},
returns: v.id('pedidoEtapasHistorico'),
returns: v.union(v.id('pedidoEtapasHistorico'), v.null()),
handler: async (ctx, args) => {
const usuario = await getUsuarioAutenticado(ctx);
const pedido = await ctx.db.get(args.pedidoId);
if (!pedido) {
throw new Error('Pedido não encontrado');
}
// Verificar se já tem histórico
const historicoExistente = await ctx.db
.query('pedidoEtapasHistorico')
.withIndex('by_pedidoId', (q) => q.eq('pedidoId', args.pedidoId))
.first();
if (historicoExistente) {
throw new Error('Este pedido já possui histórico de etapas');
}
// Buscar primeira etapa do fluxo
const primeiraEtapa = await ctx.db.query('pedidoFluxoEtapa').withIndex('by_ordem').first();
if (!primeiraEtapa) {
throw new Error('Nenhuma etapa configurada no fluxo');
}
const now = Date.now();
// Criar primeiro registro
const historicoId = await ctx.db.insert('pedidoEtapasHistorico', {
pedidoId: args.pedidoId,
etapaId: primeiraEtapa._id,
inicioData: now,
atual: true
});
// Registrar no histórico
await ctx.db.insert('historicoPedidos', {
pedidoId: args.pedidoId,
usuarioId: usuario._id,
acao: 'inicio_fluxo',
detalhes: JSON.stringify({
etapa: primeiraEtapa.codigo,
etapaNome: primeiraEtapa.nome
}),
data: now
});
return historicoId;
return await iniciarFluxoPedidoInternal(ctx, args.pedidoId, usuario._id);
}
});

View File

@@ -4,6 +4,7 @@ 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';
import { iniciarFluxoPedidoInternal } from './pedidoFlow';
import { getTodayYMD, isWithinRangeYMD, maxYMD } from './utils/datas';
// ========== HELPERS ==========
@@ -1292,6 +1293,9 @@ export const create = mutation({
data: Date.now()
});
// 5. Iniciar Fluxo se houver etapas
await iniciarFluxoPedidoInternal(ctx, pedidoId, user._id);
return pedidoId;
}
});
@@ -2079,6 +2083,9 @@ export const enviarParaAceite = mutation({
data: Date.now()
});
// Garantir que o fluxo foi iniciado
await iniciarFluxoPedidoInternal(ctx, args.pedidoId, user._id);
await ctx.scheduler.runAfter(0, internal.pedidos.notifyStatusChange, {
pedidoId: args.pedidoId,
oldStatus,