/// /** * `cards` — units of work. * * Two fields belong to the client, not the developer: * priority — the client sets it directly * target_date — the client sets it directly * Everything else is the developer's. That split is enforced by the field * whitelist in src/lib/cards/client-patch.ts, because PocketBase rules are * record-level and cannot express it. See the domain primer at the top of * this plan. * * Two fields are written now and first read in Phase 2: * start_date — bounds which commits a scope rule may claim, so a new card * cannot retroactively swallow a year of old commits. * scope_rule — the conventional-commit scope this card owns, e.g. "stock" * matching `feat(stock): ...`. */ migrate( (app) => { const projects = app.findCollectionByNameOrId("projects"); const columns = app.findCollectionByNameOrId("columns"); const users = app.findCollectionByNameOrId("users"); const collection = new Collection({ name: "cards", type: "base", listRule: "@request.auth.id != ''", viewRule: "@request.auth.id != ''", createRule: null, updateRule: null, deleteRule: null, fields: [ { name: "project", type: "relation", required: true, collectionId: projects.id, cascadeDelete: true, minSelect: 0, maxSelect: 1, }, { name: "column", type: "relation", required: true, collectionId: columns.id, cascadeDelete: false, minSelect: 0, maxSelect: 1, }, { name: "title", type: "text", required: true, max: 200, presentable: true }, { name: "description", type: "text", required: false, max: 50000 }, { name: "position", type: "number", required: true }, { name: "priority", type: "select", required: true, maxSelect: 1, values: ["critical", "high", "medium", "low"], }, { name: "target_date", type: "date", required: false }, { name: "created_by", type: "relation", required: false, collectionId: users.id, cascadeDelete: false, minSelect: 0, maxSelect: 1, }, { name: "created_by_role", type: "select", required: true, maxSelect: 1, values: ["owner", "client"], }, { name: "accepted", type: "bool", required: false }, { name: "start_date", type: "date", required: false }, { name: "scope_rule", type: "text", required: false, max: 60 }, { name: "archived", type: "bool", required: false }, { name: "created", type: "autodate", onCreate: true, onUpdate: false }, { name: "updated", type: "autodate", onCreate: true, onUpdate: true }, ], indexes: [ "CREATE INDEX idx_cards_column ON cards (`column`, position)", "CREATE INDEX idx_cards_project ON cards (project, archived)", ], }); return app.save(collection); }, (app) => { return app.delete(app.findCollectionByNameOrId("cards")); } );