顧客に納品しているホームページの機能(ブログ・予約・LINE連携など)を、顧客ごとに管理する社内CMSを、Claude Codeと作りました。その設計で何度も効いたのが、「これは作らない」と一言で決められる状態にしておくことでした。
最初の問い: マルチテナントにするか
最初に投げたのは、設計の相談です。
顧客(美容室・整体院など数十件)ごとにホームページを納品している。ブログ・予約・LINE連携などの機能を顧客ごとにON/OFFして提供したい。1つのLaravelアプリで全顧客を管理するマルチテナントにすべきか、顧客ごとに別のアプリをデプロイすべきか。判断材料を整理してほしい。
返ってきた整理の、決め手になった2点は次のとおりです。
- デザインの個別性: 小規模店舗向けの制作は、案件ごとにデザインが大きく違う。共通テーマで吸収しようとすると、テーマ機構の開発だけで数週間かかる
- ホスティング費用: 個別デプロイなら、顧客のレンタルサーバー(さくら等)に置けて、費用は顧客持ちにできる
Claude Codeの結論は、次のものでした。
テンプレートリポジトリを案件ごとに複製して個別デプロイし、社内CMS側は「どの顧客にどの機能を納品したか」の台帳として持つ。機能のライブ切り替えは顧客サイト側で行う。
私は「その方針で。社内CMSは台帳、店舗サイトのほうは複製して使う雛形、機能のライブ切り替えは顧客サイト側」と一言返しただけです。
「台帳」とは、制御しないということ
社内CMSのfeatures / customer_featuresテーブルは、顧客サイトの機能を制御しません。あくまで「この顧客のサイトには、予約機能とLINE連携を納品済み」という記録です。
// app/Services/FeatureLedgerService.php
/**
* 顧客への機能の納品状況を記録する(顧客サイト本体の動作は切り替えない、社内台帳の更新のみ)。
*/
public function setStatus(Customer $customer, Feature $feature, array $data): CustomerFeature
{
return CustomerFeature::updateOrCreate(
[
'customer_id' => $customer->id,
'feature_id' => $feature->id,
],
[
'is_enabled' => $data['is_enabled'],
'delivered_at' => $data['delivered_at'] ?? null,
'notes' => $data['notes'] ?? null,
]
);
}
コメントに「顧客サイト本体の動作は切り替えない」と書いてあります。サービスの中身は、updateOrCreateが1回だけです。
それでもAIは作ろうとする
これを最初に明確にしておかないと、Claude Codeは、親切心で「社内CMSからAPIで顧客サイトの機能をON/OFFする仕組み」を作り始めます。実際、一度それが要点整理に含まれてきたことがありました。
私は「台帳。ライブ切り替えはしない」と一言で却下しました。理由は単純で、顧客数が数十件で、機能の追加・削除が起きるのは、契約変更のときだけだからです。年に数回の操作のために、顧客サイトから社内CMSへの常時通信を設計する意味がありません。
AIは「何を作らないか」を知りません。要件が少しでも曖昧だと、あれば便利そうなものを足してきます。足すのは、悪いことではありません。ただ、小さなシステムでは、足した分がそのまま保守の負担になります。
「一言で却下」できるようにしておく
一言で止められたのは、READMEの冒頭に役割分担を書いてあったからです。
- 機能管理(features / customer_features) ※顧客サイトの機能ON/OFFの「納品記録台帳」。
ライブ切り替えは顧客サイト側で行う
READMEにこの前提があるので、どのセッションでも、Claude Codeは最初にそれを読みます。「社内CMSにブログ機能を作って」と誤って頼んでも、「ブログは顧客サイト側の機能なので、雛形のほうに実装すべきです」と返ってくるようになりました。
例外は、1つだけにする
「原則は台帳」ですが、例外が1つあります。Instagram連携です。Meta側のアプリ登録・審査を顧客ごとにやるのは非現実的なので、社内CMSが1つのMetaアプリとして、全顧客のInstagram投稿を中継します。
「原則は台帳、例外は、外部サービスの中継が必要な機能だけ」という線引きにしておくと、あとで迷ったときの基準になります。
まとめ
- 設計の相談では、選択肢を並べてもらい、決め手の観点(今回はデザインの個別性とホスティング費用)で選ぶ
- 「制御しない」ものは、コメントとREADMEに「しない」と書く。AIは、書いていないことは、親切心で足してくる
- 却下は、理由を1文で添えれば一言で済む(今回は「年に数回の操作のため」)
- 例外は、基準を決めて、数を絞る
この記事はZennにも投稿しています。