import { defineTable } from 'convex/server'; import { type Infer, v } from 'convex/values'; export const movimentacaoTipo = v.union( v.literal('entrada'), v.literal('saida'), v.literal('ajuste'), v.literal('transferencia') ); export type MovimentacaoTipo = Infer; export const requisicaoStatus = v.union( v.literal('pendente'), v.literal('aprovada'), v.literal('rejeitada'), v.literal('atendida'), v.literal('cancelada') ); export type RequisicaoStatus = Infer; export const alertaTipo = v.union( v.literal('estoque_minimo'), v.literal('estoque_zerado'), v.literal('reposicao_necessaria') ); export type AlertaTipo = Infer; export const alertaStatus = v.union( v.literal('ativo'), v.literal('resolvido'), v.literal('ignorado') ); export type AlertaStatus = Infer; export const almoxarifadoTables = { materiais: defineTable({ codigo: v.string(), nome: v.string(), descricao: v.optional(v.string()), categoria: v.string(), unidadeMedida: v.string(), estoqueMinimo: v.number(), estoqueMaximo: v.optional(v.number()), estoqueAtual: v.number(), localizacao: v.optional(v.string()), fornecedor: v.optional(v.string()), ativo: v.boolean(), criadoPor: v.id('usuarios'), criadoEm: v.number(), atualizadoEm: v.number() }) .index('by_codigo', ['codigo']) .index('by_categoria', ['categoria']) .index('by_ativo', ['ativo']) .index('by_estoqueAtual', ['estoqueAtual']), movimentacoesEstoque: defineTable({ materialId: v.id('materiais'), tipo: movimentacaoTipo, quantidade: v.number(), quantidadeAnterior: v.number(), quantidadeNova: v.number(), motivo: v.string(), documento: v.optional(v.string()), funcionarioId: v.optional(v.id('funcionarios')), setorId: v.optional(v.id('setores')), usuarioId: v.id('usuarios'), data: v.number(), observacoes: v.optional(v.string()) }) .index('by_materialId', ['materialId']) .index('by_tipo', ['tipo']) .index('by_data', ['data']) .index('by_funcionarioId', ['funcionarioId']) .index('by_usuarioId', ['usuarioId']), requisicoesMaterial: defineTable({ numero: v.string(), solicitanteId: v.id('funcionarios'), setorId: v.id('setores'), status: requisicaoStatus, aprovadoPor: v.optional(v.id('funcionarios')), dataAprovacao: v.optional(v.number()), observacoes: v.optional(v.string()), criadoEm: v.number(), atualizadoEm: v.number() }) .index('by_status', ['status']) .index('by_solicitanteId', ['solicitanteId']) .index('by_setorId', ['setorId']) .index('by_numero', ['numero']), requisicaoItens: defineTable({ requisicaoId: v.id('requisicoesMaterial'), materialId: v.id('materiais'), quantidadeSolicitada: v.number(), quantidadeAtendida: v.optional(v.number()), observacoes: v.optional(v.string()) }) .index('by_requisicaoId', ['requisicaoId']) .index('by_materialId', ['materialId']), historicoAlteracoes: defineTable({ tipoEntidade: v.string(), entidadeId: v.string(), acao: v.string(), usuarioId: v.id('usuarios'), dadosAnteriores: v.optional(v.string()), dadosNovos: v.optional(v.string()), timestamp: v.number(), ipAddress: v.optional(v.string()), observacoes: v.optional(v.string()) }) .index('by_tipoEntidade', ['tipoEntidade']) .index('by_entidadeId', ['entidadeId']) .index('by_usuarioId', ['usuarioId']) .index('by_timestamp', ['timestamp']), alertasEstoque: defineTable({ materialId: v.id('materiais'), tipo: alertaTipo, quantidadeAtual: v.number(), quantidadeMinima: v.number(), status: alertaStatus, criadoEm: v.number(), resolvidoEm: v.optional(v.number()), resolvidoPor: v.optional(v.id('usuarios')) }) .index('by_materialId', ['materialId']) .index('by_status', ['status']) .index('by_tipo', ['tipo']), configuracoesAlmoxarifado: defineTable({ estoqueMinimoPadrao: v.number(), diasAntecedenciaAlerta: v.number(), permitirEstoqueNegativo: v.boolean(), requerAprovacaoRequisicao: v.boolean(), rolesAprovacao: v.array(v.string()), emailAlertasAtivo: v.boolean(), emailsDestinatarios: v.array(v.string()), periodicidadeInventario: v.number(), ultimoInventario: v.optional(v.number()), ativo: v.boolean(), atualizadoPor: v.id('usuarios'), atualizadoEm: v.number() }) };