~/VibeHandbook
$39

12 · 02

ケーススタディ2: 認証 + データベース付きの小さなSaaSツール

アイデア

あるフリーランスのデザイナーが、クライアントごとに請求対象の時間を記録し、月次でCSVをエクスポートできる、プライベートなダッシュボードを欲しがっていました。凝ったものではありませんが、アカウント(彼女のデータが彼女だけのものになるように)と永続化が必要でした。

仕様

認証とデータベースはリスクを高めるので、仕様は境界についてより具体的になりました。

ログイン後のWebアプリで、ユーザーは次のことができる: メールで
サインアップ/ログインする、クライアントを作成する、時間エントリ
(日付、クライアント、時間数、メモ)を記録する、月で絞り込んだ
エントリのテーブルを見る、その月をCSVとしてダウンロードする。
各ユーザーは自分のデータしか決して見られない。モバイル対応。

「各ユーザーは自分のデータしか決して見られない」はUXの一行に見えます。それは実際には、アプリ全体のセキュリティモデルを十数語に圧縮したものです。仕様でそれに名前を付けておいたおかげで、AIが逸れるたびにそこへ立ち返って指し示すことができました。

スタック

個人開発者にとっての勝ち筋は、認証とデータベースが自分で書くコードではなくマネージドサービスであるスタックです。私たちはサーバーレスホストにデプロイするNext.jsアプリを選び、ホストされたPostgresデータベースと、メールログイン・セッション・パスワードリセットを代わりに処理してくれるドロップイン型の認証プロバイダーを組み合わせました。間違えうるコードが少ないほど、AIが私たちに代わって間違えうるコードも少なくなります。とりわけ認証は、AIと一緒に自前で組みたいとはほとんど思わない部類です。失敗の仕方が静かで、被害範囲が全員のアカウントに及び、マネージドプロバイダーは何百万回ものログインでエッジケースを叩かれてきたからです。

鍵となったプロンプト

重い処理は認証プロバイダー自身のテンプレートに任せ、その上にドメインロジックを重ねるようAIを指揮しました。

私たちは[認証プロバイダー]のNext.jsスターターを使っている。
2つのテーブルを持つPostgresスキーマを追加して: clients
(id, user_id, name) と time_entries (id, user_id, client_id,
date, hours, note)。すべてのクエリはセッションのログイン
ユーザーのidで絞り込まなければならない(MUST)。マイグレーションと
型付きのデータアクセス関数を生成して。

「user_idで絞り込まなければならない(MUST)」の一行は、プロジェクト全体で最も重要な文でした。私たちはデータに触れるほぼすべてのプロンプトでこの制約を繰り返しました。マルチユーザーアプリで最も恐ろしいバグは、あるユーザーが別のユーザーの行を見てしまうことだからです。打ち込んでいるときは反復が冗長に感じられます。しかしまさにその冗長さがあなたを救うのです。モデルは別々のプロンプトをまたいで、その制約がどれほど重要かを覚えていないからです。

エクスポートについては次のとおりです。

/api/export ルートを追加して。月(YYYY-MM)を受け取り、ログイン
ユーザーのその月の time_entries をクライアント名と結合して取得し、
CSVダウンロードをストリームする。有効なセッションが無ければ
リクエストを拒否する。

障害

テスト中、私たちは2つのアカウントを作り、アカウントBがドロップダウンでアカウントAのクライアントを見られることを発見しました。これこそ私たちが恐れていたバグです。AIに「直して」と頼むのではなく、まず問題を証明させました。

アカウントBがアカウントAのクライアントを見ている。コードベースの
中で clients テーブルを読むすべてのデータベースクエリを見せて。
そして各クエリについて、セッションの user_id で絞り込んでいるか
どうか教えて。まだ何も直さないで — 監査だけして。

監査により、1つのクエリ(ドロップダウンのローダー)が浮かび上がりました。それは制約を追加する前に書かれていて、すり抜けていたのです。私たちは欠けていた絞り込みを追加させ、それからガードを頼みました。

すべての読み取りが通る単一のヘルパーを追加して。セッションを受け取り、
user_idの絞り込みを注入することで、今後どのクエリも忘れられない
ようにする。既存のクエリをそれを使うようリファクタリングして。

これにより、一度きりの修正が構造的な保証に変わりました。それから私たちはその保証をテスト可能にしました。検証できないガードはただの願望にすぎないからです。

2人のユーザーを作り、それぞれにクライアントを1つ作らせてから、
ユーザーAのセッションがどのデータアクセス関数を通しても
ユーザーBのクライアントを決して読めないことをアサートする
テストを書いて。

教訓: AIがセキュリティバグを混入させたら、その実例にパッチを当てるだけでなく、その種類のミスを取り除くよう指揮すること。そして、誰かがそれを再び開けば大声で失敗するテストで、その種類を施錠してしまうこと。

ローンチ

私たちはテスト用に1か月分のデータを投入し、CSVをエクスポートし、表計算ソフトで開いて数値とエンコーディングが正しいことを確認してから、強力なデータベースパスワードを設定し、認証情報をローカルファイルからローテーションして取り除きました。サーバーレスホストにデプロイし、そのダッシュボードで本番の環境変数を追加し、彼女にURLを渡しました。彼女は本物のサインアップで自分でオンボーディングしました。ビルド全体が週末1回分でした。

オフラインでも読みたい?

PDF + EPUB + ダウンロード可能なプロンプトライブラリ + バージョンアップデートを入手しよう。

$ PDFを入手 — $39