migrate((db) => { const dao = new Dao(db); // 1. Update 'users' collection const usersCollection = dao.findCollectionByNameOrId("users"); usersCollection.schema.addField(new SchemaField({ name: "is_supervisor", type: "bool", required: false, options: {} })); usersCollection.schema.addField(new SchemaField({ name: "supervisor", type: "relation", required: false, options: { collectionId: usersCollection.id, cascadeDelete: false, maxSelect: 1, displayFields: ["name", "email"] } })); dao.saveCollection(usersCollection); // 2. Update 'time_entries' collection rules const timeEntries = dao.findCollectionByNameOrId("time_entries"); // Allow if owner OR if user's supervisor is requestor const rule = "@request.auth.id = user.id || user.supervisor.id = @request.auth.id"; timeEntries.listRule = rule; timeEntries.viewRule = rule; // create/update/delete usually restricted to owner, supervisors maybe read-only for now? // Plan said "view", so list/view is enough. dao.saveCollection(timeEntries); }, (db) => { // Revert logic (simplified) const dao = new Dao(db); const usersCollection = dao.findCollectionByNameOrId("users"); usersCollection.schema.removeField("is_supervisor"); usersCollection.schema.removeField("supervisor"); dao.saveCollection(usersCollection); const timeEntries = dao.findCollectionByNameOrId("time_entries"); timeEntries.listRule = "@request.auth.id = user.id"; timeEntries.viewRule = "@request.auth.id = user.id"; dao.saveCollection(timeEntries); })