157 lines
6.2 KiB
TypeScript
157 lines
6.2 KiB
TypeScript
import type { Id } from "./_generated/dataModel"
|
|
import { mutation } from "./_generated/server"
|
|
|
|
export const seedDemo = mutation({
|
|
args: {},
|
|
handler: async (ctx) => {
|
|
const tenantId = "tenant-atlas";
|
|
const desiredQueues = [
|
|
{ name: "Chamados", slug: "chamados" },
|
|
{ name: "Laboratório", slug: "laboratorio" },
|
|
{ name: "Visitas", slug: "visitas" },
|
|
];
|
|
|
|
// Ensure queues
|
|
const existingQueues = await ctx.db
|
|
.query("queues")
|
|
.withIndex("by_tenant", (q) => q.eq("tenantId", tenantId))
|
|
.collect();
|
|
|
|
const normalizedQueues = await Promise.all(
|
|
existingQueues.map(async (queue) => {
|
|
if (!queue) return queue;
|
|
if (queue.name === "Suporte N1" || queue.slug === "suporte-n1") {
|
|
await ctx.db.patch(queue._id, { name: "Chamados", slug: "chamados" });
|
|
return (await ctx.db.get(queue._id)) ?? queue;
|
|
}
|
|
if (queue.name === "Suporte N2" || queue.slug === "suporte-n2") {
|
|
await ctx.db.patch(queue._id, { name: "Laboratório", slug: "laboratorio" });
|
|
return (await ctx.db.get(queue._id)) ?? queue;
|
|
}
|
|
return queue;
|
|
})
|
|
);
|
|
|
|
const presentQueues = normalizedQueues.filter(
|
|
(queue): queue is NonNullable<(typeof normalizedQueues)[number]> => Boolean(queue)
|
|
);
|
|
const queuesBySlug = new Map(presentQueues.map((queue) => [queue.slug, queue]));
|
|
const queuesByName = new Map(presentQueues.map((queue) => [queue.name, queue]));
|
|
const queues = [] as typeof presentQueues;
|
|
|
|
for (const def of desiredQueues) {
|
|
let queue = queuesBySlug.get(def.slug) ?? queuesByName.get(def.name);
|
|
if (!queue) {
|
|
const newId = await ctx.db.insert("queues", { tenantId, name: def.name, slug: def.slug, teamId: undefined });
|
|
queue = (await ctx.db.get(newId))!;
|
|
queuesBySlug.set(queue.slug, queue);
|
|
queuesByName.set(queue.name, queue);
|
|
}
|
|
queues.push(queue);
|
|
}
|
|
|
|
const queueChamados = queuesBySlug.get("chamados");
|
|
const queueLaboratorio = queuesBySlug.get("laboratorio");
|
|
const queueVisitas = queuesBySlug.get("visitas");
|
|
if (!queueChamados || !queueLaboratorio || !queueVisitas) {
|
|
throw new Error("Filas padrão não foram inicializadas");
|
|
}
|
|
|
|
// Ensure users
|
|
function defaultAvatar(name: string, email: string, role: string) {
|
|
const normalizedRole = role.toUpperCase();
|
|
if (normalizedRole === "MANAGER") {
|
|
return `https://i.pravatar.cc/150?u=${encodeURIComponent(email)}`;
|
|
}
|
|
const first = name.split(" ")[0] ?? email;
|
|
return `https://avatar.vercel.sh/${encodeURIComponent(first)}`;
|
|
}
|
|
async function ensureUser(params: {
|
|
name: string;
|
|
email: string;
|
|
role?: string;
|
|
companyId?: Id<"companies">;
|
|
avatarUrl?: string;
|
|
}): Promise<Id<"users">> {
|
|
const normalizedEmail = params.email.trim().toLowerCase();
|
|
const normalizedRole = (params.role ?? "MANAGER").toUpperCase();
|
|
const desiredAvatar = params.avatarUrl ?? defaultAvatar(params.name, normalizedEmail, normalizedRole);
|
|
const existing = await ctx.db
|
|
.query("users")
|
|
.withIndex("by_tenant_email", (q) => q.eq("tenantId", tenantId).eq("email", normalizedEmail))
|
|
.first();
|
|
if (existing) {
|
|
const updates: Record<string, unknown> = {};
|
|
if (existing.name !== params.name) updates.name = params.name;
|
|
if ((existing.role ?? "MANAGER") !== normalizedRole) updates.role = normalizedRole;
|
|
if ((existing.avatarUrl ?? undefined) !== desiredAvatar) updates.avatarUrl = desiredAvatar;
|
|
if ((existing.companyId ?? undefined) !== (params.companyId ?? undefined)) updates.companyId = params.companyId ?? undefined;
|
|
if (Object.keys(updates).length > 0) {
|
|
await ctx.db.patch(existing._id, updates);
|
|
}
|
|
return existing._id;
|
|
}
|
|
return await ctx.db.insert("users", {
|
|
tenantId,
|
|
name: params.name,
|
|
email: normalizedEmail,
|
|
role: normalizedRole,
|
|
avatarUrl: desiredAvatar,
|
|
companyId: params.companyId ?? undefined,
|
|
});
|
|
}
|
|
|
|
const adminId = await ensureUser({ name: "Administrador", email: "admin@sistema.dev", role: "ADMIN" });
|
|
const staffRoster = [
|
|
{ name: "Gabriel Oliveira", email: "gabriel.oliveira@rever.com.br" },
|
|
{ name: "George Araujo", email: "george.araujo@rever.com.br" },
|
|
{ name: "Hugo Soares", email: "hugo.soares@rever.com.br" },
|
|
{ name: "Julio Cesar", email: "julio@rever.com.br" },
|
|
{ name: "Lorena Magalhães", email: "lorena@rever.com.br" },
|
|
{ name: "Rever", email: "renan.pac@paulicon.com.br" },
|
|
{ name: "Thiago Medeiros", email: "thiago.medeiros@rever.com.br" },
|
|
{ name: "Weslei Magalhães", email: "weslei@rever.com.br" },
|
|
];
|
|
|
|
await Promise.all(
|
|
staffRoster.map((staff) => ensureUser({ name: staff.name, email: staff.email, role: "AGENT" })),
|
|
);
|
|
|
|
const templateDefinitions = [
|
|
{
|
|
title: "A Rever agradece seu contato",
|
|
body: "<p>A Rever agradece seu contato. Recebemos sua solicitação e nossa equipe já está analisando os detalhes. Retornaremos com atualizações em breve.</p>",
|
|
},
|
|
{
|
|
title: "Atualização do chamado",
|
|
body: "<p>Seu chamado foi atualizado. Caso tenha novas informações ou dúvidas, basta responder a esta mensagem.</p>",
|
|
},
|
|
{
|
|
title: "Chamado resolvido",
|
|
body: "<p>Concluímos o atendimento deste chamado. A Rever agradece a parceria e permanecemos à disposição para novos suportes.</p>",
|
|
},
|
|
];
|
|
|
|
const existingTemplates = await ctx.db
|
|
.query("commentTemplates")
|
|
.withIndex("by_tenant", (q) => q.eq("tenantId", tenantId))
|
|
.collect();
|
|
|
|
for (const definition of templateDefinitions) {
|
|
const already = existingTemplates.find((template) => template?.title === definition.title);
|
|
if (already) continue;
|
|
const timestamp = Date.now();
|
|
await ctx.db.insert("commentTemplates", {
|
|
tenantId,
|
|
title: definition.title,
|
|
body: definition.body,
|
|
createdBy: adminId,
|
|
updatedBy: adminId,
|
|
createdAt: timestamp,
|
|
updatedAt: timestamp,
|
|
});
|
|
}
|
|
|
|
// No demo tickets are seeded; rely on real data from the database.
|
|
},
|
|
});
|