← 返回 Skill 列表
extension
分类: 开发与工程API Key 暂未确认

pocketbase-best-practices

PocketBase开发最佳实践,涵盖集合设计、API规则、认证、SDK使用、查询优化、实时订阅、文件处理和部署。在构建PocketBase后端、设计模式、实现访问控制、设置认证流程或优化性能时使用。

person作者: jakexiaohubgithub

PocketBase Best Practices

PocketBase is a single-binary backend (SQLite + REST + realtime + auth) that is easy to start with and easy to misuse at scale. This skill gives AI agents the guardrails: 64 rules across 9 categories, each with an incorrect vs. correct code example, covering the mistakes agents actually make — insecure API rules, unindexed queries, broken auth flows, N+1 expands, leaked server-side handles.

Updated for PocketBase v0.40 and JS SDK v0.28 (August 2026). Works with v0.36+.

How rules are prioritized

Every rule carries an impact level: Critical = security holes or broken data models, High = performance and correctness problems, Medium/Low = operational polish. When rules conflict, higher impact wins.

What's covered

| Category | Impact | What it protects you from | |----------|--------|---------------------------| | Collection Design | Critical | Wrong field types, missing indexes, manual ID strings instead of relations | | API Rules & Security | Critical | Data leaks from empty/incorrect access rules, filter injection | | Authentication | Critical | Broken password/OAuth2/OTP/MFA flows, token mishandling | | SDK Usage | High | Bad client setup, swallowed errors, cancelled-request bugs | | Query Performance | High | N+1 queries, over-fetching, missing pagination | | Realtime | Medium | Dropped subscriptions, unauthenticated realtime access | | File Handling | Medium | Unvalidated uploads, wrong file URLs, missing thumbnails | | Production & Deployment | Medium | No backups, no rate limits, exposed superuser access | | Server-Side Extending | High | Go/JSVM hook mistakes, transaction misuse, unsafe filter binding |

Quick Reference

Collection Design (CRITICAL)

  • coll-field-types: Use appropriate field types (json for objects, select for enums)
  • coll-auth-vs-base: Extend auth collection for users, base for non-auth data
  • coll-relations: Use relation fields, not manual ID strings
  • coll-indexes: Create indexes on frequently filtered/sorted fields
  • coll-view-collections: Use views for complex aggregations
  • coll-geopoint: Store coordinates as json field with lat/lng

API Rules (CRITICAL)

  • rules-basics: Always set API rules; empty = public access
  • rules-filter-syntax: Use @request.auth, @collection, @now in rules
  • rules-request-context: Access request data via @request.body, @request.query; @request.context values: default/oauth2/otp/password/realtime/protectedFile
  • rules-cross-collection: Use @collection.name.field for cross-collection checks
  • rules-locked-vs-open: Start locked, open selectively
  • rules-strftime: Use strftime('%Y-%m-%d', created) for date arithmetic (v0.36+)

Authentication (CRITICAL)

  • auth-password: Use authWithPassword for email/password login
  • auth-oauth2: Configure OAuth2 providers via Admin UI; run ≥v0.38.2 (pre-linking hijack fix); provider logos come inline from listAuthMethods() (v0.37+)
  • auth-otp: Two-step requestOTP → authWithOTP; rate-limit requestOTP and never leak email existence
  • auth-token-management: Store tokens securely, refresh before expiry
  • auth-mfa: Enable MFA for sensitive applications
  • auth-impersonation: Use impersonation for admin actions on behalf of users

SDK Usage (HIGH)

  • sdk-initialization: Initialize client once, reuse instance
  • sdk-auth-store: Use AsyncAuthStore for React Native/SSR
  • sdk-error-handling: Catch ClientResponseError, check status codes
  • sdk-auto-cancellation: Disable auto-cancel for concurrent requests
  • sdk-filter-binding: Use filter binding to prevent injection

Query Performance (HIGH)

  • query-expand: Expand relations to avoid N+1 queries
  • query-field-selection: Select only needed fields
  • query-pagination: Use cursor pagination for large datasets
  • query-batch-operations: Batch creates/updates when possible

Realtime (MEDIUM)

  • realtime-subscribe: Subscribe to specific records or collections
  • realtime-events: Handle create, update, delete events separately
  • realtime-auth: Realtime respects API rules automatically; auth unsets on password change; ~30min absolute connection cap (v0.38+)
  • realtime-reconnection: Implement reconnection logic — periodic reconnects are by design, re-sync state instead of fighting them

File Handling (MEDIUM)

  • file-upload: Use FormData for uploads, set proper content types
  • file-serving: Use pb.files.getURL() for file URLs
  • file-validation: Validate file types and sizes server-side

