91 lines
2.7 KiB
TypeScript
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" },
|
|
}
|
|
);
|
|
}
|
|
});
|