read-prod-database について
DeepAPI の本番 Supabase Postgres データベースを読み取り専用で照会するためのスキルです。Agent にクエリ範囲の選択、スキーマの確認、分析の手順を示し、内部利用データとユーザーデータを保護します。
主な機能
- 01本番データベースへの読み取り専用アクセス
- 02顧客のみ・全ワークスペースの範囲指定
- 03スキーマ確認とクエリ例
- 04拒否リストとタイムアウトの指針
- 05PII の取り扱いと書き込み防止
活用シーン
- 01顧客の利用状況と継続率の分析
- 02API リクエストとサービス費用の確認
- 03本番環境のマイグレーション版の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ davidondrej/ skills --skill read-prod-databaseインストール後、Claude Code で/read-prod-databaseを入力して読み込まれたか確認します。
詳細
本番データベースの読み取り(読み取り専用)
本番の DeepAPI Supabase Postgres(ADR 0093)への、正式に認可された読み取り専用アクセスです。このロールでは書き込みはできません。書き込みを試みないでください。
クイックスタート
# env var lives in David's ~/.zshrc. NEVER `source ~/.zshrc` (breaks agent shells).
URL=${DEEPAPI_READONLY_DB_URL:-$(rg -o 'DEEPAPI_READONLY_DB_URL="([^"]+)"' -r '$1' ~/.zshrc)}
psql "$URL" -X -c "select count(*) from public.workspaces;"
状態確認:select current_user; の結果が agents_readonly である必要があります。環境変数が存在しない場合は、処理を止めてユーザーに確認してください。
スコープ:デフォルトでは David とチームを除外(ADR 0175)
利用状況、顧客、PMFに関するクエリは、次の2つのモードのいずれかで実行します。毎回、意図的に選択してください。
- 顧客のみ(デフォルト) — David、
@davidondrej.comチーム、ドッグフーディング/テスト用ワークスペースを除外します。 - すべてのワークスペース — 内部利用を含みます。ユーザーから明示的に依頼された場合、または運用負荷/総支出を確認する場合に限ります。
ワークスペース ID が src/config/internal-workspaces.ts に含まれている(現在の UUID リストをそこからコピーしてください)か、dashboard_workspace_members のメールアドレスが @davidondrej.com ドメインである場合、そのワークスペースは内部用です。ワークスペース単位のクエリには、必ず以下を追加してください。
-- customer-only scope: replace <uuids> with the list from src/config/internal-workspaces.ts
where sr.workspace_id <> all (array['<uuid-1>','<uuid-2>']::uuid[])
and not exists (
select 1 from public.dashboard_workspace_members m
where m.workspace_id = sr.workspace_id
and split_part(m.email, '@', 2) = 'davidondrej.com')
使用するスコープを、各数値について必ずユーザーに伝えてください。結果には「顧客のみ(David とチームを除外)」または「すべてのワークスペース(内部を含む)」とラベルを付けます。ラベルのない数値や、異なるスコープの数値を混在させて提示してはいけません。
閲覧できる情報とできない情報
- 現在および将来のすべての
publicテーブルに対する SELECT(拒否リスト方式)、すべての行(このロールにはbypassrlsが設定されています)。 - 拒否リストに含まれ、常に
permission deniedとなるもの:api_keys、email_webhook_events、authスキーマ全体。これは意図的な設定です。アクセスを要求したり、回避策を使ったりしないでください(例:api_keysではなくservice_requests.api_key_idを結合します)。 - ガードレール:すべてのセッションは読み取り専用で、クエリは10秒後に強制終了されます。
スキーマを確認してからクエリを実行する
psql "$URL" -X -c '\dt public.*' # list tables
psql "$URL" -X -c '\d public.service_requests' # columns of one table
リポジトリ内のスキーマの信頼できる参照元:src/db/migrations/*.sql。
主なテーブル:workspaces(テナント)、service_requests(すべての API 呼び出し:ステータス、コスト、プロバイダー)、service_usage_events(利用状況の集計)、credit_accounts / credit_ledger_entries(金銭、不変の台帳)、credit_reservations(保留)、rate_limit_counters、waitlist_signups、schema_migrations(実行済みのマイグレーション)。
便利なパターン:
# recent requests for one workspace (route = endpoint, e.g. /v1/research/deep)
psql "$URL" -X -c "select id, route, status, created_at from public.service_requests where workspace_id = '<id>' order by created_at desc limit 20;"
# weekly returning workspaces (retention, ADR 0069) — PMF metric: apply the customer-only scope filter above
psql "$URL" -X -c "select date_trunc('week', created_at) w, count(distinct workspace_id) from public.service_requests group by 1 order by 1 desc limit 8;"
# did migration NNNN run on prod?
psql "$URL" -X -c "select version from public.schema_migrations order by version;"
失敗時の対処
permission denied for table ...→ 拒否リストに含まれるテーブルです(想定どおりです。上記を参照してください)。canceling statement due to statement timeout→ クエリが重すぎます。フィルターや上限を追加してください。同じクエリをループで再試行してはいけません。- 想定外に結果が空の場合 →
select current_userで再確認し、\dtでテーブルの存在を確認してください。データが存在しないと決めつけないでください。 - 接続拒否/認証失敗 → URL またはパスワードが変更されています。ユーザーに確認してください(パスワードは
alter role agents_readonly with passwordでローテーションされます)。
厳守事項
- 読み取り専用です。INSERT/UPDATE/DELETE/DDL、
set default_transaction_read_only = off、書き込みの回避策は禁止です。本番への書き込みはユーザーが行います(マイグレーションとschema_migrationsへの記録)。 - クエリ結果には実際のユーザーデータ(メールアドレス、名前、利用状況)が含まれます。チャット内での分析には使用できますが、個人情報や大量のデータダンプをコミット、PR、ドキュメント、コードに貼り付けてはいけません。
- セットアップ、メンテナンス、ローテーションの詳細:
docs/external/supabase-readonly-agent-db-access.md。ロール SQL:docs/database/create-agents-readonly-role.sql。