166 lines
4.3 KiB
TypeScript
166 lines
4.3 KiB
TypeScript
import { defineTable } from 'convex/server';
|
|
import { v } from 'convex/values';
|
|
|
|
export const ticketsTables = {
|
|
tickets: defineTable({
|
|
numero: v.string(),
|
|
titulo: v.string(),
|
|
descricao: v.string(),
|
|
tipo: v.union(
|
|
v.literal('reclamacao'),
|
|
v.literal('elogio'),
|
|
v.literal('sugestao'),
|
|
v.literal('chamado')
|
|
),
|
|
categoria: v.optional(v.string()),
|
|
status: v.union(
|
|
v.literal('aberto'),
|
|
v.literal('em_andamento'),
|
|
v.literal('aguardando_usuario'),
|
|
v.literal('resolvido'),
|
|
v.literal('encerrado'),
|
|
v.literal('cancelado')
|
|
),
|
|
prioridade: v.union(
|
|
v.literal('baixa'),
|
|
v.literal('media'),
|
|
v.literal('alta'),
|
|
v.literal('critica')
|
|
),
|
|
solicitanteId: v.id('usuarios'),
|
|
solicitanteNome: v.string(),
|
|
solicitanteEmail: v.string(),
|
|
responsavelId: v.optional(v.id('usuarios')),
|
|
setorResponsavel: v.optional(v.string()),
|
|
slaConfigId: v.optional(v.id('slaConfigs')),
|
|
conversaId: v.optional(v.id('conversas')),
|
|
prazoResposta: v.optional(v.number()),
|
|
prazoConclusao: v.optional(v.number()),
|
|
prazoEncerramento: v.optional(v.number()),
|
|
timeline: v.optional(
|
|
v.array(
|
|
v.object({
|
|
etapa: v.string(),
|
|
status: v.union(
|
|
v.literal('pendente'),
|
|
v.literal('em_andamento'),
|
|
v.literal('concluido'),
|
|
v.literal('vencido')
|
|
),
|
|
prazo: v.optional(v.number()),
|
|
concluidoEm: v.optional(v.number()),
|
|
observacao: v.optional(v.string())
|
|
})
|
|
)
|
|
),
|
|
alertasEmitidos: v.optional(
|
|
v.array(
|
|
v.object({
|
|
tipo: v.union(v.literal('resposta'), v.literal('conclusao'), v.literal('encerramento')),
|
|
emitidoEm: v.number()
|
|
})
|
|
)
|
|
),
|
|
anexos: v.optional(
|
|
v.array(
|
|
v.object({
|
|
arquivoId: v.id('_storage'),
|
|
nome: v.optional(v.string()),
|
|
tipo: v.optional(v.string()),
|
|
tamanho: v.optional(v.number())
|
|
})
|
|
)
|
|
),
|
|
tags: v.optional(v.array(v.string())),
|
|
canalOrigem: v.optional(v.string()),
|
|
ultimaInteracaoEm: v.number(),
|
|
criadoEm: v.number(),
|
|
atualizadoEm: v.number()
|
|
})
|
|
.index('by_numero', ['numero'])
|
|
.index('by_status', ['status'])
|
|
.index('by_solicitante', ['solicitanteId', 'status'])
|
|
.index('by_responsavel', ['responsavelId', 'status'])
|
|
.index('by_setor', ['setorResponsavel', 'status']),
|
|
|
|
ticketInteractions: defineTable({
|
|
ticketId: v.id('tickets'),
|
|
autorId: v.optional(v.id('usuarios')),
|
|
origem: v.union(v.literal('usuario'), v.literal('ti'), v.literal('sistema')),
|
|
tipo: v.union(
|
|
v.literal('mensagem'),
|
|
v.literal('status'),
|
|
v.literal('anexo'),
|
|
v.literal('alerta')
|
|
),
|
|
conteudo: v.string(),
|
|
anexos: v.optional(
|
|
v.array(
|
|
v.object({
|
|
arquivoId: v.id('_storage'),
|
|
nome: v.optional(v.string()),
|
|
tipo: v.optional(v.string()),
|
|
tamanho: v.optional(v.number())
|
|
})
|
|
)
|
|
),
|
|
statusAnterior: v.optional(
|
|
v.union(
|
|
v.literal('aberto'),
|
|
v.literal('em_andamento'),
|
|
v.literal('aguardando_usuario'),
|
|
v.literal('resolvido'),
|
|
v.literal('encerrado'),
|
|
v.literal('cancelado')
|
|
)
|
|
),
|
|
statusNovo: v.optional(
|
|
v.union(
|
|
v.literal('aberto'),
|
|
v.literal('em_andamento'),
|
|
v.literal('aguardando_usuario'),
|
|
v.literal('resolvido'),
|
|
v.literal('encerrado'),
|
|
v.literal('cancelado')
|
|
)
|
|
),
|
|
visibilidade: v.union(v.literal('publico'), v.literal('interno')),
|
|
criadoEm: v.number()
|
|
})
|
|
.index('by_ticket', ['ticketId'])
|
|
.index('by_ticket_type', ['ticketId', 'tipo'])
|
|
.index('by_autor', ['autorId']),
|
|
|
|
slaConfigs: defineTable({
|
|
nome: v.string(),
|
|
descricao: v.optional(v.string()),
|
|
prioridade: v.optional(
|
|
v.union(v.literal('baixa'), v.literal('media'), v.literal('alta'), v.literal('critica'))
|
|
),
|
|
tempoRespostaHoras: v.number(),
|
|
tempoConclusaoHoras: v.number(),
|
|
tempoEncerramentoHoras: v.optional(v.number()),
|
|
alertaAntecedenciaHoras: v.number(),
|
|
ativo: v.boolean(),
|
|
criadoPor: v.id('usuarios'),
|
|
atualizadoPor: v.optional(v.id('usuarios')),
|
|
criadoEm: v.number(),
|
|
atualizadoEm: v.number()
|
|
})
|
|
.index('by_ativo', ['ativo'])
|
|
.index('by_prioridade', ['prioridade', 'ativo'])
|
|
.index('by_nome', ['nome']),
|
|
|
|
ticketAssignments: defineTable({
|
|
ticketId: v.id('tickets'),
|
|
responsavelId: v.id('usuarios'),
|
|
atribuidoPor: v.id('usuarios'),
|
|
motivo: v.optional(v.string()),
|
|
ativo: v.boolean(),
|
|
criadoEm: v.number(),
|
|
encerradoEm: v.optional(v.number())
|
|
})
|
|
.index('by_ticket', ['ticketId', 'ativo'])
|
|
.index('by_responsavel', ['responsavelId', 'ativo'])
|
|
};
|