From 94b1e506c610233012c6a837d05e2c18fea20155 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Apr 2026 19:38:10 +0000 Subject: [PATCH 1/2] Initial plan From c7b73719133fb1890a8b2a27f01c190ee3fc0f3e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Apr 2026 20:23:20 +0000 Subject: [PATCH 2/2] fix(injectModel): fix pre-existing index rollback and required-field duplicate precheck Agent-Logs-Url: https://github.com/yash-pouranik/urBackend/sessions/a4ebb02d-93e3-4686-9938-d19a6344dc1a Co-authored-by: yash-pouranik <172860064+yash-pouranik@users.noreply.github.com> --- packages/common/src/utils/injectModel.js | 82 +++++++++++++++--------- 1 file changed, 50 insertions(+), 32 deletions(-) diff --git a/packages/common/src/utils/injectModel.js b/packages/common/src/utils/injectModel.js index a7613d7a..da93f731 100644 --- a/packages/common/src/utils/injectModel.js +++ b/packages/common/src/utils/injectModel.js @@ -144,7 +144,7 @@ function clearCompiledModel(connection, collectionName) { function getUniqueFieldFilter(fieldKey, isRequired) { if (isRequired) { - return { [fieldKey]: { $exists: true } }; + return {}; // scan ALL docs, including those missing the field } return { [fieldKey]: { $exists: true, $ne: null } }; @@ -170,44 +170,62 @@ async function findDuplicates(Model, fieldKey, isRequired) { } async function createUniqueIndexes(Model, fields = []) { - for (const field of fields) { - if (!field.unique) continue; - if (!UNIQUE_SUPPORTED_TYPES_SET.has(field.type)) continue; + const createdIndexes = []; - const normalizedKey = normalizeKey(field.key); - if (!normalizedKey) continue; - - const duplicates = await findDuplicates( - Model, - normalizedKey, - !!field.required, - ); - - if (duplicates.length > 0) { - const examples = duplicates - .slice(0, 3) - .map((d) => JSON.stringify(d._id)) - .join(", "); - - throw new Error( - `Cannot create unique index on '${normalizedKey}'. ${duplicates.length} duplicate values exist.${examples ? ` Examples: ${examples}` : ""}`, + const existingIndexes = await Model.collection.indexes(); + const existingIndexNames = new Set(existingIndexes.map((idx) => idx.name)); + + try { + for (const field of fields) { + if (!field.unique) continue; + if (!UNIQUE_SUPPORTED_TYPES_SET.has(field.type)) continue; + + const normalizedKey = normalizeKey(field.key); + if (!normalizedKey) continue; + + const duplicates = await findDuplicates( + Model, + normalizedKey, + !!field.required, ); - } - const indexName = `unique_${normalizedKey}_1`; + if (duplicates.length > 0) { + const examples = duplicates + .slice(0, 3) + .map((d) => JSON.stringify(d._id)) + .join(", "); - const indexOptions = { - unique: true, - name: indexName, - }; + throw new Error( + `Cannot create unique index on '${normalizedKey}'. ${duplicates.length} duplicate values exist.${examples ? ` Examples: ${examples}` : ""}`, + ); + } - if (!field.required) { - indexOptions.partialFilterExpression = { - [normalizedKey]: { $exists: true, $ne: null }, + const indexName = `unique_${normalizedKey}_1`; + + const indexOptions = { + unique: true, + name: indexName, }; - } - await Model.collection.createIndex({ [normalizedKey]: 1 }, indexOptions); + if (!field.required) { + indexOptions.partialFilterExpression = { + [normalizedKey]: { $exists: true, $ne: null }, + }; + } + + const createdName = await Model.collection.createIndex( + { [normalizedKey]: 1 }, + indexOptions, + ); + if (!existingIndexNames.has(createdName)) { + createdIndexes.push(createdName); + } + } + } catch (err) { + for (const indexName of createdIndexes) { + await Model.collection.dropIndex(indexName).catch(() => {}); + } + throw err; } }