Adiciona endpoint de arquivamento e ajustes de infra

- Adiciona rota API para arquivar tickets por ID
- Atualiza configuracao do Prisma para PostgreSQL
- Simplifica workflow CI/CD
- Adiciona src/generated ao gitignore
- Atualiza documentacao e dependencias

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
rever-tecnologia 2025-12-11 13:25:36 -03:00
parent 33a59634e7
commit 2682b6e8ac
13 changed files with 253 additions and 165 deletions

View file

@ -0,0 +1,46 @@
import { NextResponse } from "next/server"
import { requireAuthenticatedSession } from "@/lib/auth-server"
import { isStaff } from "@/lib/authz"
import { env } from "@/lib/env"
import { findArchivedTicket } from "@/server/archive/local-tickets"
function getInternalSecret() {
return env.INTERNAL_HEALTH_TOKEN ?? env.REPORTS_CRON_SECRET ?? null
}
export async function GET(_: Request, context: { params: { ticketId: string } }) {
const cronSecret = getInternalSecret()
const headerSecret = _.headers.get("x-cron-secret")?.trim()
const querySecret = new URL(_.url).searchParams.get("token")?.trim()
const hasSecret = cronSecret && (headerSecret === cronSecret || querySecret === cronSecret)
if (!hasSecret) {
const session = await requireAuthenticatedSession()
const role = session.user.role ?? "agent"
if (!isStaff(role)) {
return NextResponse.json({ error: "Acesso negado" }, { status: 403 })
}
}
const ticketId = context.params.ticketId
const found = await findArchivedTicket(ticketId)
if (!found) {
return NextResponse.json({ error: "Ticket arquivado não encontrado" }, { status: 404 })
}
return NextResponse.json(
{
ok: true,
ticketId,
file: found.file,
archivedAt: found.record.archivedAt,
tenantId: found.record.tenantId,
ticket: found.record.ticket,
comments: found.record.comments,
events: found.record.events,
attachments: (found.record as { attachments?: unknown }).attachments ?? [],
},
{ status: 200 }
)
}

View file

@ -1,3 +1,5 @@
import { Pool } from "pg"
import { PrismaPg } from "@prisma/adapter-pg"
import { PrismaClient } from "@/generated/prisma/client"
type PrismaClientInstance = InstanceType<typeof PrismaClient>
@ -12,6 +14,7 @@ export type PrismaDelegateClient = PrismaClientInstance
declare global {
var prisma: PrismaClientInstance | undefined
var pgPool: Pool | undefined
}
// PostgreSQL connection - requires DATABASE_URL environment variable
@ -21,11 +24,21 @@ if (!databaseUrl) {
throw new Error("DATABASE_URL environment variable is required for PostgreSQL connection")
}
export const prisma = global.prisma ?? new PrismaClient()
// Create PostgreSQL connection pool (reused in development to prevent connection exhaustion)
const pool = global.pgPool ?? new Pool({
connectionString: databaseUrl,
})
// Create Prisma adapter with the pg pool
const adapter = new PrismaPg(pool)
// Create Prisma client with the adapter
export const prisma = global.prisma ?? new PrismaClient({ adapter })
if (process.env.NODE_ENV !== "production") {
global.prisma = prisma
console.log("[prisma] Using PostgreSQL database")
global.pgPool = pool
console.log("[prisma] Using PostgreSQL database with pg adapter")
}
export * from "@/generated/prisma/client"