Skip to content

Commit 45328cc

Browse files
Merge branch 'main' into fix-create-instances-for-recurring-someday-events-web-1058
2 parents 56ead83 + 2f316fc commit 45328cc

26 files changed

+968
-1308
lines changed

packages/backend/src/common/services/mongo.service.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ class MongoService {
212212
return this.#internalClient!.client.startSession(options);
213213
}
214214

215-
objectId(id: string): ObjectId {
215+
objectId(id?: string): ObjectId {
216216
return new ObjectId(id);
217217
}
218218

packages/backend/src/event/classes/compass.event.generator.ts

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@ import {
1515
Schema_Event_Recur_Instance,
1616
} from "@core/types/event.types";
1717
import { CompassEventRRule } from "@core/util/event/compass.event.rrule";
18-
import { isAllDay, parseCompassEventDate } from "@core/util/event/event.util";
18+
import {
19+
isAllDay,
20+
isBase,
21+
parseCompassEventDate,
22+
} from "@core/util/event/event.util";
23+
import { GenericError } from "@backend/common/errors/generic/generic.errors";
24+
import { error } from "@backend/common/errors/handlers/error.handler";
1925
import mongoService from "@backend/common/services/mongo.service";
2026

2127
export class CompassEventFactory {
@@ -203,21 +209,23 @@ export class CompassEventFactory {
203209
const payload = event.payload as Schema_Event;
204210
const hasRRule = Array.isArray(payload.recurrence?.rule);
205211
const hasRecurringBase = !!payload.recurrence?.eventId;
206-
const isSomeday = payload.isSomeday;
207212
const nullRecurrence = payload.recurrence?.rule === null;
208-
const baseToStandaloneTransition = nullRecurrence && hasRecurringBase;
209-
const baseToSomedayTransition = isSomeday && hasRecurringBase;
210213

211-
if (baseToStandaloneTransition || baseToSomedayTransition) {
212-
return CompassEventFactory.genAllEvents(
213-
{
214-
...event,
215-
applyTo: RecurringEventUpdateScope.ALL_EVENTS,
216-
} as CompassAllEvents,
217-
session,
214+
const dbEvent = await CompassEventFactory.findCompassEvent(
215+
event.payload._id,
216+
event.payload.user,
217+
session,
218+
false,
219+
);
220+
221+
if (dbEvent && isBase(dbEvent)) {
222+
throw error(
223+
GenericError.BadRequest,
224+
`You cannot edit a base event with this option(${RecurringEventUpdateScope.THIS_EVENT})`,
218225
);
219226
}
220227

228+
if (nullRecurrence) delete payload.recurrence?.rule;
221229
if (hasRRule && hasRecurringBase) delete payload.recurrence?.rule;
222230
if (nullRecurrence && !hasRecurringBase) delete payload.recurrence;
223231

packages/backend/src/event/classes/compass.event.parser.test.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { RRule } from "rrule";
2+
import { GCAL_MAX_RECURRENCES } from "@core/constants/core.constants";
23
import {
34
CalendarProvider,
45
Categories_Recurrence,
@@ -25,7 +26,7 @@ import {
2526
testCompassSeries,
2627
testCompassSeriesInGcal,
2728
testCompassStandaloneEvent,
28-
} from "./compass.event.parser.test.util";
29+
} from "@backend/event/classes/compass.event.parser.test.util";
2930

3031
describe.each([{ calendarProvider: CalendarProvider.GOOGLE }])(
3132
"CompassEventParser - $calendarProvider calendar",
@@ -157,7 +158,10 @@ describe.each([{ calendarProvider: CalendarProvider.GOOGLE }])(
157158

158159
await parser.createEvent();
159160

160-
const { baseEvent } = await testCompassSeries(payload);
161+
const { baseEvent } = await testCompassSeries(
162+
payload,
163+
GCAL_MAX_RECURRENCES,
164+
);
161165

162166
switch (calendarProvider) {
163167
case CalendarProvider.GOOGLE:
@@ -274,8 +278,10 @@ describe.each([{ calendarProvider: CalendarProvider.GOOGLE }])(
274278

275279
await parser.createEvent();
276280

277-
const { baseEvent: somedayBaseEvent } =
278-
await testCompassSeries(payload);
281+
const { baseEvent: somedayBaseEvent } = await testCompassSeries(
282+
payload,
283+
10,
284+
);
279285

280286
switch (calendarProvider) {
281287
case CalendarProvider.GOOGLE:

packages/backend/src/event/classes/compass.event.parser.test.util.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ export async function testCompassSeries(
111111
)
112112
.toArray()) as Array<WithId<Omit<Schema_Event_Recur_Instance, "_id">>>;
113113

114-
expect(instances).toHaveLength(payload.isSomeday ? 0 : instanceCount);
114+
expect(instances).toHaveLength(instanceCount);
115115

116116
expect(instances).toEqual(
117117
expect.arrayContaining(

packages/backend/src/event/classes/compass.event.parser.ts

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -166,14 +166,15 @@ export class CompassEventParser {
166166
);
167167

168168
// create series in calendar providers
169+
const { isSomeday } = this.#event;
169170
const calendarProvider = CalendarProvider.GOOGLE;
171+
const provider = isSomeday ? CalendarProvider.COMPASS : calendarProvider;
170172
const userId = this.#event.user!;
171173

172-
const compassEvent = this.isBase
173-
? this.rrule!.base(calendarProvider)
174-
: this.#event;
174+
const compassEvent = (
175+
this.isBase ? this.rrule?.base(provider) : this.#event
176+
)!;
175177

176-
const { isSomeday } = compassEvent;
177178
const operation: Operation_Sync = `${this.#getCategory()}_CREATED`;
178179
const operationSummary = this.#getOperationSummary(operation);
179180

@@ -235,8 +236,10 @@ export class CompassEventParser {
235236
`UPDATING ${this.getTransitionString()}: ${this.#event._id.toString()} (Compass)`,
236237
);
237238

239+
const { isSomeday } = this.#event;
238240
const calendarProvider = CalendarProvider.GOOGLE;
239-
const compassEvent = this.rrule!.base(calendarProvider);
241+
const provider = isSomeday ? CalendarProvider.COMPASS : calendarProvider;
242+
const compassEvent = this.rrule!.base(provider);
240243
const userId = compassEvent.user!;
241244
const operation: Operation_Sync = `${this.category}_UPDATED`;
242245
const operationSummary = this.#getOperationSummary(operation);
@@ -309,6 +312,8 @@ export class CompassEventParser {
309312

310313
if (!cEvent) return [];
311314

315+
if (isSomeday) return [operationSummary];
316+
312317
switch (calendarProvider) {
313318
case CalendarProvider.GOOGLE: {
314319
const event = await _updateGcal(userId, cEvent as Schema_Event_Core);
@@ -363,13 +368,15 @@ export class CompassEventParser {
363368
const operation: Operation_Sync = `${this.category}_UPDATED`;
364369
const operationSummary = this.#getOperationSummary(operation);
365370

366-
await _createCompassEvent(
371+
const cEvent = await _createCompassEvent(
367372
{ ...this.#event, user, isSomeday: true },
368373
calendarProvider,
369374
null,
370375
session,
371376
);
372377

378+
if (!cEvent) return [];
379+
373380
switch (calendarProvider) {
374381
case CalendarProvider.GOOGLE: {
375382
const ok = await _deleteGcal(user, this.#event.gEventId!);
@@ -381,7 +388,9 @@ export class CompassEventParser {
381388
}
382389
}
383390

384-
async seriesToSomeday(session?: ClientSession): Promise<Event_Transition[]> {
391+
async seriesToSomedaySeries(
392+
session?: ClientSession,
393+
): Promise<Event_Transition[]> {
385394
this.#logger.info(
386395
`UPDATING ${this.getTransitionString()}: ${this.#event._id.toString()} (Compass)`,
387396
);
@@ -393,18 +402,20 @@ export class CompassEventParser {
393402

394403
await _deleteSeries(user, this.#event._id.toString(), session, true);
395404

396-
await _createCompassEvent(
405+
const cEvent = await _createCompassEvent(
397406
{
398407
...this.#event,
399408
user,
400409
recurrence: this.#event.recurrence,
401410
isSomeday: true,
402411
},
403412
calendarProvider,
404-
null,
413+
this.rrule,
405414
session,
406415
);
407416

417+
if (!cEvent) return [];
418+
408419
switch (calendarProvider) {
409420
case CalendarProvider.GOOGLE: {
410421
const ok = await _deleteGcal(user, this.#event.gEventId!);
@@ -425,6 +436,7 @@ export class CompassEventParser {
425436

426437
const calendarProvider = CalendarProvider.GOOGLE;
427438
const userId = this.#event.user!;
439+
const { isSomeday } = this.#event;
428440
const operation: Operation_Sync = `${this.category}_UPDATED`;
429441
const operationSummary = this.#getOperationSummary(operation);
430442

@@ -437,6 +449,8 @@ export class CompassEventParser {
437449

438450
if (!cEvent) return [];
439451

452+
if (isSomeday) return [operationSummary];
453+
440454
switch (calendarProvider) {
441455
case CalendarProvider.GOOGLE: {
442456
Object.assign(cEvent, { recurrence: null });
@@ -459,6 +473,7 @@ export class CompassEventParser {
459473

460474
const calendarProvider = CalendarProvider.GOOGLE;
461475
const userId = this.#event.user!;
476+
const { isSomeday } = this.#event;
462477
const operation: Operation_Sync = `${this.category}_UPDATED`;
463478
const operationSummary = this.#getOperationSummary(operation);
464479

@@ -471,6 +486,8 @@ export class CompassEventParser {
471486

472487
if (!cEvent) return [];
473488

489+
if (isSomeday) return [operationSummary];
490+
474491
switch (calendarProvider) {
475492
case CalendarProvider.GOOGLE: {
476493
const event = await _updateGcal(userId, cEvent);
@@ -489,11 +506,14 @@ export class CompassEventParser {
489506

490507
const calendarProvider = CalendarProvider.GOOGLE;
491508
const userId = this.#event.user!;
509+
const { isSomeday } = this.#event;
492510
const operation: Operation_Sync = `${this.category}_DELETED`;
493511
const operationSummary = this.#getOperationSummary(operation);
494512

495513
await _deleteSeries(userId, this.#event._id.toString(), session);
496514

515+
if (isSomeday) return [operationSummary];
516+
497517
switch (calendarProvider) {
498518
case CalendarProvider.GOOGLE: {
499519
const ok = await _deleteGcal(userId, this.#event.gEventId!);
@@ -511,6 +531,8 @@ export class CompassEventParser {
511531
return Categories_Recurrence.STANDALONE_SOMEDAY;
512532
case this.#isBase && this.#event.isSomeday:
513533
return Categories_Recurrence.RECURRENCE_BASE_SOMEDAY;
534+
case this.#isInstance && this.#event.isSomeday:
535+
return Categories_Recurrence.RECURRENCE_INSTANCE_SOMEDAY;
514536
case this.isStandalone:
515537
return Categories_Recurrence.STANDALONE;
516538
case this.isBase:
@@ -528,6 +550,8 @@ export class CompassEventParser {
528550
return Categories_Recurrence.STANDALONE_SOMEDAY;
529551
case this.#isDbBase && this.#dbEvent?.isSomeday:
530552
return Categories_Recurrence.RECURRENCE_BASE_SOMEDAY;
553+
case this.#isDbInstance && this.#dbEvent?.isSomeday:
554+
return Categories_Recurrence.RECURRENCE_INSTANCE_SOMEDAY;
531555
case this.#isDbStandalone:
532556
return Categories_Recurrence.STANDALONE;
533557
case this.#isDbBase:

packages/backend/src/event/classes/gcal.event.parser.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { faker } from "@faker-js/faker";
33
import { Categories_Recurrence } from "@core/types/event.types";
44
import { WithGcalId, gSchema$Event } from "@core/types/gcal";
55
import dayjs from "@core/util/date/dayjs";
6-
import { isBase, isExistingInstance } from "@core/util/event/event.util";
6+
import { isBase, isInstance } from "@core/util/event/event.util";
77
import { UserDriver } from "@backend/__tests__/drivers/user.driver";
88
import {
99
cleanupCollections,
@@ -546,7 +546,7 @@ describe("GcalEventParser", () => {
546546
.toArray();
547547

548548
const dbSeriesBase = dbSeries.find(isBase);
549-
const dbSeriesInstance = dbSeries.find(isExistingInstance);
549+
const dbSeriesInstance = dbSeries.find(isInstance);
550550

551551
expect(changes).toHaveLength(1);
552552

packages/backend/src/event/classes/gcal.event.parser.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
import { WithGcalId, gSchema$Event, gSchema$EventBase } from "@core/types/gcal";
1212
import {
1313
isBase,
14-
isExistingInstance,
14+
isInstance,
1515
isRegularEvent,
1616
} from "@core/util/event/event.util";
1717
import {
@@ -125,7 +125,7 @@ export class GcalEventParser {
125125
this.#compassEvent = cEvent ?? null;
126126

127127
this.#isInstance = isInstanceGCalEvent(this.#event);
128-
this.#isCompassInstance = cEvent ? isExistingInstance(cEvent) : false;
128+
this.#isCompassInstance = cEvent ? isInstance(cEvent) : false;
129129

130130
this.#isBase = isBaseGCalEvent(this.#event);
131131
this.#isCompassBase = cEvent ? isBase(cEvent) : false;

packages/backend/src/event/classes/gcal.event.rrule.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { recurring } from "@core/__mocks__/v1/events/gcal/gcal.recurring";
55
import { GCAL_MAX_RECURRENCES } from "@core/constants/core.constants";
66
import { gSchema$EventBase } from "@core/types/gcal";
77
import dayjs from "@core/util/date/dayjs";
8-
import { isExistingInstance } from "@core/util/event/event.util";
8+
import { isInstance } from "@core/util/event/event.util";
99
import {
1010
isBaseGCalEvent,
1111
isInstanceGCalEvent,
@@ -281,7 +281,7 @@ describe("GcalEventRRule: ", () => {
281281
expect(instance.user).toEqual(userId);
282282
expect(instance.startDate).toBeDefined();
283283
expect(instance.endDate).toBeDefined();
284-
expect(isExistingInstance(instance)).toEqual(true);
284+
expect(isInstance(instance)).toEqual(true);
285285

286286
expect(instance.startDate).toEqual(
287287
startDate.add(index, "day").format(dateFormat),
@@ -313,7 +313,7 @@ describe("GcalEventRRule: ", () => {
313313
expect(instance.user).toEqual(userId);
314314
expect(instance.startDate).toBeDefined();
315315
expect(instance.endDate).toBeDefined();
316-
expect(isExistingInstance(instance)).toEqual(true);
316+
expect(isInstance(instance)).toEqual(true);
317317

318318
expect(instance.startDate).toEqual(
319319
startDate.add(index, "day").format(dateFormat),

packages/backend/src/event/controllers/event.controller.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
CompassCoreEventSchema,
88
CompassEvent,
99
CompassEventStatus,
10+
CompassThisEvent,
1011
Params_DeleteMany,
1112
Payload_Order,
1213
RecurringEventUpdateScope,
@@ -70,7 +71,7 @@ class EventController {
7071

7172
await this.processEvents([
7273
{
73-
payload: event as CompassEvent["payload"],
74+
payload: event as CompassThisEvent["payload"],
7475
status: CompassEventStatus.CANCELLED,
7576
applyTo: applyTo as RecurringEventUpdateScope.THIS_EVENT,
7677
},
@@ -141,7 +142,7 @@ class EventController {
141142
const { body, query, params, session } = req;
142143
const user = session?.getUserId() as string;
143144
const _id = params["id"] as string;
144-
const payload = { ...body, user, _id } as CompassEvent["payload"];
145+
const payload = { ...body, user, _id } as CompassThisEvent["payload"];
145146
const applyTo = query["applyTo"] as RecurringEventUpdateScope.THIS_EVENT;
146147

147148
await this.processEvents([

0 commit comments

Comments
 (0)