106 lines
2.9 KiB
TypeScript

import { serve } from "https://deno.land/std@0.168.0/http/server.ts";
import { mydb } from "../../lib/mySupabase.ts";
import { corsHeaders, jsonResponse, errorResponse } from "../../lib/utils.ts";
import { validateAuth } from "../../lib/auth.ts";
/**
* POST /appointments/confirm/:token
* Confirmar consulta via link com token temporário
*
* Params:
* token: string (UUID gerado e enviado por email/SMS)
*
* Body:
* {
* confirmed: boolean,
* confirmation_method?: string (email|sms|app|link)
* }
*
* Returns:
* {
* success: boolean,
* appointment_id: uuid,
* confirmed: boolean,
* message: string
* }
*/
serve(async (req) => {
if (req.method === "OPTIONS") {
return new Response("ok", { headers: corsHeaders() });
}
try {
const url = new URL(req.url);
const token = url.pathname.split("/").pop();
// Token pode ser usado sem autenticação (é seguro por ser temporário)
// Mas vamos validar o token
const tempTokenRes = await mydb
.from("temp_tokens")
.select("*")
.eq("token", token)
.eq("purpose", "appointment_confirmation")
.single();
if (tempTokenRes.error || !tempTokenRes.data) {
return errorResponse("Token inválido ou expirado", 400);
}
const tempToken = tempTokenRes.data;
// Verificar se token expirou
if (new Date(tempToken.expires_at) < new Date()) {
return errorResponse("Token expirado", 400);
}
if (req.method !== "POST") {
return errorResponse("Method not allowed", 405);
}
const body = await req.json();
const { confirmed, confirmation_method } = body;
const appointmentId = tempToken.payload?.appointment_id;
if (!appointmentId) {
return errorResponse("Appointment ID não encontrado no token", 400);
}
// Marcar token como usado
await mydb
.from("temp_tokens")
.update({ used_at: new Date().toISOString() })
.eq("token", token);
// Registrar confirmação no banco
await mydb.from("appointment_history").insert({
appointment_id: appointmentId,
field_changed: "confirmation_status",
old_value: "pending_confirmation",
new_value: confirmed ? "confirmed" : "not_confirmed",
change_reason: `Confirmação via ${confirmation_method || "link"}`,
});
// Audit log (sem user_id pois é confirmação pública)
await mydb.from("audit_log").insert({
action: "confirm_appointment_link",
target_type: "appointment",
target_id: appointmentId,
payload: { confirmed, confirmation_method, token_used: token },
});
return jsonResponse({
success: true,
appointment_id: appointmentId,
confirmed,
message: confirmed
? "Consulta confirmada com sucesso!"
: "Consulta não confirmada",
});
} catch (error: unknown) {
console.error("[confirm]", error);
const err = error as Error;
return errorResponse(err.message, 500);
}
});