import { corsHeaders, handleCorsPreflightRequest } from '../_shared/cors.ts' import { requireManager } from '../_shared/admin-auth.ts' import { createServiceRoleClient } from '../_shared/quota.ts' import { verifyCurrentAdminActor } from '../_shared/admin-current-role.ts' import { AdminPublicError, adminErrorResponse, adminJsonResponse, requireUuid, validateQueryKeys, } from '../_shared/admin-contract.ts' async function readPaymentHistory(req: Request): Promise { const admin = await requireManager(req) const url = new URL(req.url) validateQueryKeys(url, ['userId', 'source']) const userId = requireUuid(url.searchParams.get('userId'), 'invalid_userId') const source = url.searchParams.get('source') ?? 'db' if (source !== 'db' && source !== 'payple') throw new AdminPublicError(400, 'invalid_payment_source') if (source === 'payple') { throw new AdminPublicError(501, 'payple_live_history_not_configured') } const serviceClient = createServiceRoleClient() await verifyCurrentAdminActor(serviceClient, admin) const [subscriptionResult, auditResult, eventsResult, operationsResult] = await Promise.all([ serviceClient .from('subscriptions') .select('id, user_id, tier, status, provider, payment_provider, current_period_start, current_period_end, overage_credits, admin_note, cancel_at, created_at, updated_at') .eq('user_id', userId) .maybeSingle(), serviceClient .from('audit_log') .select('id, admin_id, action, target_type, target_id, memo, created_at') .eq('target_id', userId) .eq('target_type', 'subscription') .order('created_at', { ascending: false }) .limit(50), serviceClient .from('payment_provider_events') .select('id, provider, event_type, event_created_at, disposition, received_at, processed_at') .eq('user_id', userId) .order('event_created_at', { ascending: false }) .limit(50), serviceClient .from('payment_provider_operations') .select('id, provider, operation_type, requested_tier, state, error_code, expires_at, created_at, updated_at') .eq('user_id', userId) .order('created_at', { ascending: false }) .limit(50), ]) if (subscriptionResult.error || auditResult.error || eventsResult.error || operationsResult.error) { throw new AdminPublicError(500, 'admin_payment_read_failed') } return adminJsonResponse({ subscription: subscriptionResult.data ?? null, auditLogs: auditResult.data ?? [], providerEvents: eventsResult.data ?? [], providerOperations: operationsResult.data ?? [], liveProviderHistoryAvailable: false, }, corsHeaders) } export async function handleAdminPayments(req: Request): Promise { const preflight = handleCorsPreflightRequest(req) if (preflight) return preflight try { if (req.method !== 'GET') { return adminJsonResponse({ error: 'method_not_allowed' }, corsHeaders, 405) } return await readPaymentHistory(req) } catch (error) { console.error('admin-payments request failed', error) return adminErrorResponse(error, corsHeaders) } } if (import.meta.main) Deno.serve(handleAdminPayments)