From 8bf4c4f03548bc776593a3673215859b96752406 Mon Sep 17 00:00:00 2001 From: nathan musoke Date: Thu, 13 Jul 2023 19:33:16 -0400 Subject: [PATCH] fix: Allow identical ticks on one day (#340) The schema enforces a unique index on {climbId, dateClimbed, style, userID, source}. This is meant to prevent duplicating ticks imported from mountain project. However, it also prevents logging such ticks when they are legitimate. The import procedure also deletes imported ticks before reimporting, so this was overly cautious. Change the schema so it does not enforce uniqueness in this way. Instead, add non-unique indexes on { userId } and { userId, climbId }. Add a db migration script. Remove climb uniqueness test. Fixes https://github.com/OpenBeta/open-tacos/issues/631 --- .../0004-unique-user-climb-date-style.js | 11 ++++++++++ src/db/TickSchema.ts | 3 ++- src/model/__tests__/ticks.ts | 20 ------------------- 3 files changed, 13 insertions(+), 21 deletions(-) create mode 100644 db-migrations/0004-unique-user-climb-date-style.js diff --git a/db-migrations/0004-unique-user-climb-date-style.js b/db-migrations/0004-unique-user-climb-date-style.js new file mode 100644 index 00000000..5414f2e6 --- /dev/null +++ b/db-migrations/0004-unique-user-climb-date-style.js @@ -0,0 +1,11 @@ +/** + * https://github.com/OpenBeta/open-tacos/issues/631 + **/ + +rs1 = db.ticks.createIndex({ userId: -1 }) +rs2 = db.ticks.createIndex({ userId: -1, climbId: -1 }) +rs3 = db.ticks.dropIndex({ climbId: 1, dateClimbed: 1, style: 1, userId: 1, source: 1 }) + +printjson(rs1) +printjson(rs2) +printjson(rs3) diff --git a/src/db/TickSchema.ts b/src/db/TickSchema.ts index 15149bb1..53e9a861 100644 --- a/src/db/TickSchema.ts +++ b/src/db/TickSchema.ts @@ -24,7 +24,8 @@ export const TickSchema = new Schema({ source: { type: Schema.Types.String, enum: ['MP', 'OB'] as TickSource[], required: true, index: true } }) -TickSchema.index({ climbId: 1, dateClimbed: 1, style: 1, userId: 1, source: 1 }, { unique: true }) +TickSchema.index({ userId: 1 }) // for ticksByUser() +TickSchema.index({ userId: 1, climbId: 1 }) // for ticksByUserIdAndClimb() export const getTickModel = (name: string = 'ticks'): mongoose.Model => { return mongoose.model(name, TickSchema) diff --git a/src/model/__tests__/ticks.ts b/src/model/__tests__/ticks.ts index 5b719944..5325f34c 100644 --- a/src/model/__tests__/ticks.ts +++ b/src/model/__tests__/ticks.ts @@ -185,24 +185,4 @@ describe('Ticks', () => { expect(newTick?._id).toEqual(OBTick._id) expect(newTick?.notes).toEqual('Not sandbagged') }) - - it('should reject duplicate ticks', async () => { - const tick1: TickInput = { - name: 'Small Dog', - notes: 'Not sandbagged', - climbId: 'c76d2083-6b8f-524a-8fb8-76e1dc79833f', - userId: 'user123', - style: 'Lead', - attemptType: 'Fell/Hung', - dateClimbed: new Date('2012-12-12'), - grade: '5.7', - source: 'OB' - } - - await ticks.addTick(tick1) - - await expect( - ticks.addTick(tick1) - ).rejects.toThrow() - }) })