102 lines
2.6 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, hasPermission } from "../../lib/auth.ts";
/**
* POST /appointments/no-show
* Marcar consulta como no-show (paciente não compareceu)
*
* Body:
* {
* appointment_id: uuid,
* reason?: string,
* automatic_detection?: boolean
* }
*
* Returns:
* {
* success: boolean,
* appointment_id: uuid,
* penalty_applied: boolean,
* message: string
* }
*/
serve(async (req) => {
if (req.method === "OPTIONS") {
return new Response("ok", { headers: corsHeaders() });
}
try {
const auth = await validateAuth(req);
if (!auth) {
return errorResponse("Não autorizado", 401);
}
if (req.method !== "POST") {
return errorResponse("Method not allowed", 405);
}
const body = await req.json();
const { appointment_id, reason, automatic_detection } = body;
// Apenas staff ou sistema pode marcar no-show
if (
!hasPermission(auth.role, ["admin", "secretary", "doctor"]) &&
!automatic_detection
) {
return errorResponse("Sem permissão", 403);
}
// Registrar no-show
const noShowRes = await mydb
.from("no_show_tracking")
.insert({
appointment_id,
patient_id: null, // Será preenchido na query
doctor_id: null,
marked_at: new Date().toISOString(),
reason,
automatic_detection: automatic_detection || false,
})
.select();
if (noShowRes.error) {
return errorResponse(noShowRes.error.message);
}
// Aplicar penalidade se necessário
let penaltyApplied = false;
// TODO: Implementar lógica de penalidade (reduzir pontos gamificação, etc)
// Registrar em patient_journey
await mydb.from("patient_journey").insert({
patient_id: null,
event_type: "no_show",
event_data: { appointment_id, reason },
points_earned: -5, // Penalidade de pontos
});
// Audit log
await mydb.from("audit_log").insert({
user_id: automatic_detection ? null : auth.userId,
action: "mark_no_show",
target_type: "appointment",
target_id: appointment_id,
payload: { reason, automatic: automatic_detection },
});
return jsonResponse({
success: true,
appointment_id,
penalty_applied: penaltyApplied,
message: "Consulta marcada como no-show",
});
} catch (error: unknown) {
console.error("[no-show]", error);
const err = error as Error;
return errorResponse(err.message, 500);
}
});