Files
photobooth-qr/supabase/functions/_shared/supabase-admin.ts
T
KevinLecou 9b1461978b Ajoute la V1 fonctionnelle : upload invité, galerie admin, QR code, backend Supabase
Schéma dédié `photobooth` (jamais exposé via PostgREST, accès exclusivement
via fonctions SECURITY DEFINER dans public) avec RLS, policies Storage sur
bucket privé event-photos, Edge Functions admin-gallery et expire-events,
et job pg_cron d'expiration J+7. Le tout déployé et testé en conditions
réelles sur le projet Supabase kevin-lecou-hub avant relecture sécurité
(faille d'abus sur insert_public_photo corrigée en cours de route).

Côté front : page upload invité (compression + HEIC + RGPD), galerie admin
avec export ZIP, générateur de QR code autonome. Workflow n8n de purge
Storage J+7 fourni (à activer manuellement côté n8n).
2026-09-16 11:32:31 +02:00

45 lines
1.7 KiB
TypeScript

// Client Supabase service_role, partagé entre les Edge Functions du projet.
//
// SUPABASE_URL et SUPABASE_SERVICE_ROLE_KEY sont injectées automatiquement
// par le runtime Supabase Edge Functions dans chaque fonction déployée (pas
// besoin de les définir soi-même via `supabase secrets set`) — cf. doc
// Supabase "Edge Functions > Environment variables". En local
// (`supabase functions serve`), elles sont également injectées à partir du
// projet local.
//
// ⚠️ Ce client ne doit JAMAIS être exposé côté front (cf. CLAUDE.md :
// "Ne jamais exposer la service_role key côté client"). Il ne doit exister
// que dans ces Edge Functions, exécutées côté serveur par construction.
import {
createClient,
type SupabaseClient,
} from "npm:@supabase/supabase-js@2";
let cachedClient: SupabaseClient | null = null;
export function getSupabaseAdmin(): SupabaseClient {
if (cachedClient) return cachedClient;
const url = Deno.env.get("SUPABASE_URL");
const serviceRoleKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY");
if (!url || !serviceRoleKey) {
throw new Error(
"SUPABASE_URL / SUPABASE_SERVICE_ROLE_KEY manquantes dans l'environnement de l'Edge Function."
);
}
cachedClient = createClient(url, serviceRoleKey, {
auth: { persistSession: false },
});
return cachedClient;
}
/** Nom du bucket Storage des photos. Même variable que côté front
* (.env.example : SUPABASE_STORAGE_BUCKET), à définir comme secret de
* fonction ; valeur de repli alignée sur la migration
* 20260915120400_storage_event_photos_policies.sql. */
export function getStorageBucket(): string {
return Deno.env.get("SUPABASE_STORAGE_BUCKET") ?? "event-photos";
}