/// PocketBase migration: sync full bank transaction list (BankTransaction rows). /// /// Apply on the server (from /opt/pocketbase or wherever the binary lives): /// /// sudo cp this_file /opt/pocketbase/pb_migrations/ /// sudo chown pocketbase:pocketbase /opt/pocketbase/pb_migrations/*.js /// sudo -u pocketbase /opt/pocketbase/pocketbase migrate up /// sudo systemctl restart pocketbase /// /// Depends on usersapp (same owner rules as labels / tx_meta). migrate((app) => { const users = app.findCollectionByNameOrId("usersapp"); const ownerRules = { listRule: "user = @request.auth.id", viewRule: "user = @request.auth.id", createRule: "@request.auth.id != '' && user = @request.auth.id", updateRule: "user = @request.auth.id", deleteRule: "user = @request.auth.id", }; // --- bank transactions (API cache + CSV imports) --- // Components are stored so clients can rebuild BankTransaction; tx_id is the // clipped BankTransaction.id used for unique upserts (same clip as tx_meta). const transactions = new Collection({ type: "base", name: "transactions", ...ownerRules, fields: [ { type: "relation", name: "user", required: true, collectionId: users.id, cascadeDelete: true, maxSelect: 1, }, { // BankTransaction.id → "date|currency|amount|description" (clipped) type: "text", name: "tx_id", required: true, min: 1, max: 2000, }, { type: "text", name: "date", required: true, min: 1, max: 32, }, { type: "text", name: "description", required: true, min: 1, max: 4000, }, { type: "number", name: "amount", required: true, }, { type: "text", name: "currency", required: true, min: 1, max: 8, }, { type: "bool", name: "pending", required: false, }, ], indexes: [ "CREATE UNIQUE INDEX idx_transactions_user_tx ON transactions (user, tx_id)", ], }); app.save(transactions); }, (app) => { try { app.delete(app.findCollectionByNameOrId("transactions")); } catch (_) {} });