Files
pwap/web/supabase/functions/cleanup-proofs/index.ts
T
pezkuwichain 508f0763f4 fix: payment proof lifecycle, repeating toast, and escrow migrations
- Replace IPFS/Pinata upload with Supabase Storage for payment proofs
- Add 1-day auto-expiry for proof images (retained if disputed)
- Fix repeating "payment deadline expired" toast (fire once, clear interval)
- Fix cancel_reason → cancellation_reason column reference
- Add payment proof lifecycle migration (proof_expires_at, cleanup functions)
- Add atomic escrow migration (accept_p2p_offer, complete/cancel trade)
- Add cleanup-proofs edge function for daily expired proof deletion
2026-02-24 06:15:22 +03:00

79 lines
2.2 KiB
TypeScript

/**
* Cleanup expired payment proofs
*
* Schedule: Daily via Supabase Dashboard > Database > Extensions > pg_cron
* Or call manually: supabase functions invoke cleanup-proofs
*
* Flow:
* 1. Call DB function to get expired proof URLs and clear them
* 2. Delete actual files from Supabase Storage
*/
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2'
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 supabase = createClient(
Deno.env.get('SUPABASE_URL')!,
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
)
// 1. Find expired proofs (not disputed, past expiry)
const { data: expiredTrades, error: fetchError } = await supabase
.from('p2p_fiat_trades')
.select('id, buyer_payment_proof_url')
.not('buyer_payment_proof_url', 'is', null)
.not('proof_expires_at', 'is', null)
.lt('proof_expires_at', new Date().toISOString())
.not('status', 'eq', 'disputed')
if (fetchError) throw fetchError
let deleted = 0
for (const trade of expiredTrades || []) {
// 2. Extract storage path from URL
const url = trade.buyer_payment_proof_url
const pathMatch = url?.match(/p2p-payment-proofs\/(.+)$/)
if (pathMatch) {
// 3. Delete file from storage
await supabase.storage
.from('p2p-payment-proofs')
.remove([pathMatch[1]])
}
// 4. Clear URL in DB
await supabase
.from('p2p_fiat_trades')
.update({
buyer_payment_proof_url: null,
proof_expires_at: null,
updated_at: new Date().toISOString(),
})
.eq('id', trade.id)
deleted++
}
return new Response(
JSON.stringify({ success: true, deleted }),
{ headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
)
} catch (error) {
return new Response(
JSON.stringify({ success: false, error: error.message }),
{ status: 500, headers: { ...corsHeaders, 'Content-Type': 'application/json' } }
)
}
})