Fix consulting order processing and display

- Fix consulting history to show continuous time range (09:00 - 11:00) instead of listing individual slots
- Add foreign key relationships for consulting_slots (order_id and user_id)
- Fix handle-order-paid to query profiles(email, name) instead of full_name
- Add completed consulting sessions with recordings to Member Access page
- Add user_id foreign key constraint to consulting_slots table
- Add orders foreign key constraint for consulting_slots relationship

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
dwindown
2025-12-27 01:17:47 +07:00
parent 73c03285ea
commit 17440cdf89
10 changed files with 404 additions and 79 deletions

View File

@@ -24,17 +24,19 @@ serve(async (req: Request): Promise<Response> => {
const { order_id } = body;
console.log("[HANDLE-PAID] Processing paid order:", order_id);
console.log("[HANDLE-PAID] Request body:", JSON.stringify(body));
const supabaseUrl = Deno.env.get("SUPABASE_URL")!;
const supabaseServiceKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!;
const supabase = createClient(supabaseUrl, supabaseServiceKey);
// Get full order details with items AND consulting slots
// Use maybeSingle() in case there are no related records
const { data: order, error: orderError } = await supabase
.from("orders")
.select(`
*,
profiles(email, full_name),
profiles(email, name),
order_items (
product_id,
product:products (title, type)
@@ -48,12 +50,20 @@ serve(async (req: Request): Promise<Response> => {
)
`)
.eq("id", order_id)
.single();
.maybeSingle();
if (orderError || !order) {
console.error("[HANDLE-PAID] Order not found:", order_id, orderError);
if (orderError) {
console.error("[HANDLE-PAID] Database error:", orderError);
return new Response(
JSON.stringify({ success: false, error: "Order not found" }),
JSON.stringify({ success: false, error: "Database error", details: orderError.message }),
{ status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }
);
}
if (!order) {
console.error("[HANDLE-PAID] Order not found:", order_id);
return new Response(
JSON.stringify({ success: false, error: "Order not found", order_id }),
{ status: 404, headers: { ...corsHeaders, "Content-Type": "application/json" } }
);
}
@@ -67,7 +77,7 @@ serve(async (req: Request): Promise<Response> => {
}));
const userEmail = order.profiles?.email || "";
const userName = order.profiles?.full_name || "Pelanggan";
const userName = order.profiles?.name || userEmail.split('@')[0] || "Pelanggan";
const orderItems = order.order_items as Array<{
product_id: string;
product: { title: string; type: string };
@@ -140,12 +150,13 @@ serve(async (req: Request): Promise<Response> => {
// Don't fail the entire process
}
}
}
// Send consulting notification with the consultingSlots data
await sendNotification(supabase, "consulting_scheduled", {
nama: userName,
email: userEmail,
order_id: order_id.substring(0, 8),
order_id_short: order_id.substring(0, 8),
tanggal_pesanan: new Date().toLocaleDateString("id-ID"),
total: `Rp ${order.total_amount.toLocaleString("id-ID")}`,
metode_pembayaran: order.payment_method || "Unknown",
@@ -188,7 +199,7 @@ serve(async (req: Request): Promise<Response> => {
await sendNotification(supabase, "payment_success", {
nama: userName,
email: userEmail,
order_id: order_id.substring(0, 8),
order_id_short: order_id.substring(0, 8),
tanggal_pesanan: new Date().toLocaleDateString("id-ID"),
total: `Rp ${order.total_amount.toLocaleString("id-ID")}`,
metode_pembayaran: order.payment_method || "Unknown",

View File

@@ -65,7 +65,7 @@ serve(async (req) => {
// Find the order by payment_reference or id
const { data: order, error: orderError } = await supabase
.from("orders")
.select("id, payment_status")
.select("id, payment_status, user_id, total_amount")
.or(`payment_reference.eq.${payload.order_id},id.eq.${payload.order_id}`)
.single();

View File

@@ -0,0 +1,16 @@
-- Configure database settings for handle-order-paid trigger
-- These settings are required for the payment trigger to work
-- Set base URL (change if different)
DELETE FROM pg_settings WHERE name = 'app.base_url';
ALTER DATABASE postgres SET "app.base_url" = 'https://lovable.backoffice.biz.id';
-- Set service role key (you need to replace this with your actual service role key)
-- Get it from: Supabase Dashboard > Project Settings > API > service_role (confidential)
-- Uncomment and set the actual key:
-- ALTER DATABASE postgres SET "app.service_role_key" = 'YOUR_SERVICE_ROLE_KEY_HERE';
-- Verify settings
SELECT
current_setting('app.base_url', true) as base_url,
current_setting('app.service_role_key', true) as service_role_key;

View File

@@ -0,0 +1,37 @@
-- Add foreign key relationship between consulting_slots and profiles (user_id)
-- This enables the relationship query in ConsultingHistory component
-- First, check if the foreign key already exists
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.table_constraints
WHERE table_name = 'consulting_slots'
AND constraint_name = 'consulting_slots_user_id_fkey'
) THEN
-- Add foreign key constraint if it doesn't exist
ALTER TABLE consulting_slots
ADD CONSTRAINT consulting_slots_user_id_fkey
FOREIGN KEY (user_id) REFERENCES auth.users(id) ON DELETE CASCADE;
RAISE NOTICE 'Foreign key constraint added for user_id';
ELSE
RAISE NOTICE 'Foreign key constraint for user_id already exists';
END IF;
END $$;
-- Verify the relationship
SELECT
tc.table_name,
kcu.column_name,
ccu.table_name AS foreign_table_name,
ccu.column_name AS foreign_column_name
FROM information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
AND tc.table_schema = kcu.table_schema
JOIN information_schema.constraint_column_usage AS ccu
ON ccu.constraint_name = tc.constraint_name
WHERE tc.constraint_type = 'FOREIGN KEY'
AND tc.table_name = 'consulting_slots'
AND kcu.column_name = 'user_id';

View File

@@ -0,0 +1,36 @@
-- Add foreign key relationship between consulting_slots and orders
-- This enables the relationship query in handle-order-paid edge function
-- First, check if the column exists
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM information_schema.table_constraints
WHERE table_name = 'consulting_slots'
AND constraint_name = 'consulting_slots_order_id_fkey'
) THEN
-- Add foreign key constraint if it doesn't exist
ALTER TABLE consulting_slots
ADD CONSTRAINT consulting_slots_order_id_fkey
FOREIGN KEY (order_id) REFERENCES orders(id) ON DELETE CASCADE;
RAISE NOTICE 'Foreign key constraint added successfully';
ELSE
RAISE NOTICE 'Foreign key constraint already exists';
END IF;
END $$;
-- Verify the relationship
SELECT
tc.table_name,
kcu.column_name,
ccu.table_name AS foreign_table_name,
ccu.column_name AS foreign_column_name
FROM information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
AND tc.table_schema = kcu.table_schema
JOIN information_schema.constraint_column_usage AS ccu
ON ccu.constraint_name = tc.constraint_name
WHERE tc.constraint_type = 'FOREIGN KEY'
AND tc.table_name = 'consulting_slots';