supersam/supabase/functions/get-delivery-invitation/index.ts

130 lines
3.5 KiB
TypeScript

import {
getClientInvitationStateFromOrderStatus,
hashInvitationToken,
isActiveInvitationState,
} from "../_shared/delivery-invitations.ts";
import { createServiceClient } from "../_shared/chatbot.ts";
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers": "authorization, x-client-info, apikey, content-type",
};
Deno.serve(async (request) => {
if (request.method === "OPTIONS") {
return new Response("ok", { headers: corsHeaders });
}
if (!["GET", "POST"].includes(request.method)) {
return new Response(JSON.stringify({ error: "Method not allowed" }), {
status: 405,
headers: {
...corsHeaders,
"Content-Type": "application/json",
},
});
}
try {
const url = new URL(request.url);
const token = request.method === "POST"
? ((await request.json()) as { token?: string })?.token || ""
: url.searchParams.get("token") || "";
if (!token) {
return new Response(JSON.stringify({ error: "token is required" }), {
status: 400,
headers: {
...corsHeaders,
"Content-Type": "application/json",
},
});
}
const tokenHash = await hashInvitationToken(token);
const supabase = createServiceClient();
const { data: invitation, error: invitationError } = await supabase
.from("delivery_invitations")
.select("*")
.eq("token_hash", tokenHash)
.single();
if (invitationError) {
if (invitationError.code === "PGRST116") {
return new Response(
JSON.stringify({ ok: false, error: "Invitation not found" }),
{
status: 404,
headers: {
...corsHeaders,
"Content-Type": "application/json",
},
},
);
}
throw invitationError;
}
const { data: order, error: orderError } = await supabase
.from("orders")
.select("id, order_number, status, delivery_agreement_status, customer")
.eq("id", invitation.order_id)
.single();
if (orderError) {
throw orderError;
}
const publicState = getClientInvitationStateFromOrderStatus(order.status);
if (isActiveInvitationState(publicState) && !invitation.opened_at) {
await supabase
.from("delivery_invitations")
.update({
opened_at: new Date().toISOString(),
})
.eq("id", invitation.id);
}
return new Response(
JSON.stringify({
ok: true,
invitation: {
orderId: invitation.order_id,
state: publicState,
token: token,
orderNumber: order.order_number,
customerName: order.customer?.name || invitation.customer_name || null,
customerPhone: order.customer?.phone || invitation.customer_phone || null,
availableSlots: invitation.available_slots || [],
deliveryDate: invitation.delivery_date || null,
deliveryTime: invitation.delivery_time || null,
orderStatus: order.status,
deliveryAgreementStatus: order.delivery_agreement_status,
},
}),
{
headers: {
...corsHeaders,
"Content-Type": "application/json",
},
},
);
} catch (error) {
return new Response(
JSON.stringify({
ok: false,
error: error instanceof Error ? error.message : "Unexpected error",
}),
{
status: 500,
headers: {
...corsHeaders,
"Content-Type": "application/json",
},
},
);
}
});