import { mutation, query } from "./_generated/server"; import { v } from "convex/values"; // Criar uma nova solicitação de acesso export const create = mutation({ args: { nome: v.string(), matricula: v.string(), email: v.string(), telefone: v.string(), }, returns: v.object({ solicitacaoId: v.id("solicitacoesAcesso"), }), handler: async (ctx, args) => { // Verificar se já existe uma solicitação pendente com a mesma matrícula const existingByMatricula = await ctx.db .query("solicitacoesAcesso") .withIndex("by_matricula", (q) => q.eq("matricula", args.matricula)) .filter((q) => q.eq(q.field("status"), "pendente")) .first(); if (existingByMatricula) { throw new Error("Já existe uma solicitação pendente para esta matrícula."); } // Verificar se já existe uma solicitação pendente com o mesmo email const existingByEmail = await ctx.db .query("solicitacoesAcesso") .withIndex("by_email", (q) => q.eq("email", args.email)) .filter((q) => q.eq(q.field("status"), "pendente")) .first(); if (existingByEmail) { throw new Error("Já existe uma solicitação pendente para este e-mail."); } const solicitacaoId = await ctx.db.insert("solicitacoesAcesso", { nome: args.nome, matricula: args.matricula, email: args.email, telefone: args.telefone, status: "pendente", dataSolicitacao: Date.now(), }); return { solicitacaoId }; }, }); // Listar todas as solicitações (para o painel administrativo) export const getAll = query({ args: {}, returns: v.array( v.object({ _id: v.id("solicitacoesAcesso"), _creationTime: v.number(), nome: v.string(), matricula: v.string(), email: v.string(), telefone: v.string(), status: v.union( v.literal("pendente"), v.literal("aprovado"), v.literal("rejeitado") ), dataSolicitacao: v.number(), dataResposta: v.union(v.number(), v.null()), observacoes: v.union(v.string(), v.null()), }) ), handler: async (ctx) => { const solicitacoes = await ctx.db .query("solicitacoesAcesso") .order("desc") .collect(); return solicitacoes.map((s) => ({ _id: s._id, _creationTime: s._creationTime, nome: s.nome, matricula: s.matricula, email: s.email, telefone: s.telefone, status: s.status, dataSolicitacao: s.dataSolicitacao, dataResposta: s.dataResposta ?? null, observacoes: s.observacoes ?? null, })); }, }); // Listar apenas solicitações pendentes export const getPendentes = query({ args: {}, returns: v.array( v.object({ _id: v.id("solicitacoesAcesso"), _creationTime: v.number(), nome: v.string(), matricula: v.string(), email: v.string(), telefone: v.string(), status: v.union( v.literal("pendente"), v.literal("aprovado"), v.literal("rejeitado") ), dataSolicitacao: v.number(), dataResposta: v.union(v.number(), v.null()), observacoes: v.union(v.string(), v.null()), }) ), handler: async (ctx) => { const solicitacoes = await ctx.db .query("solicitacoesAcesso") .withIndex("by_status", (q) => q.eq("status", "pendente")) .order("desc") .collect(); return solicitacoes.map((s) => ({ _id: s._id, _creationTime: s._creationTime, nome: s.nome, matricula: s.matricula, email: s.email, telefone: s.telefone, status: s.status, dataSolicitacao: s.dataSolicitacao, dataResposta: s.dataResposta ?? null, observacoes: s.observacoes ?? null, })); }, }); // Aprovar uma solicitação export const aprovar = mutation({ args: { solicitacaoId: v.id("solicitacoesAcesso"), observacoes: v.optional(v.string()), }, returns: v.null(), handler: async (ctx, args) => { const solicitacao = await ctx.db.get(args.solicitacaoId); if (!solicitacao) { throw new Error("Solicitação não encontrada."); } if (solicitacao.status !== "pendente") { throw new Error("Esta solicitação já foi processada."); } await ctx.db.patch(args.solicitacaoId, { status: "aprovado", dataResposta: Date.now(), observacoes: args.observacoes, }); return null; }, }); // Rejeitar uma solicitação export const rejeitar = mutation({ args: { solicitacaoId: v.id("solicitacoesAcesso"), observacoes: v.optional(v.string()), }, returns: v.null(), handler: async (ctx, args) => { const solicitacao = await ctx.db.get(args.solicitacaoId); if (!solicitacao) { throw new Error("Solicitação não encontrada."); } if (solicitacao.status !== "pendente") { throw new Error("Esta solicitação já foi processada."); } await ctx.db.patch(args.solicitacaoId, { status: "rejeitado", dataResposta: Date.now(), observacoes: args.observacoes, }); return null; }, }); // Obter uma solicitação por ID export const getById = query({ args: { solicitacaoId: v.id("solicitacoesAcesso"), }, returns: v.union( v.object({ _id: v.id("solicitacoesAcesso"), _creationTime: v.number(), nome: v.string(), matricula: v.string(), email: v.string(), telefone: v.string(), status: v.union( v.literal("pendente"), v.literal("aprovado"), v.literal("rejeitado") ), dataSolicitacao: v.number(), dataResposta: v.union(v.number(), v.null()), observacoes: v.union(v.string(), v.null()), }), v.null() ), handler: async (ctx, args) => { const solicitacao = await ctx.db.get(args.solicitacaoId); if (!solicitacao) { return null; } return { _id: solicitacao._id, _creationTime: solicitacao._creationTime, nome: solicitacao.nome, matricula: solicitacao.matricula, email: solicitacao.email, telefone: solicitacao.telefone, status: solicitacao.status, dataSolicitacao: solicitacao.dataSolicitacao, dataResposta: solicitacao.dataResposta ?? null, observacoes: solicitacao.observacoes ?? null, }; }, });