/// // M21 — technicianAssignments optimistic concurrency lock. // // Rejects updates to technicianAssignments when the client-sent // `__expectedUpdated` doesn't match the current `updated` value. // Clients opt in by including `__expectedUpdated`; if absent the // check is skipped (backward-compatible). migrate( (app) => { app.onRecordUpdateRequest((e) => { if (e.collection.name !== 'technicianAssignments') return; const body = e.httpContext.request().body; const expected = body.get('__expectedUpdated'); if (!expected) return; // opt-in // Fetch the original record from the DB to get the current updated value. let original; try { original = e.dao.findRecordById(e.collection, e.record.id); } catch { return; // record not found — let the normal error handling cover this } const originalUpdated = String(original.get('updated') || ''); if (originalUpdated !== String(expected)) { throw new ApiError(409, 'Record was modified by another user'); } // Remove the meta field so it doesn't persist to the database. body.remove('__expectedUpdated'); console.log('[M21] optimistic lock passed for', e.record.id); }); console.log('[M21] optimistic lock hook installed'); }, (app) => { console.log('[M21] rollback requested — remove this migration file and restart PocketBase'); }, );