91 lines
2.7 KiB
TypeScript

import { validateExternalAuth } from "../_shared/auth.ts";
import { getExternalAppointments } from "../_shared/external.ts";
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers":
"authorization, x-client-info, apikey, content-type",
};
Deno.serve(async (req) => {
if (req.method === "OPTIONS")
return new Response("ok", { headers: corsHeaders });
try {
const { user, ownSupabase } = await validateExternalAuth(req);
const supabase = ownSupabase;
const externalJwt = req.headers.get("x-external-jwt")!;
const { doctor_id, date_from, date_to } = await req.json();
// 1. Verificar se existe cache válido no NOSSO Supabase
const cacheKey = `heatmap_${doctor_id || "all"}_${date_from}_${date_to}`;
const { data: cachedData } = await supabase
.from("analytics_cache")
.select("*")
.eq("cache_key", cacheKey)
.gte("expires_at", new Date().toISOString())
.single();
if (cachedData) {
return new Response(
JSON.stringify({ success: true, data: cachedData.data, cached: true }),
{ headers: { ...corsHeaders, "Content-Type": "application/json" } }
);
}
// 2. Buscar appointments do Supabase EXTERNO
const appointments = await getExternalAppointments(
{ doctor_id },
`Bearer ${externalJwt}`
);
// 3. Processar heatmap (dia da semana x hora)
const heatmap: Record<string, Record<string, number>> = {};
const days = [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
];
appointments.forEach((apt: any) => {
// scheduled_at é timestamp ISO 8601 (ex: "2025-11-27T14:30:00")
const date = new Date(apt.scheduled_at);
const dayName = days[date.getDay()];
const hour = date.getHours();
if (!heatmap[dayName]) heatmap[dayName] = {};
if (!heatmap[dayName][hour]) heatmap[dayName][hour] = 0;
heatmap[dayName][hour]++;
});
// 4. Salvar no cache (expira em 1 hora)
const expiresAt = new Date();
expiresAt.setHours(expiresAt.getHours() + 1);
await supabase.from("analytics_cache").upsert({
cache_key: cacheKey,
data: heatmap,
expires_at: expiresAt.toISOString(),
created_at: new Date().toISOString(),
});
return new Response(
JSON.stringify({ success: true, data: heatmap, cached: false }),
{ headers: { ...corsHeaders, "Content-Type": "application/json" } }
);
} catch (error: any) {
return new Response(
JSON.stringify({ success: false, error: error.message }),
{
status: 400,
headers: { ...corsHeaders, "Content-Type": "application/json" },
}
);
}
});