chore: reorganize project structure and ensure default queues
This commit is contained in:
parent
854887f499
commit
1cccb852a5
201 changed files with 417 additions and 838 deletions
|
|
@ -1,155 +0,0 @@
|
|||
import { PrismaClient } from "@prisma/client"
|
||||
import { ConvexHttpClient } from "convex/browser"
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
function toMillis(date) {
|
||||
return date instanceof Date ? date.getTime() : date ? new Date(date).getTime() : undefined
|
||||
}
|
||||
|
||||
function normalizeString(value, fallback = "") {
|
||||
if (!value) return fallback
|
||||
return value.trim()
|
||||
}
|
||||
|
||||
function slugify(value) {
|
||||
return normalizeString(value)
|
||||
.toLowerCase()
|
||||
.replace(/[^a-z0-9\s-]/g, "")
|
||||
.replace(/\s+/g, "-")
|
||||
.replace(/-+/g, "-") || undefined
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const tenantId = process.env.SYNC_TENANT_ID || "tenant-atlas"
|
||||
const convexUrl = process.env.NEXT_PUBLIC_CONVEX_URL || "http://127.0.0.1:3210"
|
||||
const secret = process.env.CONVEX_SYNC_SECRET
|
||||
|
||||
if (!secret) {
|
||||
console.error("CONVEX_SYNC_SECRET não configurado. Configure no .env.")
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const [users, queues, tickets, companies] = await Promise.all([
|
||||
prisma.user.findMany({
|
||||
include: {
|
||||
teams: {
|
||||
include: { team: true },
|
||||
},
|
||||
company: true,
|
||||
},
|
||||
}),
|
||||
prisma.queue.findMany(),
|
||||
prisma.ticket.findMany({
|
||||
include: {
|
||||
requester: true,
|
||||
assignee: true,
|
||||
queue: true,
|
||||
company: true,
|
||||
comments: {
|
||||
include: {
|
||||
author: true,
|
||||
},
|
||||
},
|
||||
events: true,
|
||||
},
|
||||
orderBy: { createdAt: "asc" },
|
||||
}),
|
||||
prisma.company.findMany(),
|
||||
])
|
||||
|
||||
const userSnapshot = users.map((user) => ({
|
||||
email: user.email,
|
||||
name: normalizeString(user.name, user.email),
|
||||
role: user.role,
|
||||
avatarUrl: user.avatarUrl ?? undefined,
|
||||
teams: user.teams
|
||||
.map((membership) => membership.team?.name)
|
||||
.filter((name) => Boolean(name) && typeof name === "string"),
|
||||
companySlug: user.company?.slug ?? undefined,
|
||||
}))
|
||||
|
||||
const queueSnapshot = queues.map((queue) => ({
|
||||
name: normalizeString(queue.name, queue.slug ?? queue.id),
|
||||
slug: queue.slug ? queue.slug : normalizeString(queue.name, queue.id).toLowerCase().replace(/\s+/g, "-"),
|
||||
}))
|
||||
|
||||
const referenceFallbackStart = 41000
|
||||
let referenceCounter = referenceFallbackStart
|
||||
|
||||
const ticketSnapshot = tickets.map((ticket) => {
|
||||
const reference = ticket.reference && ticket.reference > 0 ? ticket.reference : ++referenceCounter
|
||||
const requesterEmail = ticket.requester?.email ?? userSnapshot[0]?.email ?? "unknown@example.com"
|
||||
const assigneeEmail = ticket.assignee?.email ?? undefined
|
||||
const queueSlug = ticket.queue?.slug ?? slugify(ticket.queue?.name)
|
||||
const companySlug = ticket.company?.slug ?? ticket.requester?.company?.slug ?? undefined
|
||||
|
||||
return {
|
||||
reference,
|
||||
subject: normalizeString(ticket.subject, `Ticket ${reference}`),
|
||||
summary: ticket.summary ?? undefined,
|
||||
status: ticket.status,
|
||||
priority: ticket.priority,
|
||||
channel: ticket.channel,
|
||||
queueSlug: queueSlug ?? undefined,
|
||||
requesterEmail,
|
||||
assigneeEmail,
|
||||
companySlug,
|
||||
dueAt: toMillis(ticket.dueAt) ?? undefined,
|
||||
firstResponseAt: toMillis(ticket.firstResponseAt) ?? undefined,
|
||||
resolvedAt: toMillis(ticket.resolvedAt) ?? undefined,
|
||||
closedAt: toMillis(ticket.closedAt) ?? undefined,
|
||||
createdAt: toMillis(ticket.createdAt) ?? Date.now(),
|
||||
updatedAt: toMillis(ticket.updatedAt) ?? Date.now(),
|
||||
tags: Array.isArray(ticket.tags) ? ticket.tags : undefined,
|
||||
comments: ticket.comments.map((comment) => ({
|
||||
authorEmail: comment.author?.email ?? requesterEmail,
|
||||
visibility: comment.visibility,
|
||||
body: comment.body,
|
||||
createdAt: toMillis(comment.createdAt) ?? Date.now(),
|
||||
updatedAt: toMillis(comment.updatedAt) ?? Date.now(),
|
||||
})),
|
||||
events: ticket.events.map((event) => ({
|
||||
type: event.type,
|
||||
payload: event.payload ?? {},
|
||||
createdAt: toMillis(event.createdAt) ?? Date.now(),
|
||||
})),
|
||||
}
|
||||
})
|
||||
|
||||
const companySnapshot = companies.map((company) => ({
|
||||
slug: company.slug ?? slugify(company.name),
|
||||
name: company.name,
|
||||
cnpj: company.cnpj ?? undefined,
|
||||
domain: company.domain ?? undefined,
|
||||
phone: company.phone ?? undefined,
|
||||
description: company.description ?? undefined,
|
||||
address: company.address ?? undefined,
|
||||
createdAt: toMillis(company.createdAt) ?? Date.now(),
|
||||
updatedAt: toMillis(company.updatedAt) ?? Date.now(),
|
||||
}))
|
||||
|
||||
const client = new ConvexHttpClient(convexUrl)
|
||||
|
||||
const result = await client.mutation("migrations:importPrismaSnapshot", {
|
||||
secret,
|
||||
snapshot: {
|
||||
tenantId,
|
||||
companies: companySnapshot,
|
||||
users: userSnapshot,
|
||||
queues: queueSnapshot,
|
||||
tickets: ticketSnapshot,
|
||||
},
|
||||
})
|
||||
|
||||
console.log("Sincronização concluída:", result)
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((error) => {
|
||||
console.error(error)
|
||||
process.exitCode = 1
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect()
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue