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:
parent
33a59634e7
commit
2682b6e8ac
13 changed files with 253 additions and 165 deletions
46
src/app/api/admin/tickets/archived/[ticketId]/route.ts
Normal file
46
src/app/api/admin/tickets/archived/[ticketId]/route.ts
Normal 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 }
|
||||
)
|
||||
}
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue