pocketbase-best-practices について
PocketBaseを使うAIエージェント向けに、セキュリティ、性能、認証、サーバー拡張の開発指針をまとめたスキルです。影響度順の64ルールに、誤った例と修正例が含まれます。
主な機能
- 019分野のPocketBase開発を網羅
- 02影響度順に64ルールを掲載
- 03誤例と修正コードを提示
- 04セキュリティ、クエリ、認証の指針
- 05GoとJSVMの拡張に対応
活用シーン
- 01コレクション設計とアクセスルールの検討
- 02遅いクエリやN+1問題の調査
- 03認証とファイルアップロードの確認
- 04本番デプロイとバックアップの準備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ greendesertsnow/ pocketbase-skills --skill pocketbase-best-practicesインストール後、Claude Code で/pocketbase-best-practicesを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
AGENTS.mdmetadata.jsonreferences/api-rules-security.mdauthentication.mdcollection-design.mdfile-handling.mdproduction-deployment.mdquery-performance.mdrealtime.mdsdk-usage.mdserver-side-extending.mdrules/_sections.md_template.mdauth-impersonation.mdauth-mfa.mdauth-oauth2.mdauth-otp.mdauth-password.mdauth-token-management.mdcoll-auth-vs-base.mdcoll-field-types.mdcoll-geopoint.mdcoll-indexes.mdcoll-relations.mdcoll-view-collections.mddeploy-backup.mddeploy-configuration.mddeploy-rate-limiting.mddeploy-reverse-proxy.mddeploy-scaling.md詳細
PocketBase のベストプラクティス
PocketBase は、導入しやすく、大規模運用では誤用しやすいシングルバイナリのバックエンド(SQLite + REST + リアルタイム + 認証)です。このスキルは AI エージェント向けのガードレールを提供します。9 カテゴリにわたる 64 のルールがあり、それぞれに誤ったコード例と正しいコード例が付属しています。安全でない API ルール、インデックスのないクエリ、壊れた認証フロー、N+1 の展開、漏えいしたサーバー側ハンドルなど、エージェントが実際に起こすミスを取り上げます。
PocketBase v0.40 および JS SDK v0.28(2026 年 8 月)向けに更新済みです。 v0.36 以降で動作します。
ルールの優先順位
すべてのルールには影響度が設定されています。Critical はセキュリティ上の欠陥や壊れたデータモデル、High はパフォーマンスと正確性の問題、Medium/Low は運用上の仕上げを指します。ルールが競合する場合は、影響度の高いものが優先されます。
対象範囲
| カテゴリ | 影響度 | 防止できる問題 |
|---|---|---|
| コレクション設計 | Critical | 不適切なフィールド型、インデックスの不足、リレーションの代わりに手動で ID 文字列を使用すること |
| API ルールとセキュリティ | Critical | 空または不適切なアクセスルールによるデータ漏えい、フィルターインジェクション |
| 認証 | Critical | 壊れたパスワード/OAuth2/OTP/MFA フロー、トークンの誤った取り扱い |
| SDK の使用 | High | 不適切なクライアント設定、エラーの握りつぶし、キャンセルされたリクエストに関するバグ |
| クエリパフォーマンス | High | N+1 クエリ、過剰なデータ取得、ページネーションの不足 |
| リアルタイム | Medium | サブスクリプションの切断、未認証のリアルタイムアクセス |
| ファイル処理 | Medium | 未検証のアップロード、不適切なファイル URL、サムネイルの不足 |
| 本番環境とデプロイ | Medium | バックアップがない、レート制限がない、スーパー�ーユーザーアクセスの露出 |
| サーバー側の拡張 | High | Go/JSVM フックのミス、トランザクションの誤用、安全でないフィルターバインディング |
クイックリファレンス
コレクション設計(CRITICAL)
- coll-field-types:適切なフィールド型を使用します(オブジェクトには json、列挙型には select)
- coll-auth-vs-base:ユーザーには auth コレクション、認証を使用しないデータには base コレクションを拡張します
- coll-relations:手動の ID 文字列ではなく、リレーションフィールドを使用します
- coll-indexes:頻繁にフィルターや並べ替えに使うフィールドにインデックスを作成します
- coll-view-collections:複雑な集計にはビューを使用します
- coll-geopoint:座標は lat/lng を含む json フィールドとして保存します
API ルール(CRITICAL)
- rules-basics:必ず API ルールを設定します。空の場合はパブリックアクセスになります
- rules-filter-syntax:ルールでは @request.auth、@collection、@now を使用します
- rules-request-context:リクエストデータには @request.body、@request.query 経由でアクセスします。
@request.contextの値:default/oauth2/otp/password/realtime/protectedFile - rules-cross-collection:コレクションをまたぐチェックには @collection.name.field を使用します
- rules-locked-vs-open:最初はアクセスを制限し、必要な範囲だけ開放します
- rules-strftime:日付の計算には
strftime('%Y-%m-%d', created)を使用します(v0.36 以降)
認証(CRITICAL)
- auth-password:メールアドレスとパスワードでログインするには authWithPassword を使用します
- auth-oauth2:OAuth2 プロバイダーは Admin UI で設定します。v0.38.2 以降を実行します(事前リンクによる乗っ取りの修正を含む)。プロバイダーのロゴは
listAuthMethods()からインラインで取得できます(v0.37 以降) - auth-otp:
requestOTP→authWithOTPの 2 段階方式を使用します。requestOTP にレート制限を設け、メールアドレスの登録有無を決して漏らさないようにします - auth-token-management:トークンを安全に保存し、有効期限が切れる前に更新します
- auth-mfa:機密性の高いアプリケーションでは MFA を有効にします
- auth-impersonation:ユーザーに代わって管理者操作を行うには、なりすまし機能を使用します
SDK の使用(HIGH)
- sdk-initialization:クライアントは一度だけ初期化し、インスタンスを再利用します
- sdk-auth-store:React Native/SSR では AsyncAuthStore を使用します
- sdk-error-handling:ClientResponseError をキャッチし、ステータスコードを確認します
- sdk-auto-cancellation:並行リクエストでは自動キャンセルを無効にします
- sdk-filter-binding:インジェクションを防ぐためにフィルターバインディングを使用します
クエリパフォーマンス(HIGH)
- query-expand:リレーションを展開して N+1 クエリを回避します
- query-field-selection:必要なフィールドだけを選択します
- query-pagination:大規模なデータセットにはカーソルページネーションを使用します
- query-batch-operations:可能な場合は作成や更新を一括処理します
リアルタイム(中程度)
- realtime-subscribe: 特定のレコードまたはコレクションを購読します
- realtime-events: 作成、更新、削除のイベントを個別に処理します
- realtime-auth: リアルタイム機能では API ルールが自動的に適用されます。パスワード変更時に認証が解除されます。接続時間には約 30 分の絶対上限があります(v0.38+)
- realtime-reconnection: 再接続ロジックを実装します。定期的な再接続は設計上の動作であるため、再接続を阻止するのではなく、状態を再同期してください
ファイル処理(中程度)
- file-upload: アップロードには FormData を使用し、適切なコンテンツタイプを設定します
- file-serving: ファイル URL には pb.files.getURL() を使用します
- file-validation: サーバー側でファイルの種類とサイズを検証します
デプロイ(中程度)
- deploy-backup: pb_data の定期バックアップをスケジュールします
- deploy-configuration: 設定には環境変数を使用します。v0.40 のログ上限(
Log.Dataは約 16KB)に注意し、SQL コンソール(v0.39+)はデバッグ専用として扱います - deploy-reverse-proxy: 本番環境では nginx/caddy の背後に配置します
- deploy-sqlite-considerations: 本番環境のワークロードに合わせて SQLite を最適化します
- deploy-rate-limiting: 組み込みのレートリミッターを有効にします(v0.36.7 時点では固定ウィンドウ方式)。多層防御のため、Nginx/Caddy の背後に配置します
- deploy-scaling: リアルタイム機能のために
ulimit -nを引き上げ、GOMEMLIMITを設定し、設定の暗号化を有効にします - deploy-superuser-ips: 本番環境では IP/CIDR によってスーパーユーザーのアクセスを許可リストに登録します(v0.38+)。復旧には
superuser ipsコンソールコマンドを使用します
サーバー側の拡張(高)
- ext-go-setup:
app.OnServe()を使ってルートを登録します。フック内では親スコープの app ではなくe.Appを使用します。v0.40 には Go 1.27 が必要です(encoding/json/v2— リリース前にテストしてください) - ext-js-setup:
*.pb.jsをpb_hooks/に配置し、/// <reference path="../pb_data/types.d.ts" />を追加します - ext-hooks-chain: 常に
e.Next()/e.next()を呼び出します。後でUnbindできるように、Id を指定してBindを使用します - ext-hooks-record-vs-request: レスポンス(リアルタイムを含む)の整形には
OnRecordEnrichを使用します。HTTP のみの場合はOnRecordRequestを使用します - ext-routing-custom:
/api/{yourapp}/の下にルートを作成し、RequireAuth()ミドルウェアを適用します - ext-transactions:
RunInTransaction内ではスコープ付きのtxAppを使用し、外側のappを決してキャプチャしないでください - ext-filter-binding-server:
FindFirstRecordByFilter/FindRecordsByFilterで{:name}+dbx.Paramsを使ってユーザー入力をバインドします - ext-filesystem:
NewFilesystem()/NewBackupsFilesystem()の各ハンドルでdefer fs.Close()を呼び出します - ext-cron-jobs:
app.Cron().MustAdd(id, expr, fn)/cronAdd()で登録します。ID は安定した値を使用し、__pb*__プレフィックスは使わないでください - ext-go-migrations:
migrations/の下にバージョン管理された.goファイルを配置します。Automigrate: osutils.IsProbablyGoRun() - ext-js-migrations:
migrate(upFn, downFn)を含むpb_migrations/<unix>_*.jsを配置します。ファイル名によって自動検出されます - ext-mailer: 送信時に
app.Settings().Metaから送信者を解決します。[email protected]を決してリリースに含めないでください。送信ごとにメールクライアントを作成します - ext-settings: 呼び出し時に
app.Settings()で読み取ります。_paramsを保存時に暗号化するには、PB_ENCRYPTION(32 文字)を設定します - ext-testing:
tests.NewTestApp(testDataDir)+tests.ApiScenarioを使用します。defer app.Cleanup()を指定し、ExpectedEventsを検証します - ext-compose-request-flow: 各レイヤー(ルート → tx → フック → enrich)でどの app インスタンスが有効かを示す、一連の処理をたどる解説です
- ext-go-custom-sqlite: FTS5/ICU が必要な場合にのみ
DBConnectを使用します。DBConnectは 2 回呼び出されます(data.db + auxiliary.db) - ext-jsvm-scope: ハンドラーの外部にある変数は実行時に未定義です。共有設定はハンドラー内で
require()を使って読み込んでください - ext-jsvm-modules: goja で動作するのは CJS(
require())のみです。先に ESM をバンドルし、変更可能なモジュール状態は避けてください
プロンプトの例
AI エージェントで以下を試して、スキルの動作を確認してください。
新機能の構築:
- 「商品、注文、レビューを含む EC アプリ向けに PocketBase のスキーマを設計してください」
- 「アプリに Google と GitHub の OAuth2 ログインを実装してください」
- 「PocketBase のサブスクリプションを使ってリアルタイム通知システムを構築してください」
- 「画像の検証とサムネイルのプレビュー機能を備えたファイルアップロードフォームを作成してください」
問題の修正:
- 「10 万件のレコードでリストクエリが遅いので、最適化してください」
- 「一括操作で 403 エラーが発生します」
- 「投稿一覧で著者データをループ内で読み込むことによる N+1 クエリ問題を修正してください」
- 「リアルタイムサブスクリプションが数分後に動作しなくなります」
セキュリティレビュー:
- 「API ルールを確認してください。ユーザーが自分のデータにのみアクセスできるようにする必要があります」
- 「適切なアクセス制御を設定してください。管理者はすべてのコンテンツを管理し、ユーザーは自分のコンテンツのみ編集できるようにしてください」
- 「SSR 用の認証 Cookie は安全に設定されていますか?」
- 「コレクションルールに IDOR の脆弱性がないか監査してください」
本番環境への移行:
- 「PocketBase 向けに HTTPS、レート制限、セキュリティヘッダーを備えた Nginx を設定してください」
- 「PocketBase データベースの自動バックアップを設定してください」
- 「約 500 人の同時ユーザーがいる本番環境のワークロード向けに SQLite の設定を最適化してください」
- 「Docker Compose と Caddy を使って PocketBase をデプロイしてください」
PocketBase の拡張:
- 「レコード作成後に Slack 通知を送信するカスタム Go ルートを追加してください」
- 「ユーザー登録前にメールドメインを検証する pb_hooks スクリプトを作成してください」
- 「Go アプリでカスタム SQLite ドライバーを使った FTS5 の全文検索を設定してください」
- 「競合状態を起こさずに、複数の pb_hooks ファイル間で設定オブジェクトを共有してください」
詳細ルール
コード例を含むルールの完全なドキュメントを確認するには、該当するカテゴリを読み込んでください。
- コレクション設計 - スキーマパターン、フィールド型、リレーション、インデックス
- API ルールとセキュリティ - アクセス制御、フィルター式、セキュリティパターン
- 認証 - パスワード認証、OAuth2、MFA、トークン管理
- SDK の使用方法 - クライアントの初期化、認証ストア、エラー処理、フック
- クエリのパフォーマンス - ページネーション、展開、一括操作、N+1 の防止
- リアルタイム - SSE サブスクリプション、イベント処理、再接続
- ファイル処理 - アップロード、配信、検証
- 本番環境とデプロイ - バックアップ、設定、リバースプロキシ、SQLite の最適化
- サーバー側の拡張 - Go/JSVM のセットアップ、イベントフック、カスタムルート、モジュール、カスタム SQLite