PolarDB Supabase は、PolarDB for PostgreSQL が提供するフルマネージドな Supabase サービスです。このサービスは、PolarDB for PostgreSQL を活用し、リアルタイムデータベース、RESTful API、GoTrue 身分認証、ファイルストレージ、およびログ収集などの主要機能を統合しています。また、Supabase における複雑なパラメーター管理およびアプリケーションの運用および保守 (O&M) を不要にすることを目的として最適化・強化されており、柔軟でパフォーマンス専有型のバックエンドソリューションを提供します。PolarDB Supabase を使用することで、Web アプリケーション、SaaS プラットフォーム、AI 統合アプリケーションなどのモダンなアプリケーションを迅速に構築できます。
本セクションでは、PolarDB Supabase を使用して会議メモシステムを迅速に構築する方法について説明します。
主な特徴
特徴 | 説明 |
完全なデータベース機能 | Supabase は PolarDB for PostgreSQL 上に構築されており、以下の完全なデータベース機能を提供します:
|
リアルタイムサブスクリプション | PostgreSQL の論理レプリケーションに基づくリアルタイムデータ同期を実現します:
|
身分認証(Auth) | 組み込みの包括的な身分認証および権限付与システムです:
|
行レベルセキュリティ(RLS) | PostgreSQL に基づく行レベルセキュリティポリシーです:
|
ストレージサービス | PolarDB ファイルシステムに基づくファイルストレージおよび管理機能です:
|
Edge Functions | Deno を基盤とするサーバーサイド関数です:
|
API(REST & GraphQL) | 自動生成される API オペレーションです:
|
会議メモシステムの構築
会議メモシステムでは、主に以下の機能を使用します:
特徴 | 説明 |
データストレージ。主に会議、メモ、タスク、ユーザー状態などのテーブル情報を記録します。 | |
コラボレーション機能。メモの共同編集およびユーザーのオンライン状態をリアルタイムで同期します。 | |
データセキュリティ。ユーザーのアクセス権限を制御します。 | |
ファイル管理。会議資料のアップロードおよびダウンロードを行います。 | |
ユーザー管理。ユーザーのログインおよびセッション管理を行います。 |
アプリケーション技術スタック
フロントエンド:Next.js 15 + React 18 + TypeScript。
バックエンド:PolarDB Supabase(PostgreSQL + 認証 + リアルタイムサブスクリプション + ストレージ)。
UI:Tailwind CSS + Radix UI。
状態管理:React Hooks + ローカル状態。
データベース設計
会議メモシステムの主な機能(会議テーブル、メモテーブル、ユーザーのオンライン状態テーブル、タグテーブル、タスクテーブルなど)に対応するシステムテーブルを設計できます。データ整合性を保証するために外部キー制約を使用します。
リアルタイムサブスクリプションの構成
リアルタイム機能の有効化
-- リアルタイムサブスクリプション機能を有効化
ALTER PUBLICATION supabase_realtime ADD TABLE meetings;
ALTER PUBLICATION supabase_realtime ADD TABLE notes;
ALTER PUBLICATION supabase_realtime ADD TABLE user_presence;
ALTER PUBLICATION supabase_realtime ADD TABLE tags;
ALTER PUBLICATION supabase_realtime ADD TABLE tasks;
ALTER PUBLICATION supabase_realtime ADD TABLE meeting_activities;
ALTER PUBLICATION supabase_realtime ADD TABLE meeting_files; クライアント側のリアルタイムサブスクリプション
// リアルタイムサブスクリプションを管理するカスタム Hook の作成
export function useRealtime(meetingId: string, callbacks: RealtimeCallbacks) {
const channelsRef = useRef<any[ ]>([ ])
const cleanup = useCallback(() => {
channelsRef.current.forEach((channel) => {
supabase.removeChannel(channel)
})
channelsRef.current = []
}, [])
useEffect(() => {
if (!meetingId) return
// 以前の接続をクリーンアップ
cleanup()
// 複数の専用チャネルを作成
const presenceChannel = supabase
.channel(`presence:${meetingId}`)
.on(
"postgres_changes",
{
event: "*",
schema: "public",
table: "user_presence",
filter: `meeting_id=eq.${meetingId}`,
},
(payload) => {
console.log("ユーザーのオンライン状態の変更:", payload)
if (callbacks.onUserPresenceChange) {
loadOnlineUsers()
}
},
)
.subscribe()
// クリーンアップ用にチャネル参照を保存
channelsRef.current = [presenceChannel, /* その他のチャネル */]
}, [meetingId, callbacks])
return { cleanup }
}
リアルタイムサブスクリプションの設計ガイド
機能の分離:オンライン状態、文書共同編集、タスク通知など、ビジネスシナリオごとに独立したチャネルを分割し、論理的な結合を回避します。
イベントフィルタリング:
filterパラメーター(例:会議 ID の指定)を活用してイベント範囲を限定し、冗長なデータ送信を削減します。リソースの解放:コンポーネントのアンインストールまたはページ遷移時に、
removeChannelを明示的に呼び出してすべてのチャネル接続をクリーンアップし、リソースを解放します。エラー処理:サブスクリプションチャネルのステータスを監視し、切断、タイムアウト、その他の例外発生時に再試行または段階的な機能縮小(degrade gracefully)を実施します。
セキュリティ
行レベルセキュリティ(RLS)
-- RLS の有効化
ALTER TABLE meetings ENABLE ROW LEVEL SECURITY;
-- セキュリティポリシーの作成
CREATE POLICY "ユーザーはすべての会議を参照可能" ON meetings
FOR SELECT USING (true);
CREATE POLICY "ユーザーは会議を作成可能" ON meetings
FOR INSERT WITH CHECK (true);
CREATE POLICY "ユーザーは自身の会議のみ更新可能" ON meetings
FOR UPDATE USING (auth.uid() = created_by);
ユーザー認証
const login = useCallback(async (email: string, password: string) => {
try {
const { data, error } = await supabase.auth.signInWithPassword({ email, password })
if (error) throw error
if (data.user) {
const userData = transformSupabaseUser(data.user)
setUser(userData)
localStorage.setItem("meeting_user", JSON.stringify(userData))
return { success: true, user: userData }
}
return { success: false, error: 'ログインに失敗しました' }
} catch (error: any) {
return { success: false, error: error.message || 'ログインに失敗しました' }
}
}, [])
const transformSupabaseUser = (supabaseUser: SupabaseUser): User => ({
id: supabaseUser.id,
email: supabaseUser.email || null,
name: supabaseUser.user_metadata?.name || supabaseUser.email?.split('@')[0] || 'ユーザー',
avatar_url: supabaseUser.user_metadata?.avatar_url || null,
created_at: supabaseUser.created_at,
is_anonymous: supabaseUser.user_metadata?.is_anonymous || false,
})
クライアント統合
クライアント構成
// lib/supabase.ts
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
// 型定義
export interface Meeting {
id: string
created_at: string
title: string
description: string | null
}環境変数の管理
# 本番環境の環境変数
NEXT_PUBLIC_SUPABASE_URL=<YOUR_SUPABASE_PUBLIC_URL>
NEXT_PUBLIC_SUPABASE_ANON_KEY=<YOUR_SUPABASE_ANON_KEY>クイックセットアップ
サンプルプロジェクトコードのダウンロード: PolarDB-Supabase-App-Demo。
実行環境の準備: サンプルプロジェクトコードを実行するには、ご利用のローカル環境に
Node.jsおよびpnpmがインストールされている必要があります。説明Node.js: 公式Node.jsウェブサイトからダウンロードしてインストールできます。pnpm:Node.jsをインストールした後、npmを使用してpnpmをグローバルにインストールできます。コマンドはnpm install -g pnpmです。
環境構成: プロジェクトのルートディレクトリに
.env.localファイルを作成し、以下の値をご利用の PolarDB Supabase 構成情報に置き換えてください。説明クラスターの リストページで、ご利用の Application ID をクリックすると、アプリケーション詳細ページに移動します。Topology タブおよび Configuration タブで関連する構成情報を確認できます。
<YOUR_SUPABASE_PUBLIC_URL>はアプリケーションの パブリックネットワークアドレス です。<YOUR_SUPABASE_ANON_KEY>はアプリケーションパラメーターsecret.jwt.anonKeyの値です。
# Production environment variables NEXT_PUBLIC_SUPABASE_URL=<YOUR_SUPABASE_PUBLIC_URL> NEXT_PUBLIC_SUPABASE_ANON_KEY=<YOUR_SUPABASE_ANON_KEY>データベースの初期化: プロジェクトのルートディレクトリにある
scriptsフォルダ内に01-create-tables.sqlファイルがあります。この SQL を Supabase Dashboard の右側ナビゲーションウィンドウにある SQL Editor で実行してください。
プロジェクトの実行: プロジェクトのルートディレクトリで以下のコマンドを実行して依存パッケージをインストールし、プロジェクトを起動できます。起動後、デフォルトのローカルアクセスアドレスは
http://localhost:3000です。ご利用のブラウザから直接システムにアクセスできます。pnpm install pnpm dev
概要
会議メモシステムプロジェクトから得られた実践的な経験に基づき、PolarDB Supabase のベストプラクティスには以下が含まれます。
データベース設計: 合理的なテーブルスキーマ、インデックス、および制約。
リアルタイムサブスクリプション構成:関心の分離、リソース管理、エラー処理。
セキュリティ:RLSポリシー、データ検証、ユーザー認証。
デプロイメントとメンテナンス:環境構成、移行。
これらのベストプラクティスに従うことで、安定した、安全な、高性能なPolarDB Supabase アプリケーションの構築に役立ちます。