Free SKILL.md scraped from GitHub. Clone the repo or copy the file directly into your Claude Code skills directory.
npx versuz@latest install davila7-claude-code-templates-cli-tool-components-skills-pocketbase-pb-collectionsgit clone https://github.com/davila7/claude-code-templates.gitcp claude-code-templates/SKILL.MD ~/.claude/skills/davila7-claude-code-templates-cli-tool-components-skills-pocketbase-pb-collections/SKILL.md--- name: "PocketBase Collections" description: "Collection and schema design for PocketBase. Use when creating collections, designing schemas, adding fields, setting up relations, or choosing between base/auth/view collection types. Prevents wrong field types, documents zero-default behavior, and covers relation cascading." --- # PocketBase Collection & Schema Design ## Collection Types ### Base Collection Standard data collection. System fields: `id`, `created`, `updated`. ### Auth Collection Extends base with authentication. Additional system fields: `email`, `emailVisibility`, `verified`, `password`, `tokenKey`. Cannot delete system fields. Can disable email/password auth in collection options. ### View Collection Read-only, backed by a SQL SELECT query. No create/update/delete. Fields are auto-detected from the query. Useful for aggregations, joins, and computed views. ```sql -- Example: view collection query SELECT p.id, p.title, COUNT(c.id) as comments_count FROM posts p LEFT JOIN comments c ON c.post = p.id GROUP BY p.id ``` View collections support API rules (list/view only) and can be used in relations. ## Field Types | Type | Go type | Zero default | Notes | |------|---------|-------------|-------| | `text` | `string` | `""` | min/max length, regex pattern | | `editor` | `string` | `""` | Rich text (sanitized HTML) | | `number` | `float64` | `0` | min/max, `noDecimal` option | | `bool` | `bool` | `false` | | | `email` | `string` | `""` | Auto-validated format | | `url` | `string` | `""` | Auto-validated format | | `date` | `string` | `""` | ISO 8601 (`2024-01-01 00:00:00.000Z`) | | `select` | `string`/`[]string` | `""`/`[]` | `values` list, `maxSelect` | | `file` | `string`/`[]string` | `""`/`[]` | `maxSelect`, `maxSize`, `mimeTypes` | | `relation` | `string`/`[]string` | `""`/`[]` | `collectionId`, `cascadeDelete`, `maxSelect` | | `json` | `any` | `null` | Only type that can be null! `maxSize` | | `autodate` | `string` | auto | `onCreate`/`onUpdate` modifiers | | `password` | `string` | `""` | Stored hashed, never returned in API | **Critical**: all types default to their zero value, NOT null. Only `json` fields can be null. ## Field Modifiers Use in collection schema definitions: - **`required`** — field cannot be empty/zero - **`unique`** — unique constraint (composite via unique indexes) - **`presentable`** — included in relation display - **`hidden`** — excluded from API responses unless explicitly requested - **`:autogenerate`** — for `text` fields: auto-generate value (e.g., slug from other field) ## Relation Patterns ### One-to-many ``` posts.author -> users (maxSelect: 1) ``` Each post has one author. Query posts by author: `author = "USER_ID"`. ### Many-to-many ``` posts.tags -> tags (maxSelect: 0, meaning unlimited) ``` Multi-select relation. Filter: `tags ?= "TAG_ID"` (contains). ### Back-relations No explicit back-relation field needed. Use `@collection.posts.author` in API rules or expand from either side: ``` GET /api/collections/users/records/USER_ID?expand=posts_via_author ``` ### Cascade Delete Set `cascadeDelete: true` on the relation field. When the referenced record is deleted, all records pointing to it are also deleted. Default is `false` (sets to empty string). ### Self-referencing A collection can reference itself: ``` categories.parent -> categories (maxSelect: 1) ``` ## Indexes - Created in the collection settings (not field-level) - Format: `CREATE [UNIQUE] INDEX idx_name ON collection (field1, field2)` - Unique indexes enforce composite uniqueness - Partial indexes: `CREATE INDEX ... WHERE condition` - Indexes on relation fields improve join performance ## Auth Collection Specifics ### OAuth2 Enable per-provider in collection settings. Each provider needs client ID + secret. PocketBase handles the full OAuth2 flow. ### OTP (One-Time Password) Enable in auth collection settings. Sends code via email. Configure `otp.enabled`, `otp.duration`, `otp.length`. ### MFA (Multi-Factor Authentication) Enable in auth collection settings. Requires a second factor after primary auth. `mfa.enabled`, `mfa.duration`, `mfa.rule` (filter to determine which users need MFA). ### Password Auth Enabled by default. Can customize `minPasswordLength`. Can disable entirely if using only OAuth2/OTP. ### Auth Options - `authToken.duration` — token lifetime (seconds) - `passwordAuth.enabled` — toggle email/password - `passwordAuth.identityFields` — fields used for login (default: `email`; can add `username`) - `oauth2.enabled` — toggle OAuth2 - `otp.enabled` — toggle OTP ## Best Practices 1. **Prefer `select` over `bool`** when there might be more than 2 states in the future 2. **Use `relation` not `text`** for foreign keys — you get cascade, expand, and type safety 3. **`json` fields** are schemaless — use sparingly, prefer typed fields 4. **Name collections** in lowercase snake_case (e.g., `blog_posts`, `user_profiles`) 5. **Index early** — add indexes for any field used in filters or sorts 6. **`maxSelect: 1`** on relations returns a string ID; **`maxSelect: >1` or `0`** returns an array