Chargement…
Chargement…
Case study orienté impact: objectif métier clair, exécution maîtrisée, preuve ROI et plan de delivery traçable.
Statut
Bientôt disponible
Projet personnel en conditions réelles
Preuve technique
RLS multi-tenant
Supabase Auth + Postgres
Accès
Démo live
Lien direct plus bas sur cette page
Scope livré
0 livrables
Briques prêtes à exploiter par les équipes
Aperçu produit
Leads scorés
128
workspace démo
Deals en pipeline
61
4 étapes kanban
RLS
Actif
scopé par workspace
Auth
Supabase
comptes réels, pas de mock
Funnel produit (workspace démo)
Lead entrant
Scoring automatique
Routing membre
Deal créé (pipeline)
Proposition IA générée
Deal gagné
Équipe & infrastructure
Membre invité
Accepté · rôle CommercialBannière paiement
past_due → lien /billingPolitique RLS
Scoping par workspace vérifiéQueue Inngest
Repli synchrone si clé absenteCœur produit
Livré & testé
Bloqué sur
Clés de prod
Supabase/Stripe/OpenAI
Architecture système
Lead intake
Scoring + routing automatique
RLS multi-tenant
Supabase Auth · isolation workspace
Pipeline Kanban
Deals · proposals
Queue durable
Inngest · retries automatiques
Proposition IA
Génération GPT-4o
Code — extrait anonymisé
1// Logique partagée — appelée par la fonction Inngest ET par le repli synchrone2async function processLead(input: LeadInput, workspaceId: string): Promise<Deal> {3 const scored = scoreLead(input) // même logique, quel que soit le chemin d'exécution4 const route = routeToOwner(scored, await getWorkspaceMembers(workspaceId))56 return db.deals.create({7 workspaceId, // scope RLS — jamais de fuite cross-tenant8 leadId: input.id,9 score: scored.value,10 ownerId: route.ownerId,11 stage: 'new',12 })13}
1// Queue durable — repli synchrone si Inngest n'est pas configuré (jamais bloquant)2export const processLeadEvent = inngest.createFunction(3 { id: 'process-lead', retries: 3 },4 { event: 'lead/created' },5 async ({ event }) => processLead(event.data.lead, event.data.workspaceId)6)78async function submitLead(input: LeadInput, workspaceId: string): Promise<Deal> {9 const sent = await inngest.send({ name: 'lead/created', data: { lead: input, workspaceId } })10 if (sent) return { status: 'queued' } as Deal1112 // INNGEST_EVENT_KEY absent → même logique exécutée en ligne, pas d'échec visible13 return processLead(input, workspaceId)14}
Le problème
Les agences et cabinets de conseil (2-30 personnes) ont dépassé le tableur mais ne peuvent pas justifier Salesforce ou Clari : chaque lead doit être routé et scoré en quelques minutes, et un dashboard doit expliquer en langage clair pourquoi l'objectif du mois a été manqué — pas juste afficher des chiffres.
La solution
Couche RevOps complète livrée et testée : schéma multi-tenant (workspaces, leads, deals, proposals), row-level security scopant chaque requête à l'appartenance au workspace, vrais comptes via Supabase Auth (le signup crée un utilisateur et son workspace en une étape), queue de traitement durable (Inngest, avec repli synchrone si non configuré), invitations d'équipe et génération de propositions par IA. Seul blocage restant : les vraies clés de production (Supabase/Stripe/OpenAI) ne sont pas encore posées sur Railway — un dossier stratégique complet (niche, concurrents, modèle économique, roadmap) documente pourquoi ce scope et cette niche.
Impact clé
Stack technique