Claude Codeでマルチテナント設計を実装する
Claude Codeを活用して、データ分離・テナント管理・アクセス制御を備えたマルチテナントアプリケーションを構築する方法を解説します。
マルチテナント設計をClaude Codeで実装する
SaaSアプリケーションではマルチテナント設計が不可欠です。テナント間のデータ分離、テナント固有の設定管理、アクセス制御をどう実現するかが重要な設計判断となります。Claude Codeを使えば、適切なマルチテナントパターンを一貫性のあるコードで実装できます。
テナント分離パターンの選択
主なアプローチは3つあります。
- 行レベル分離: 全テナントが同じテーブルを共有し、
tenantIdカラムでフィルタリング - スキーマ分離: テナントごとに別のDBスキーマを使用
- DB分離: テナントごとに独立したデータベース
Claude Codeに設計判断を相談することもできます。
> SaaSアプリのマルチテナント設計について相談したい。
> 想定テナント数は1000程度、各テナントのデータ量は中程度。
> 行レベル分離で実装して、テナントIDによるフィルタリングを
> ミドルウェアで自動化して。
テナント解決ミドルウェア
// src/middleware/tenant.ts
import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
export async function resolveTenant(request: NextRequest) {
// サブドメインからテナントを解決
const hostname = request.headers.get('host') || '';
const subdomain = hostname.split('.')[0];
// カスタムドメインの場合
const tenant = await prisma.tenant.findFirst({
where: {
OR: [
{ subdomain },
{ customDomain: hostname },
],
isActive: true,
},
});
if (!tenant) {
return NextResponse.json({ error: 'テナントが見つかりません' }, { status: 404 });
}
// リクエストヘッダーにテナントIDを注入
const headers = new Headers(request.headers);
headers.set('x-tenant-id', tenant.id);
return NextResponse.next({ request: { headers } });
}
テナントスコープ付きPrismaクライアント
// src/lib/tenant-prisma.ts
import { PrismaClient } from '@prisma/client';
export function createTenantPrisma(tenantId: string) {
const prisma = new PrismaClient().$extends({
query: {
$allModels: {
async findMany({ args, query }) {
args.where = { ...args.where, tenantId };
return query(args);
},
async findFirst({ args, query }) {
args.where = { ...args.where, tenantId };
return query(args);
},
async create({ args, query }) {
args.data = { ...args.data, tenantId };
return query(args);
},
async update({ args, query }) {
args.where = { ...args.where, tenantId };
return query(args);
},
async delete({ args, query }) {
args.where = { ...args.where, tenantId };
return query(args);
},
},
},
});
return prisma;
}
テナント設定の管理
// src/services/tenant-settings.ts
interface TenantSettings {
branding: {
primaryColor: string;
logo?: string;
companyName: string;
};
features: {
maxUsers: number;
storageLimit: number;
apiAccess: boolean;
};
notifications: {
emailEnabled: boolean;
slackWebhook?: string;
};
}
export class TenantSettingsService {
async getSettings(tenantId: string): Promise<TenantSettings> {
const tenant = await prisma.tenant.findUnique({
where: { id: tenantId },
select: { settings: true, plan: true },
});
// プランに基づくデフォルト設定とカスタム設定をマージ
const planDefaults = getPlanDefaults(tenant!.plan);
return { ...planDefaults, ...tenant!.settings } as TenantSettings;
}
async updateSettings(tenantId: string, updates: Partial<TenantSettings>) {
return prisma.tenant.update({
where: { id: tenantId },
data: { settings: updates },
});
}
}
データ分離テストの重要性
マルチテナント実装では、テナント間のデータ漏洩を防ぐテストが非常に重要です。Claude Codeに「テナントAのデータがテナントBからアクセスできないことを確認するテスト」を依頼して、十分なカバレッジを確保しましょう。
関連リソース
ロールベースのアクセス制御はRBAC実装ガイド、データベース設計はデータベースマイグレーションを参考にしてください。
PostgreSQLの行レベルセキュリティ(RLS)についてはPostgreSQL公式ドキュメント(postgresql.org/docs)をご覧ください。
無料PDF: Claude Code はじめてのチートシート
まずは無料PDFで基本コマンドと最初の使い方をまとめて確認してください。登録後はそのままテンプレート集や導入相談にも進めます。
スパムは送りません。登録情報は厳重に管理します。
Claude Codeを仕事で使える形にしませんか?
無料PDFで基礎を固めたあと、すぐ使えるテンプレート集で試し、必要なら業務自動化や導入相談まで進められます。
この記事を書いた人
Masa
現役DX室長|Claude Code でゼロから多言語AI技術メディア運営中。実務直結の自動化、AI開発相談・研修受付中。
関連書籍・参考図書
この記事のテーマに関連する書籍を楽天ブックスで探せます。
※ 当サイトは楽天市場のアフィリエイトプログラムに参加しています。上記リンクから商品をご購入いただくと、運営者に紹介料が支払われる場合があります。
関連記事
Claude Codeで多言語記事を毎日公開するための7つのデプロイ前チェック
日本語だけ公開して終わらせないために、Claude Codeで多言語記事を毎日出す前に確認したい7つのチェックを実例つきで整理しました。
Codex AutomationsでAIに毎日のコンテンツ運用を任せる方法
Codex Automationsを使って、アクセス確認、記事改善、CTA改善、デプロイ、公開確認までを毎日の運用フローとして回す方法を解説します。
Claude Code × GCP Cloud Functions 完全ガイド|サーバーレス関数を爆速開発
GCP Cloud FunctionsをClaude Codeで効率化。HTTP/Pub/Sub/Firestoreトリガーの実装からローカルテスト・デプロイ自動化まで、Masaの実務経験をもとに実例コードで解説。