浏览代码

Merge pull request #29002 from overleaf/ii-domain-capture-v1-field

[web] Make subscription.v1_id unique

GitOrigin-RevId: e65ea4b6bec54531cdc161ac02aee17d4a5cbdeb
ilkin-overleaf 9 月之前
父节点
当前提交
a33d799ee4
共有 1 个文件被更改,包括 75 次插入0 次删除
  1. 75 0
      tools/migrations/20251010082205_add_unique_constraint_subscription_v1_id.mjs

+ 75 - 0
tools/migrations/20251010082205_add_unique_constraint_subscription_v1_id.mjs

@@ -0,0 +1,75 @@
+import Helpers from './lib/helpers.mjs'
+
+const tags = ['saas']
+
+const originalIndexes = [
+  {
+    key: { v1_id: 1 },
+    name: 'v1_id_1',
+    sparse: true,
+  },
+]
+const newIndexes = [
+  {
+    key: { v1_id: 1 },
+    name: 'v1_id_2',
+    unique: true,
+    partialFilterExpression: {
+      v1_id: { $type: 'number' },
+    },
+  },
+]
+
+async function assertNoDuplicateV1Ids(collection) {
+  const duplicates = await collection
+    .aggregate([
+      { $match: { v1_id: { $exists: true, $ne: null } } },
+      {
+        $group: {
+          _id: '$v1_id',
+          count: { $sum: 1 },
+          docs: { $push: '$_id' },
+        },
+      },
+      { $match: { count: { $gt: 1 } } },
+    ])
+    .toArray()
+
+  if (duplicates.length > 0) {
+    const duplicateDetails = duplicates.map(dup => ({
+      v1_id: dup._id,
+      count: dup.count,
+      docs: dup.docs,
+    }))
+    throw new Error(
+      `Duplicate v1_id values found. Migration aborted to prevent data loss. Details: ${JSON.stringify(
+        duplicateDetails,
+        null,
+        2
+      )}`
+    )
+  }
+}
+
+const migrate = async client => {
+  const { db } = client
+
+  // pre‑check (keep old index intact if failing)
+  await assertNoDuplicateV1Ids(db.subscriptions)
+  await Helpers.dropIndexesFromCollection(db.subscriptions, originalIndexes)
+  await Helpers.addIndexesToCollection(db.subscriptions, newIndexes)
+}
+
+const rollback = async client => {
+  const { db } = client
+
+  await Helpers.dropIndexesFromCollection(db.subscriptions, newIndexes)
+  // recreate the original non-unique sparse index
+  await Helpers.addIndexesToCollection(db.subscriptions, originalIndexes)
+}
+
+export default {
+  tags,
+  migrate,
+  rollback,
+}