昨日の夜10時、Directusのデプロイを営業資産に変えるという漠然としたアイデアがあった。今朝の午前7時には、Railway上で動作する管理画面、3つのライブダッシュボード、5つの投稿を備えた公開デモブログ、サービス全体をピッチする2,400語の営業ピラー、そして真夜中に検出して修正した本番環境バグ3件を手に入れていた。インフラストラクチャの総コスト:月額5ドル。総所要時間:1晩と翌朝に分散した、およそ9時間の集中作業。
これがそのケーススタディだ。何が構築されたか、何が壊れたか、何を学んだか、そしてビルドの背後にある実際の数字。同様のプロジェクトをビジネスのために発注すべきかどうかを評価している場合、以下のデータポイントが私が提供できる最も誠実なリファレンスだ。
目指したこと
優先順位順に3つの目標。
1番目は、既存のSupabase Postgresデータベースに接続したDirectusをデプロイすることだ。目標:カスタムAstro管理画面が既に管理しているのと同じデータを指す、ジェネリックなCRUD管理画面。理由:カスタム管理画面(チームが好むMonday風のインラインエディタを備えている)を置き換えることではなく、カスタム管理画面にはない運用レイヤーを追加することだ。一括編集、保存済みビュー、ロールベースの権限、スキーマブラウザ、Insightsダッシュボード。
次に、6ヶ月間欲しかったダッシュボードをセットアップする。3つのボード:コンテンツパイプライン(ブログ公開速度、トピックキュー深度)、SEOヘルス(ランク順位、AI Overview掲載率、インテント分布)、ツール使用(AEOツール検索、ブランド名ツール検索、アドバイザー使用)。月曜日に一目で確認できるコンクリートな数字で、エンジンが正常に動作しているかどうかを知る。
3番目に、全体のビルドをセールスアセットに変える。私自身がデプロイするDirectusアドミンは、クライアント向けにデプロイするものと全く同じだ。つまり、デプロイ自体がデモになる。見込み客は私のセールスページのボタンをクリックして、実データが入った本物のDirectusアドミンにアクセスし、リッチテキストエディタに入力して、保存されたビューの動作を確認し、その後コールを予約するために戻ってくる。デモループの総摩擦:ページランドからライブエディタまで約15秒。
0〜4時間:デプロイ
Railway hobby plan、公式Directusテンプレート、ワンクリックデプロイ。テンプレートはDirectus、Redis、バンドルされたPostGISデータベース、S3互換ストレージバケットを搭載している。設定を含む総デプロイ時間:空のRailwayアカウントからログイン済みアドミンまで35分。
最初の驚き:Directusテンプレートはそのデータベース接続を個別のhost/port/user/passwordフィールドではなく、バンドルされたPostGISサービスを指す参照変数経由で配線している。Directusを外部のSupabase Postgresにリダイレクトするために、接続文字列変数(DB_CONNECTION_STRING)を見つけて、認証情報付きのSupabase Session pooler URLを貼り付ける必要があった。
2番目の驚き:私のSupabaseデータベースパスワードに「#」という文字が含まれていた。Postgres接続文字列では%23としてURLエンコードされる。エンコードがないと、URLパーサーは#がURL fragmentを意味するため、文字列をそこで切る。接続文字列が不正だったため、DirectusはECONNREFUSED::1:5432をログに記録して、localhostにフォールバックした。30分間混乱してから、パスワードを英数字のみにローテーションして、接続が確立された。
Directusが接続された後、Supabaseデータベースの12テーブルがすべてDirectus Collectionsとして自動インポートされた。スキーマ移行ゼロ、データ移行ゼロ、ダウンタイムゼロ。カスタムAstroアドミンとDirectusアドミンの両方が同じデータを見て、両方がそれに書き込み、両方が互いの変更を即座に反映する。
4〜12時間:設定、設定、設定
作業のほとんどはデプロイではなく、Directusが生のデータベースブラウザではなく磨かれたアドミンとして機能するようにするためのフィールドレベルの設定だった。すべての列にはインターフェースメタデータ、表示フォーマット、ソート順序、幅、グループ、可視性の決定が必要だ。デフォルトのDirectusは全て表示;磨かれたバージョンはチームが必要なものだけを表示する。
このフェーズからの3つの観察。
Directus管理UIをクリックで操作するのは遅い。フィールドあたり約2分、12個のコレクション全体で90個以上のフィールド、総クリック時間は3時間近い。ブラウザ駆動AI Agent(ChromeのClaude)に委譲し、Directus REST APIで一括設定に切り替えた。Agentは PATCH /fields/{collection}/{field} 呼び出しを順序立てて実行し、フルメタオブジェクトをペイロードとして送信した。コレクションあたり3分(従来は40分)。設定フェーズ全体は3時間から40分に圧縮された。
REST APIアプローチにより再現性も確保できた。すべてのPATCHはcurl相当で、新しいDirectusデプロイに対して実行し直して同じ設定を復元できる。設定は実質的にコードになり、脆弱なUIクリックの山ではなくなった。
このフェーズの最後の4分の1は、3つのInsightsダッシュボード構築だった。各パネルはPOST /panelsに送信するJSON設定。フィールドメタデータが配置されれば、ダッシュボードはおおよそ20分で完成した。3ボード、6パネル、実データレンダリング。6ヶ月間推測していた数字がついに画面に表示された。
時間12~18:最も時間がかかった3つのバグ
本当のビルドは本番環境で壊れるまで本当ではない。mainにシップして本番サイトをリフレッシュした後、3つのバグが浮き出た。
Bug 1:CSPでブロックされたSplineシーン、3つ積み重なった原因
3D-firstウェブピラー(Spline NEXBOTロボットヒーロー)もシップした。デプロイ後、本番ではロボットが見えなくなったがローカルでは動作した。3つの積み重なった問題が順序立てて発生した。
その1:define:varsを使用するscriptタグはAstroにインライン化され、これは Vite が @splinetool/viewer の動的インポートをバンドルしなかったことを意味し、ベアモジュール指定子がブラウザで解決不可能になった。その2:それを修正後、spline-viewerエレメントはアップグレード時にhidden属性を持つ親の内部にあったため、Litカスタムエレメントは0x0寸法で初期化され回復しなかった。その3:それを修正後、Splineビューアはシーン読み込み時にunpkg.comからモデリングWASMをフェッチするが、私のCSPはそれをホワイトリストしていなかった。各修正が次のバグを浮き出させた。総デバッグ時間:90分。
本番環境のみのデバッグはそれ自体が専門分野だ。開発サーバーは本番ビルドとは異なる方法でベアインポートを解決する。開発環境はより許容的なデフォルトCSPを持つ。どちらのバグもローカルで完璧に動作している状態では浮き出す不可能だった。教訓:ローカルが正常に機能していても、実環境への早期シップが重要だ。
Bug 2:AI OverviewブーリアンとPostgres avg()
あるInsightsパネルが「追跡しているSERPラン中、AI Overviewが表示される割合は何パーセントか」を表示したかった。seo_serp_runsテーブルにはai_overview_presentというboolean列がある。素朴な直感:その列をavg()して100を掛け、パーセンテージとしてレンダリング。
Postgresはavg(boolean)でエラーを投げる。その型に対して関数は存在しない。複数の回避策を試したが失敗:Directusは「percentage」aggregateを公開していない、trueのカウントにハードコードされた分母を使う方法はより多くの行が入ってくると狂う、クエリ時点でのキャストはInsightsパネルのオプションを通じて公開されていない。
うまくいった修正:ai_overview_present_intという生成列を追加し、case when ai_overview_present then 100 else 0 endとして計算する。整数列に対するavg()は簡単に機能し、パーセンテージを直接生成する。一行のSQLマイグレーション、アプリケーションコードの変更はゼロ。
Bug 3:CSP内の画像ホスト
デモブログに5つのUnsplash写真URLをシードした。ブラウザはimg-srcでimages.unsplash.comをホワイトリストに登録していなかったため、それらを静かにブロックした。公開デモブログ上に真っ黒なカード画像が表示された。UnsplashをCSPに追加すると画像がレンダリングされたが、その時点でSupabase Storageにすべての画像についてFALを使うという自分自身の譲れないルールに違反していることに気づいた。
正しい修正:すべてのdemo_postsの行を取得し、FAL flux-pro/v1.1-ultraでカテゴリーごとの編集用写真を生成し、sharpでWebPに品質82、最大幅1600でエンコード、公開Supabase Storageバケットにアップロード、featured_imageをストレージCDN URLに更新するスクリプト。ビルドに20分、5つのFAL生成コストは1ポンド未満。UnsplashをCSPから削除。画像は独自のインフラに存在し、外部依存なし、ホストごとのCSP更新の綱渡りはもう今後ない。
18時間目から24時間目:セールスの柱
Directusが動作し、デモブログが正しくレンダリングされるようになり、/solutions/headless-cms-and-admin-tools/でセールスの柱を書いた。4つのサービスティア(CMS、社内オペレーション管理、ディレクトリ、カスタム)、USDで価格設定(括弧内はGBP)、6つのFAQ、WordPressとHubSpotとNotionとAirtableとの比較表、間違った形の顧客を早期に除外する「受けない案件」セクション。
この柱は直接ライブデモにリンクしている。「OPEN THE EDITOR」をクリックした見込み客は実際のDirectus管理画面に着地し、貼り付けた認証情報が表示される。数秒後、彼らは実際のエディタで実際の投稿を編集している。デモループはページ着地からライブ編集まで15秒。
柱ページ全体の時間:90分の執筆と30分のスキーママークアップ、内部リンク、ビジュアルポリッシュ。ページ自体は3つのバグ中2つにかかった時間より短かった。
数字
構築コスト内訳。これはケーススタディ投稿であり、見込み客が質問する内容だからだ。
Railway Hobby プランfor Directus + Redis + bucket:月額 $5、月次請求。最初の 30 日間は無料。
Supabase Postgres:既存インフラ、新たなコストなし。Pro プランを既に使用しており、データベースは月額およそ $25。
FAL API(5 つのヒーロー画像用):合計 1 ポンド未満、およそ $1 USD。
DataForSEO(42 キーワードの検索ボリューム + インテント + 難易度でバックフィル):合計 $0.04。
私の時間、バグと執筆を含むエンドツーエンド:9 時間の集中作業。コンサルティング日給がおよそ $1,500 / 日なので、機会費用はおよそ $1,700。
動作する営業資産をリリースするための総現金支出:周辺インフラがおよそ $6 + API 費用が $1。時間を含む真のコスト:およそ $1,700。
参考比較:「ヘッドレス CMS 管理ツール構築」エンゲージメントを見積もるエージェンシーは、同等のスコープに対して通常 $8,000~$15,000 USD を請求する。私自身のサービスページでは $8,000~$19,000 USD を請求している。構築コストと販売価格のギャップが、エージェンシー事業の経済エンジン全体だ。このケーススタディは、構築コストの数字が実在することの証明である。
見込み客に対してこれが証明すること
3つのこと。すべて次の10分以内に検証できます。
第一に、ビルドは実在します。セールスページのOPEN THE EDITORボタンをクリックしてください。リッチテキストエディタに入力してください。投稿をスケジュール設定してください。ダッシュボードを見てください。このものは存在します。モックアップではなく、Figmaファイルでもなく、スクリーンショットでもありません。それはあなたのビジネスのためにデプロイするのと同じソフトウェアです。
第二に、速度は実在します。「漠然としたアイデア」から「本番環境にデプロイされた営業資産とライブデモ」まで、24時間です。クライアントエンゲージメントはこのスピードで動きません。なぜならクライアントエンゲージメントには、ディスカバリー、デザインレビュー、ステークホルダー承認、セキュリティ監査が含まれるからです。しかし、6週間のタイムラインが正直なのか楽観的なのかを決定するのは、基礎となるビルド速度です。24時間のソロビルド作業は、オーバーヘッドを含めると標準的なエージェンシーエンゲージメント時間の約3週間に相当します。その計算が6~8週間のティア1タイムラインを生み出すのです。
第三に、障害モードは実在します。3つの本番環境バグがリアルタイムで検出され、修正されました。CSP問題、ダイナミックインポートバンドリング、生成カラムの計算。これらは、クライアントエンゲージメントで発生するのと同じバグです。ライブサイトでそれらを検出し、解決したという事実は、能力の実際のデモです。バグのない磨かれたケーススタディのほうが、疑わしいものだったでしょう。
私が異なることをしたであろうこと
3つの小さな反思。有用性の順序で。
Unsplashの回避策の前にFALイメージ生成スクリプトで開始すべきでした。CSP更新後の巻き戻しダンスは、不要な混乱で10分を消費しました。FALイメージについての譲歩できないルールは、まさにこの理由のためにあり、私は最初に耳を傾けるべきでした。
最初からUI クリックスルーを試すのではなく、Directus設定にREST APIアプローチを使用すべきでした。エージェント駆動型のREST呼び出しシーケンスは3倍高速で、再現可能な設定を生成しました。この教訓はDirectusを超えて一般化されます。包括的なREST APIを公開する管理者は、そのUIを通じてではなく、そのAPIを通じて設定されるべきです。
ケーススタディポストをもっと早く書くべきでした。このポストはビルド完了の約12時間後に書かれています。私がこれを書いている時点で、いくつかの障害モードはすでに記憶から薄れています。正直なケーススタディは、バグがまだ正確に説明するのに十分新鮮なままである同じ日のうちに書かれるものです。
次にどこへ行くか
自社でも同様のビルドを委託すべきか検討しているのであれば、デモループが最速で実用的な答えにたどり着く方法です。/solutions/headless-cms-and-admin-tools/ を開き、デモボタンをクリックして、表示されている認証情報でログインし、15分間クリックして回ってください。その終わりには、このツールの形状がチームに適しているかどうかが明確に見えるようになります。
はい、ならば、そのページにリンクされている30分間のコールを予約してください。既存のスタック、チームサイズ、データ形状を教えてください。コール終了時には、ティアの選択、価格帯、納期が決まります。引き受けるエンゲージメントの大半は6~12週間で8,000~50,000米ドルの範囲です。引き受けないものについては、コール中に理由を説明します。
フル営業ピッチが必要な場合、柱ページは /solutions/headless-cms-and-admin-tools/ にあります。ライブデモに直接進みたい場合、認証情報はそのページにあります。次のケーススタディが必要な場合、次のブログ投稿はアジア回廊メーカービルド、または同じパターンを別の業界に適用したものについて扱う予定です。どちらがより有用かお知らせください。