Deployment (MEDIUM)

  • deploy-backup: Schedule regular backups of pb_data
  • deploy-configuration: Use environment variables for config; mind v0.40 log caps (Log.Data ~16KB) and treat the SQL console (v0.39+) as debug-only
  • deploy-reverse-proxy: Put behind nginx/caddy in production
  • deploy-sqlite-considerations: Optimize SQLite for production workloads
  • deploy-rate-limiting: Enable the built-in rate limiter (fixed-window as of v0.36.7); front with Nginx/Caddy for defense in depth
  • deploy-scaling: Raise ulimit -n for realtime, set GOMEMLIMIT, enable settings encryption
  • deploy-superuser-ips: Whitelist superuser access by IP/CIDR in production (v0.38+); recovery via the superuser ips console command

Server-Side Extending (HIGH)

  • ext-go-setup: Use app.OnServe() to register routes; use e.App inside hooks, not the parent-scope app; v0.40 needs Go 1.27 (encoding/json/v2 — test before shipping)
  • ext-js-setup: Drop *.pb.js in pb_hooks/; add /// <reference path="../pb_data/types.d.ts" />
  • ext-hooks-chain: Always call e.Next()/e.next(); use Bind with an Id for later Unbind
  • ext-hooks-record-vs-request: Use OnRecordEnrich to shape responses (incl. realtime); OnRecordRequest for HTTP-only
  • ext-routing-custom: Namespace routes under /api/{yourapp}/; attach RequireAuth() middleware
  • ext-transactions: Use the scoped txApp inside RunInTransaction; never capture the outer app
  • ext-filter-binding-server: Bind user input with {:name} + dbx.Params in FindFirstRecordByFilter / FindRecordsByFilter
  • ext-filesystem: defer fs.Close() on every NewFilesystem() / NewBackupsFilesystem() handle
  • ext-cron-jobs: Register with app.Cron().MustAdd(id, expr, fn) / cronAdd(); stable ids, no __pb*__ prefix
  • ext-go-migrations: Versioned .go files under migrations/; Automigrate: osutils.IsProbablyGoRun()
  • ext-js-migrations: pb_migrations/<unix>_*.js with migrate(upFn, downFn); auto-discovered by filename
  • ext-mailer: Resolve sender from app.Settings().Meta at send-time; never ship no-reply@example.com; create the mail client per send
  • ext-settings: Read via app.Settings() at call time; set PB_ENCRYPTION (32 chars) to encrypt _params at rest
  • ext-testing: tests.NewTestApp(testDataDir) + tests.ApiScenario; defer app.Cleanup(), assert ExpectedEvents
  • ext-compose-request-flow: Composite walkthrough showing which app instance is active at each layer (route → tx → hook → enrich)
  • ext-go-custom-sqlite: Only use DBConnect when you need FTS5/ICU; DBConnect is called twice (data.db + auxiliary.db)
  • ext-jsvm-scope: Variables outside handlers are undefined at runtime — load shared config via require() inside the handler
  • ext-jsvm-modules: Only CJS (require()) works in goja; bundle ESM first; avoid mutable module state

Example Prompts

Try these with your AI agent to see the skill in action:

Building a new feature:

  • "Design a PocketBase schema for an e-commerce app with products, orders, and reviews"
  • "Implement OAuth2 login with Google and GitHub for my app"
  • "Build a real-time notification system with PocketBase subscriptions"
  • "Create a file upload form with image validation and thumbnail previews"

Fixing issues:

  • "My list query is slow on 100k records -- optimize it"
  • "I'm getting 403 errors on my batch operations"
  • "Fix the N+1 query problem in my posts list that loads author data in a loop"
  • "My realtime subscriptions stop working after a few minutes"

Security review:

  • "Review my API rules -- users should only access their own data"
  • "Set up proper access control: admins manage all content, users edit only their own"
  • "Are my authentication cookies configured securely for SSR?"
  • "Audit my collection rules for IDOR vulnerabilities"

Going to production:

  • "Configure Nginx with HTTPS, rate limiting, and security headers for PocketBase"
  • "Set up automated backups for my PocketBase database"
  • "Optimize SQLite settings for a production workload with ~500 concurrent users"
  • "Deploy PocketBase with Docker Compose and Caddy"

Extending PocketBase:

  • "Add a custom Go route that sends a Slack notification after a record is created"
  • "Write a pb_hooks script that validates an email domain before user signup"
  • "Set up FTS5 full-text search with a custom SQLite driver in my Go app"
  • "Share a config object across multiple pb_hooks files without race conditions"

Detailed Rules

Load the relevant category for complete rule documentation with code examples: