pocketbase
GitHubPocketBase后端开发规范,涵盖Schema管理、Go自定义钩子、认证流程及集合API规则。指导开发者在canutin项目中正确使用PocketBase进行数据操作与扩展。
Trigger Scenarios
Install
npx skills add fmaclen/canutin --skill pocketbase -g -y
SKILL.md
Frontmatter
{
"name": "pocketbase",
"description": "PocketBase backend - schema, Go hooks, admin API, dev credentials, collections"
}
PocketBase Conventions
Overview
Backend runtime and database for canutin. Custom Go hooks extend PocketBase with balance-calculation logic and custom API routes. A single binary serves HTTP, realtime, and the admin UI.
Dev Environment
- Base URL:
$PUBLIC_PB_URL— each checkout has its own port, so read it from the generated.envrather than assuming the default - Server ownership, ports, and start/reset commands: see local-servers
- Types auto-generated in
src/lib/pocketbase.schema.tson schema changes
Authentication
- Superuser (dev only):
superadmin@example.com/123qweasdzxc— auto-upserted on server start viascripts/pb-server.ts - Regular user auth:
POST /api/collections/users/auth-with-password - Superuser auth:
POST /api/collections/_superusers/auth-with-password - Include token in
Authorization: Bearer <token>for subsequent requests - Test helpers in
e2e/pocketbase.helpers.tsalready handle auth — use them instead of reimplementing
Collections
Source of truth: src/lib/pocketbase.schema.ts (generated from live schema).
Core collections: users, accounts, transactions, assets, accountBalances, assetBalances, balanceTypes, transactionLabels, accountShares, assetShares.
- All collections are queryable by superadmins
- Regular users are scoped via collection API rules (see the admin UI)
- Filter syntax:
field='value',&&,||,>=, etc.
List and view rules that authorize through reverse relations must begin with
@request.auth.id != '' && (...), wrapping the entire owner/sharing expression.
PocketBase treats a missing relation and missing auth ID as equal, so an unguarded
sharing clause can admit anonymous reads of records with no shares. Cover both
list and direct-record access when changing these rules.
The latestAccountBalances, latestAssetBalances, and latestSecurityBalances
views copy the list and view rules of accountBalances, assetBalances, and
securityBalances. When a balance collection's rule changes, change its view's
rule in the same migration flow.
Available APIs
All PocketBase APIs are available to authenticated clients with the appropriate scope:
Custom Go Hooks
Location: pocketbase/main.go (split into balance.go, shares.go, import.go).
Current hooks:
- Balance calculation — after transaction create/update/delete, enqueues affected account(s) for balance recalculation with a 250ms trailing-edge debounce
- Shares — ownership/permission extensions on accounts and assets
- Bulk import —
/api/canutin/importand/api/canutin/import/revert(see pb-import.md)
Pattern for new hooks:
- Use
OnRecordAfter*Successhooks for post-mutation logic - Debounce expensive operations using the worker + ticker pattern
- Handle account reassignment in update hooks (old and new account)
- Split into multiple files when
main.gobecomes unwieldy
Served Skill Reference
pocketbase/skill.go hand-maintains the behavioral semantics — custom endpoints, behavioral constraints, auth — of the /api/canutin/skill reference; the import payload shape is generated from the Go structs. Update the hand-maintained sections whenever custom routes or backend hooks change. CI enforces this: a change under pocketbase/**/*.go without a matching pocketbase/skill.go or .agents/skills/ update fails the PR unless labeled skip-skill-check.
Schema Changes
- Never write migration files by hand
- Migrations are auto-generated via the admin API (
POST /api/collections,PATCH /api/collections/<id>) becauseAutomigrate: trueis set withTemplateLangJS— see pb-migrate.md - Migrations land in
pocketbase/pb_migrations/as JS files
Anti-patterns
- Dev credentials in production — these are for local development only
- Hand-written migrations — always go through the admin API
- Starting PocketBase by default — follow the ownership rules in local-servers
- Raw
app.Save()Go calls for schema — use the collection API endpoints so automigrate hooks fire - Original Ozzo validation module — use PocketBase's maintained fork (
github.com/pocketbase/ozzo-validation/v4) so custom validation errors use the same types PocketBase recognizes
See Also
- realtime.md - Client-side subscription patterns
- testing.md - Test helpers for seeding/querying data
- pb-import.md - Bulk import API
- pb-migrate.md - Schema-change workflow
- PocketBase docs: https://pocketbase.io/docs/
Version History
-
b491bd7
Current 2026-09-28 12:22
修复了仅加载最新余额的问题,确保净资产显示完整(#452)。
- 28eb754 2026-09-23 01:22


