/// // // M5 — Unique index on `repairOrders.roNumber`. // // The frontend generates RO numbers with Math.random() and now guards against // collisions against the loaded set (see src/pages/RepairOrders.tsx, // uniqueRONumber()). But two advisors creating ROs in the same second can // still race past the frontend check. This migration adds a server-side // unique index so the second write fails at the DB layer instead of silently // producing two ROs with the same number. // // If your existing data has duplicate roNumbers, this migration will fail — // dedupe in the admin UI first (find records where roNumber = '', set them to // unique placeholder values, then retry). // migrate( (db) => { const col = db.findCollectionByNameOrId('repairOrders'); if (!col) { console.warn('[M5] repairOrders collection not found — skipping'); return; } // PocketBase 0.20+ uses the `Index` helper on a field. Add a unique // index on roNumber if one isn't already present. Using a TextField // option `unique` is the simplest cross-version approach. let changed = false; const existing = col.fields.find((f) => f.name === 'roNumber'); if (existing && existing.type === 'text' && !existing.options?.unique) { existing.options = { ...(existing.options || {}), unique: true }; changed = true; } else if (!existing) { // Field missing entirely — add it with unique. col.fields.push(new TextField({ name: 'roNumber', required: false, options: { unique: true }, })); changed = true; } if (changed) { db.save(col); console.log('[M5] set roNumber unique=true on repairOrders'); } else { console.log('[M5] roNumber already unique — no change'); } }, (db) => { const col = db.findCollectionByNameOrId('repairOrders'); if (!col) return; const f = col.fields.find((f) => f.name === 'roNumber'); if (f && f.type === 'text' && f.options?.unique) { f.options.unique = false; db.save(col); } } );