Part of epic #100.
Wraps up Phase 0 by adding shared helpers used across all 8 functions AND un-skipping the dormant E2E test suite.
Shared helpers to ship
Three files under supabase/functions/_shared/:
1. cors.ts
Standard CORS preflight + headers helper. Every function should import:
import { corsHeaders, handleCors } from '../_shared/cors.ts';
serve(async (req) => {
const cors = handleCors(req);
if (cors) return cors; // returns preflight response, or null
// ... function logic
return new Response(JSON.stringify(...), { headers: corsHeaders });
});
2. auth.ts
Extract user_id from caller's JWT (the browser sends Authorization: Bearer <token> automatically via Supabase client).
export async function getUserId(req: Request): Promise<string> {
const authHeader = req.headers.get('Authorization');
if (!authHeader) throw new Error('Missing Authorization header');
// Use supabase.auth.getUser(token) to verify + extract
// Return user.id, or throw
}
3. idempotency.ts
Helper to compute / read idempotency_key from a payment_intents row:
export function getIdempotencyKey(intent: PaymentIntent): string {
return intent.idempotency_key || crypto.randomUUID();
}
E2E test un-skip
The 7 files under tests/e2e/payment/ contain 86 test.skip()'d tests total:
| File |
Skipped tests |
01-stripe-onetime.spec.ts |
8 |
02-paypal-subscription.spec.ts |
12 |
03-failed-payment-retry.spec.ts |
12 |
04-gdpr-consent.spec.ts |
2 |
05-offline-queue.spec.ts |
18 |
06-realtime-dashboard.spec.ts |
20 |
07-performance.spec.ts |
14 |
Most have inline test.skip(!isStripeConfigured, '...') guards that the previous Phase 0a–0e sub-issues will partially un-block. This issue is for the FINAL pass: remove the outer test.skip() decorators so the suite runs against sandbox keys.
Acceptance
🤖 Created from audit on 2026-05-20
Part of epic #100.
Wraps up Phase 0 by adding shared helpers used across all 8 functions AND un-skipping the dormant E2E test suite.
Shared helpers to ship
Three files under
supabase/functions/_shared/:1.
cors.tsStandard CORS preflight + headers helper. Every function should import:
2.
auth.tsExtract
user_idfrom caller's JWT (the browser sendsAuthorization: Bearer <token>automatically via Supabase client).3.
idempotency.tsHelper to compute / read
idempotency_keyfrom apayment_intentsrow:E2E test un-skip
The 7 files under
tests/e2e/payment/contain 86test.skip()'d tests total:01-stripe-onetime.spec.ts02-paypal-subscription.spec.ts03-failed-payment-retry.spec.ts04-gdpr-consent.spec.ts05-offline-queue.spec.ts06-realtime-dashboard.spec.ts07-performance.spec.tsMost have inline
test.skip(!isStripeConfigured, '...')guards that the previous Phase 0a–0e sub-issues will partially un-block. This issue is for the FINAL pass: remove the outertest.skip()decorators so the suite runs against sandbox keys.Acceptance
supabase/functions/_shared/cors.tsexists and is used by at least one Phase 0a-0e functionsupabase/functions/_shared/auth.tsexists and is used by all 8 Phase 0 functionssupabase/functions/_shared/idempotency.tsexiststest.skip()decorators removed fromtests/e2e/payment/*.spec.tsdocker compose exec scripthammer pnpm exec playwright test tests/e2e/payment/runs against sandbox: all tests either pass OR cleanly skip via the innertest.skip(!isStripeConfigured, ...)guard (for forks without keys)docs/PAYMENT-DEPLOYMENT.mdStep 4.2 updated to remove "NOT YET SHIPPED" warning🤖 Created from audit on 2026-05-20