Supabase with Claude Code
Aprenda sobre supabase usando o Claude Code. Dicas praticas e exemplos de codigo incluidos.
Supabase とは
Supabaseはオープンソースのバックエンドプラットフォームです。PostgreSQLデータベース、認証、リアルタイムサブスクリプション、ストレージを統合的に提供します。Claude Codeを使えば、Supabaseの各機能を効率的に実装できます。
セットアップ
// lib/supabase.ts
import { createClient } from "@supabase/supabase-js";
import type { Database } from "./database.types";
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!;
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;
export const supabase = createClient<Database>(
supabaseUrl,
supabaseAnonKey
);
// サーバーサイド用(Service Role Key)
export function createServerClient() {
return createClient<Database>(
supabaseUrl,
process.env.SUPABASE_SERVICE_ROLE_KEY!,
{ auth: { persistSession: false } }
);
}
認証
// メール/パスワード認証
async function signUp(email: string, password: string) {
const { data, error } = await supabase.auth.signUp({
email,
password,
options: {
data: { display_name: email.split("@")[0] },
},
});
if (error) throw error;
return data;
}
async function signIn(email: string, password: string) {
const { data, error } = await supabase.auth.signInWithPassword({
email,
password,
});
if (error) throw error;
return data;
}
// OAuth認証
async function signInWithGitHub() {
const { data, error } = await supabase.auth.signInWithOAuth({
provider: "github",
options: {
redirectTo: `${window.location.origin}/auth/callback`,
},
});
if (error) throw error;
return data;
}
// 認証状態の監視
supabase.auth.onAuthStateChange((event, session) => {
if (event === "SIGNED_IN") {
console.log("Signed in:", session?.user.email);
} else if (event === "SIGNED_OUT") {
console.log("Signed out");
}
});
データベースCRUD
// 型安全なクエリ
async function getPosts(params: {
page?: number;
category?: string;
}) {
const { page = 1, category } = params;
const perPage = 20;
let query = supabase
.from("posts")
.select(`
id,
title,
content,
published_at,
author:users(id, name, avatar),
categories(id, name, slug)
`, { count: "exact" })
.eq("published", true)
.order("published_at", { ascending: false })
.range((page - 1) * perPage, page * perPage - 1);
if (category) {
query = query.contains("categories", [{ slug: category }]);
}
const { data, error, count } = await query;
if (error) throw error;
return { posts: data, total: count };
}
// 挿入
async function createPost(post: {
title: string;
content: string;
}) {
const { data: { user } } = await supabase.auth.getUser();
if (!user) throw new Error("Not authenticated");
const { data, error } = await supabase
.from("posts")
.insert({
title: post.title,
content: post.content,
author_id: user.id,
})
.select()
.single();
if (error) throw error;
return data;
}
リアルタイムサブスクリプション
import { useEffect, useState } from "react";
function useRealtimeComments(postId: string) {
const [comments, setComments] = useState<Comment[]>([]);
useEffect(() => {
// 初期データ取得
supabase
.from("comments")
.select("*, author:users(name, avatar)")
.eq("post_id", postId)
.order("created_at")
.then(({ data }) => setComments(data || []));
// リアルタイム購読
const channel = supabase
.channel(`comments:${postId}`)
.on(
"postgres_changes",
{
event: "INSERT",
schema: "public",
table: "comments",
filter: `post_id=eq.${postId}`,
},
async (payload) => {
// 作者情報を取得
const { data } = await supabase
.from("users")
.select("name, avatar")
.eq("id", payload.new.author_id)
.single();
setComments((prev) => [
...prev,
{ ...payload.new, author: data },
]);
}
)
.subscribe();
return () => {
supabase.removeChannel(channel);
};
}, [postId]);
return comments;
}
ストレージ
async function uploadAvatar(file: File, userId: string) {
const ext = file.name.split(".").pop();
const path = `avatars/${userId}.${ext}`;
const { error: uploadError } = await supabase.storage
.from("profiles")
.upload(path, file, {
upsert: true,
contentType: file.type,
});
if (uploadError) throw uploadError;
const { data } = supabase.storage
.from("profiles")
.getPublicUrl(path);
// プロフィールを更新
await supabase
.from("users")
.update({ avatar: data.publicUrl })
.eq("id", userId);
return data.publicUrl;
}
Row Level Security
-- RLSポリシーの設定
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
-- 公開済み記事は誰でも閲覧可
CREATE POLICY "Public posts are viewable by everyone"
ON posts FOR SELECT
USING (published = true);
-- 自分の記事のみEdit可
CREATE POLICY "Users can update own posts"
ON posts FOR UPDATE
USING (auth.uid() = author_id);
-- 認証済みユーザーのみ作成可
CREATE POLICY "Authenticated users can create posts"
ON posts FOR INSERT
WITH CHECK (auth.uid() = author_id);
Claude Codeでの活用
Supabase開発をClaude Codeに依頼する例です。認証についてはOAuth認証の実装、データベース設計はPrisma ORM完全ガイドも参照してください。
Supabaseでブログアプリのバックエンドを構築して。
- 認証: メール/パスワード + GitHub OAuth
- テーブル: users, posts, comments, categories
- RLSポリシーの設定
- リアルタイムコメント機能
- 画像アップロード機能
Supabaseの詳細はSupabase公式ドキュメントを参照してください。Claude Codeの使い方は公式ドキュメントで確認できます。
Summary
Supabaseは認証からデータベース、リアルタイムまでを統合的に提供するプラットフォームです。Claude Codeを使えば、各機能の実装を効率的に進め、フルスタックアプリケーションを素早く構築できます。
Related Posts
Como Turbinar Seus Projetos Pessoais com o Claude Code [Com Exemplos]
Aprenda a acelerar drasticamente projetos de desenvolvimento pessoal usando o Claude Code. Inclui exemplos reais e um workflow prático da ideia ao deploy.
Como Automatizar Refatoração com o Claude Code
Aprenda a automatizar refatoração de código de forma eficiente usando o Claude Code. Inclui prompts práticos e padrões concretos de refatoração para projetos reais.
Guia Completo de Configuração CORS com Claude Code
Aprenda sobre o guia completo de configuração CORS usando o Claude Code. Dicas práticas e exemplos de código incluídos.