feat: improve ticket export and navigation

This commit is contained in:
Esdras Renan 2025-10-13 00:08:18 -03:00
parent 0731c5d1ea
commit 7d6f3bea01
28 changed files with 1612 additions and 609 deletions

View file

@ -1,4 +1,4 @@
import { NextResponse } from "next/server"
import { NextRequest, NextResponse } from "next/server"
import { cookies } from "next/headers"
import { ConvexHttpClient } from "convex/browser"
@ -25,33 +25,55 @@ function decodeMachineCookie(value: string) {
}
}
export async function GET() {
function encodeMachineCookie(payload: {
machineId: string
persona: string | null
assignedUserId: string | null
assignedUserEmail: string | null
assignedUserName: string | null
assignedUserRole: string | null
}) {
return Buffer.from(JSON.stringify(payload)).toString("base64url")
}
export async function GET(request: NextRequest) {
const session = await assertAuthenticatedSession()
if (!session || session.user?.role !== "machine") {
return NextResponse.json({ error: "Sessão de máquina não encontrada." }, { status: 403 })
}
const cookieStore = await cookies()
const cookieValue = cookieStore.get(MACHINE_CTX_COOKIE)?.value
if (!cookieValue) {
return NextResponse.json({ error: "Contexto da máquina ausente." }, { status: 404 })
}
const decoded = decodeMachineCookie(cookieValue)
if (!decoded?.machineId) {
return NextResponse.json({ error: "Contexto da máquina inválido." }, { status: 400 })
}
const convexUrl = env.NEXT_PUBLIC_CONVEX_URL
if (!convexUrl) {
return NextResponse.json({ error: "Convex não configurado." }, { status: 500 })
}
const client = new ConvexHttpClient(convexUrl)
const cookieStore = await cookies()
const cookieValue = cookieStore.get(MACHINE_CTX_COOKIE)?.value ?? null
const decoded = cookieValue ? decodeMachineCookie(cookieValue) : null
let machineId: Id<"machines"> | null = decoded?.machineId ? (decoded.machineId as Id<"machines">) : null
if (!machineId) {
try {
const lookup = (await client.query(api.machines.findByAuthEmail, {
authEmail: session.user.email.toLowerCase(),
})) as { id: string } | null
if (!lookup?.id) {
return NextResponse.json({ error: "Máquina não vinculada à sessão atual." }, { status: 404 })
}
machineId = lookup.id as Id<"machines">
} catch (error) {
console.error("[machines.session] Falha ao localizar máquina por e-mail", error)
return NextResponse.json({ error: "Não foi possível localizar a máquina." }, { status: 500 })
}
}
try {
const context = (await client.query(api.machines.getContext, {
machineId: decoded.machineId as Id<"machines">,
machineId,
})) as {
id: string
tenantId: string
@ -66,10 +88,32 @@ export async function GET() {
authEmail: string | null
}
return NextResponse.json({
const responsePayload = {
machineId: context.id,
persona: context.persona,
assignedUserId: context.assignedUserId,
assignedUserEmail: context.assignedUserEmail,
assignedUserName: context.assignedUserName,
assignedUserRole: context.assignedUserRole,
}
const response = NextResponse.json({
machine: context,
cookie: decoded,
cookie: responsePayload,
})
const isSecure = request.nextUrl.protocol === "https:"
response.cookies.set({
name: MACHINE_CTX_COOKIE,
value: encodeMachineCookie(responsePayload),
httpOnly: true,
sameSite: "lax",
secure: isSecure,
path: "/",
maxAge: 60 * 60 * 24 * 30,
})
return response
} catch (error) {
console.error("[machines.session] Falha ao obter contexto da máquina", error)
return NextResponse.json({ error: "Falha ao obter contexto da máquina." }, { status: 500 })

View file

@ -55,12 +55,13 @@ export async function POST(request: Request) {
assignedUserName: session.machine.assignedUserName,
assignedUserRole: session.machine.assignedUserRole,
}
const isSecure = new URL(request.url).protocol === "https:"
response.cookies.set({
name: "machine_ctx",
value: Buffer.from(JSON.stringify(machineCookiePayload)).toString("base64url"),
httpOnly: true,
sameSite: "lax",
secure: true,
secure: isSecure,
path: "/",
maxAge: 60 * 60 * 24 * 30,
})