Appearance
APIs & Integrations ​
Purpose: Document internal APIs (Edge Functions, RPCs) and external integrations used by the app. Audience: Developer, Owner, AI Agent Prerequisites: Supabase project linked; Stripe/Resend configured.
Internal APIs
- Supabase Edge Functions (TypeScript/Deno) under
supabase/functions/*.- Billing/subscriptions:
stripe-webhook— webhook handler for Stripe events (supabase/functions/stripe-webhook/index.ts:5)stripe-sync— Stripe data sync taskssync-invoices,daily-subscription-sync,check-subscription,fix-subscription-dates,auto-fix-subscription-dates,set-starter-subscriptionsget-price-id— helper to map plan/interval to Stripe Price ID
- Checkout/customer portal:
create-checkout,customer-portal
- Deals/payments:
create-deal-checkout,create-deal-payment,refund-deal-payment,release-deal-payout,payment-status
- Notifications/email:
send-email,send-notification,send-admin-listing-notification,send-admin-message,send-auth-email,send-payment-email,send-admin-contact-notification,send-listing-approval-notification,send-new-user-notification,send-sponsored-notifications
- Schedulers/maintenance:
run-daily-tasks,run-price-alerts,update-views-count,cleanup-duplicates,process-sponsored-activations
- Onboarding/connect:
connect-onboarding-link,connect-dashboard-link,refresh-kyc-status
- Documents:
deal-create-upload-url,generate-apa-pdf
- AI & Analysis:
analyze-project— AI-powered project analysis using Mistral AI
- Billing/subscriptions:
Blur policy (DB helpers)
- View:
public.listing_view_secure— projects listing columns usingcan_view_field - RPC:
public.can_view_field(p_listing, p_field_key, p_user?)— allows/denies visibility based onblurred_fieldsand subscription plan - Config:
public.blurred_fields— flags per plan (unauth/free/starter/pro) - Frontend mapping:
FIELD_TO_COLUMN_MAP,VISUALLY_BLURRED_FIELDS_TO_FETCH,COMPLETELY_BLOCKED_FIELDS_IF_BLURRED - Docs:
docs/architecture/blur-policy.md
Inventory (by folder name)
apa-auto-handover — automate asset handover steps
auth-email-webhook — auth-related email handler
auto-fix-subscription-dates, fix-subscription-dates — data corrections for subscriptions
check-subscription — verify current subscription and sync
cleanup-duplicates — maintenance
connect-dashboard-link, connect-onboarding-link — Stripe Connect flows
create-checkout — Subscriptions checkout
create-deal-checkout, create-deal-payment — Deal checkout/payment
customer-portal — Manage billing portal sessions
daily-subscription-sync — Periodic sync for subscriptions
deal-create-upload-url — Pre-signed URL for deal docs
fix-user-subscription — Repair user subscription linkage
generate-apa-pdf — Generate APA PDF
get-price-id — Map plan/interval to Stripe Price ID
payment-status — Return payment status
process-sponsored-activations — Sponsored listing activations
refresh-kyc-status — Stripe KYC status refresh
refund-deal-payment — Refund logic
release-deal-payout — Release payouts to sellers
run-daily-tasks — Orchestrator for daily jobs
run-price-alerts — Execute price alert checks
security-headers — Common security headers
send-admin-contact-notification — Notify admin of contact
send-admin-listing-notification — Notify admin of listing events
send-admin-message — Admin direct message
send-auth-email — Authentication emails
send-email — Generic email sender
send-listing-approval-notification — Notify sellers upon approval
send-listing-notifications — Listing-related notifications
send-new-user-notification — Notify on new user
send-notification — General notification function
send-payment-email — Payment emails
send-resubmission-notification — Notify for resubmissions
send-sponsored-notifications — Sponsored listing notifications
set-starter-subscriptions — Set Starter for cohorts
stripe-sync — Sync with Stripe
stripe-webhook — Webhook entrypoint for Stripe
sync-invoices — Invoice synchronization
test-env, test-sponsored-activation, test-stripe — testing utilities
update-views-count — Increment listing views
PostgreSQL functions (RPCs) — selected examples:
calculate_commission(p_amount numeric, p_seller_id uuid)— computes commission by seller tier (supabase/backups/remote-schema.sql:257)- Other RPCs used by admin and listings may be present; confirm in migrations before use.
External services
- Stripe — subscriptions, payments, Connect onboarding and payouts
- Secrets server-side:
STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET - Publishable key client-side:
VITE_STRIPE_PUBLISHABLE_KEY
- Secrets server-side:
- Resend (via
send-emailfunction) — transactional emails - Mistral AI — AI-powered project analysis
- Secret server-side:
MISTRAL_API_KEY(Supabase project secret) - Models:
mistral-small-latest(primary),mistral-large-latest(fallback) - Rate limits: Handles 429 errors gracefully
- Secret server-side:
- Supabase Realtime — WebSocket updates for critical events
- Frontend hook:
src/hooks/useGlobalRealtimeNotifications.ts:24
- Frontend hook:
Realtime model
- Critical channel with row filters per user for
subscriptions,offers, andlistingsstatus changes- See
src/hooks/useGlobalRealtimeNotifications.ts:24-55,65-118
- See
- Non-critical admin notifications via polling to minimize socket load
- See
src/hooks/useAdminPollingNotifications.ts:40-175
- See
Security
- Never expose secrets in client code. Use env per
docs/setup/environment.md. - Validate Stripe webhooks; verify signatures and idempotency in Edge Functions.
Invocation patterns (frontend → Edge Functions)
Send email
- Code:
src/lib/emailService.ts:19-21 - Pattern:ts
await supabase.functions.invoke('send-email', { body: { to, subject, html, emailType } })
- Code:
Resolve price ID + create subscription checkout
- Code:
src/hooks/useStripeCheckout.ts:31-53 - Flow:
get-price-idwith{ plan: 'starter_monthly' | 'pro_monthly' | ... }create-checkoutwith{ priceId, successUrl, cancelUrl }→{ url }
- Code:
Open Stripe customer portal
- Code:
src/hooks/useCustomerPortal.ts:27-40 - Pattern:ts
const { data } = await supabase.functions.invoke('customer-portal') window.open(data.url, '_blank')
- Code:
Admin notifications (batch/polling)
- Code:
src/hooks/useAdminPollingNotifications.ts:67-69, 101-148, 188-197 - Functions:
send-admin-listing-notification,send-email
- Code:
Seller verification emails + in-app notifications
- Code:
src/hooks/useSellerVerification.ts:47-57, 72-82
- Code:
Stripe webhook events (server → DB side-effects)
- Function:
supabase/functions/stripe-webhook/index.ts - Examples handled:
account.updated— maps Stripe Connect account KYC/payout status into DB (connect_accounts,profiles); see file top and mapping helpers.- Typical subscription events (
checkout.session.completed,customer.subscription.*) are expected to be handled by billing functions (see Inventory) to updatesubscriptions.
Deal payments (server → checkout/intents/payout)
- Functions:
create-deal-checkout,create-deal-payment,payment-status,release-deal-payout,refund-deal-payment. - Frontend references:
src/pages/Deal.tsx(Stripe Elements) and Admin transactions (src/pages/admin/AdminTransactions.tsx:237,255).
Orchestration and scheduling
run-daily-tasks— calls sub-functions using internal logic/slots.run-price-alerts— scans price alerts (price_alerts,price_alert_events,price_alert_runs).
Error handling conventions
- Frontend checks
{ data, error }fromfunctions.invokeand reports via toasts/logs. - Server logs are visible in Supabase dashboard per function; include correlation metadata where useful.
Rate limiting and performance
- Prefer critical-only realtime; batch non-critical via polling.
- Use SELECT with counts only where needed; paginate (9 items per page in Explore).
Examples (JS + curl)
send-email
- JS (includes user JWT automatically):ts
await supabase.functions.invoke('send-email', { body: { to: 'test@example.com', subject: 'Hello', html: '<b>Hi</b>', emailType: 'test' } }) - curl (local dev):bash
curl -X POST http://127.0.0.1:54321/functions/v1/send-email \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer YOUR_SUPABASE_ANON_KEY' \ -d '{"to":"test@example.com","subject":"Hello","html":"<b>Hi</b>","emailType":"test"}'
- JS (includes user JWT automatically):
get-price-id → create-checkout (subscriptions)
- JS:ts
const { data: price } = await supabase.functions.invoke('get-price-id', { body: { plan: 'starter_monthly' } }) const { data: checkout } = await supabase.functions.invoke('create-checkout', { body: { priceId: price?.priceId, successUrl: location.origin + '/?ok=1', cancelUrl: location.origin + '/?cancel=1' } }) window.open(checkout?.url, '_blank') - curl (local):bash
curl -s http://127.0.0.1:54321/functions/v1/get-price-id -H 'Authorization: Bearer YOUR_SUPABASE_ANON_KEY' -H 'Content-Type: application/json' -d '{"plan":"starter_monthly"}' curl -s http://127.0.0.1:54321/functions/v1/create-checkout -H 'Authorization: Bearer YOUR_SUPABASE_ANON_KEY' -H 'Content-Type: application/json' -d '{"priceId":"PRICE_ID"}'
- JS:
customer-portal
- JS:ts
const { data } = await supabase.functions.invoke('customer-portal') window.open(data?.url, '_blank')
- JS:
create-deal-payment
- JS:ts
const { data } = await supabase.functions.invoke('create-deal-payment', { body: { dealId } }) const clientSecret = data?.client_secret
- JS:
release-deal-payout / refund-deal-payment (admin)
- curl (via dev proxy):bashNote: Require admin role; in production call the hosted function endpoint with proper Authorization.
curl -X POST /functions/v1/release-deal-payout -H 'Content-Type: application/json' -d '{"dealId":"DEAL_UUID"}' curl -X POST /functions/v1/refund-deal-payment -H 'Content-Type: application/json' -d '{"dealId":"DEAL_UUID"}'
- curl (via dev proxy):
Stripe Connect
- Onboarding link:ts
const { data } = await supabase.functions.invoke('connect-onboarding-link'); window.open(data?.url, '_blank') - Dashboard link:ts
const { data } = await supabase.functions.invoke('connect-dashboard-link'); window.open(data?.url, '_blank') - Refresh KYC:ts
const { data } = await supabase.functions.invoke('refresh-kyc-status') // data.summary.currently_due_count, past_due_count, disabled_reason, payouts_enabled
- Onboarding link:
Subscription sync (Stripe)
- check-subscription:ts
const { data, error } = await supabase.functions.invoke('check-subscription') - sync-invoices / stripe-sync / daily-subscription-sync (scheduled):bash
curl -X POST http://127.0.0.1:54321/functions/v1/sync-invoices -H 'Authorization: Bearer YOUR_SUPABASE_ANON_KEY'
- check-subscription:
Price alerts (scheduled)
- run-price-alerts:bash
curl -X POST http://127.0.0.1:54321/functions/v1/run-price-alerts -H 'Authorization: Bearer YOUR_SUPABASE_ANON_KEY'
- run-price-alerts:
AI Project Analysis
- analyze-project:ts
const { data, error } = await supabase.functions.invoke('analyze-project', { body: { url: 'https://example.com' } }) // Returns structured project analysis JSON - curl (local dev):bash
curl -X POST http://127.0.0.1:54321/functions/v1/analyze-project \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer YOUR_SUPABASE_ANON_KEY' \ -d '{"url":"https://example.com"}'
- analyze-project:
Roles & permissions (high-level)
- Public/user: get-price-id, create-checkout (authenticated), customer-portal (authenticated), create-deal-payment (participant), send-email (system controlled use), refresh-kyc-status (seller), connect-* (seller), analyze-project (authenticated)
- Admin: release-deal-payout, refund-deal-payment, send-admin-* functions, cleanup-duplicates, process-sponsored-activations
- Scheduled: run-daily-tasks, run-price-alerts, daily-subscription-sync, stripe-sync, sync-invoices, update-views-count
Next steps
- See
docs/setup/stripe.mdfor Stripe keys and webhooks. - See
docs/operations/monitoring.mdfor function monitoring.