Aller au contenu principal

Supabase avec Cursor : Développement backend-as-a-service piloté par l'IA

Cursor Supabase

Supabase fournit une puissante alternative open-source à Firebase pour les applications modernes. Combiné avec les capacités IA de Cursor, vous pouvez rapidement mettre en place l'authentification, la base de données, les abonnements en temps réel et les fonctions serverless. Ce guide couvre les workflows Supabase avec Cursor.

Prérequis​

Avant de commencer :

  • Cursor installé (dernière version recommandée)
  • Compte Supabase (le niveau gratuit suffit)
  • Supabase CLI installé pour le développement local

Configuration du projet​

Initialisation de Supabase​

# Installer Supabase CLI
npm install -g supabase

# Se connecter
supabase login

# Initialiser le projet
supabase init

# Lier à votre projet
supabase link --project-ref your-project-ref

Installation du client​

npm install @supabase/supabase-js
npm install -D @supabase/cli

Variables d'environnement​

NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key

Conception du schéma de base de données​

Conception de tables avec l'IA​

Conçois des tables Supabase pour une application de blog :
- Posts (avec catégories, relation auteur)
- Commentaires (réponses imbriquées)
- Profils utilisateurs (étend auth.users)

Cursor génère le SQL :

-- Activer RLS
alter table auth.users enable row level security;

-- Table des profils
CREATE TABLE profiles (
id uuid references auth.users on delete cascade primary key,
username text unique not null,
avatar_url text,
created_at timestamptz default now()
);

-- Table des posts
CREATE TABLE posts (
id bigint generated always as identity primary key,
title text not null,
slug text unique not null,
content text not null,
status text default 'draft',
author_id uuid references profiles(id) not null,
created_at timestamptz default now(),
updated_at timestamptz default now()
);

-- Table des commentaires
CREATE TABLE comments (
id bigint generated always as identity primary key,
post_id bigint references posts(id) on delete cascade,
parent_id bigint references comments(id) on delete cascade,
author_id uuid references profiles(id),
content text not null,
created_at timestamptz default now()
);

Intégration de l'authentification​

Authentification Next.js​

// lib/supabase.ts
import { createClient } from '@supabase/supabase-js';

export const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);

// middleware.ts
import { createMiddlewareClient } from '@supabase/auth-helpers-nextjs';

export async function middleware(req: NextRequest) {
const res = NextResponse.next();
const supabase = createMiddlewareClient({ req, res });
const { data: { session } } = await supabase.auth.getSession();
return res;
}

Routes protégées​

// app/dashboard/page.tsx
import { createServerComponentClient } from '@supabase/auth-helpers-nextjs';
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation';

export default async function Dashboard() {
const supabase = createServerComponentClient({ cookies });
const { data: { session } } = await supabase.auth.getSession();

if (!session) {
redirect('/login');
}

return <div>Welcome {session.user.email}</div>;
}

Sécurité au niveau des lignes (RLS)​

Génération de politiques​

-- Les utilisateurs ne peuvent voir que leur propre profil
CREATE POLICY "Users can view own profile"
ON profiles FOR SELECT
USING (auth.uid() = id);

-- Les utilisateurs ne peuvent mettre à jour que leur propre profil
CREATE POLICY "Users can update own profile"
ON profiles FOR UPDATE
USING (auth.uid() = id);

-- Les posts publiés sont visibles par tous
CREATE POLICY "Published posts are viewable"
ON posts FOR SELECT
USING (status = 'published');

Abonnements en temps réel​

Abonnement client​

'use client';

import { useEffect, useState } from 'react';
import { supabase } from '@/lib/supabase';

export function RealtimeComments({ postId }: { postId: string }) {
const [comments, setComments] = useState([]);

useEffect(() => {
const channel = supabase
.channel('comments')
.on(
'postgres_changes',
{
event: '*',
schema: 'public',
table: 'comments',
filter: `post_id=eq.${postId}`,
},
(payload) => {
setComments((prev) => [...prev, payload.new]);
}
)
.subscribe();

return () => {
supabase.removeChannel(channel);
};
}, [postId]);

return (
<div>
{comments.map((comment) => (
<div key={comment.id}>{comment.content}</div>
))}
</div>
);
}

Edge Functions​

Création d'une function​

// supabase/functions/process-payment/index.ts
import { serve } from 'https://deno.land/[email protected]/http/server.ts';
import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';

serve(async (req) => {
const { amount, currency } = await req.json();

const supabase = createClient(
Deno.env.get('SUPABASE_URL')!,
Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
);

// Traiter la logique de paiement
const result = await processPayment({ amount, currency });

return new Response(JSON.stringify(result), {
headers: { 'Content-Type': 'application/json' },
});
});

Déploiement​

supabase functions deploy process-payment

Référence rapide​

OpérationCommande/Code
Démarrer l'environnement localsupabase start
Migration de base de donnéessupabase db diff
Générer des typessupabase gen types
Déployer des functionssupabase functions deploy
Voir les logssupabase functions logs

Ressources connexes​

Dernière mise à jour : Juillet 2025