@remit/backend 0.0.133 → 0.0.134

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remit/backend",
3
- "version": "0.0.133",
3
+ "version": "0.0.134",
4
4
  "description": "Remit Mail Inspector API backend",
5
5
  "license": "MIT",
6
6
  "author": "",
@@ -10,6 +10,7 @@ import type {
10
10
  SettleCalendarSuggestionInput,
11
11
  } from "@remit/data-ports";
12
12
  import {
13
+ CalendarInviteAnswer,
13
14
  CalendarInviteMethod,
14
15
  CalendarSuggestionSource,
15
16
  CalendarSuggestionState,
@@ -354,6 +355,7 @@ const INVITATION = [
354
355
  const putSuggestion = (
355
356
  accountConfigId: string,
356
357
  messageId: string,
358
+ method: CalendarSuggestionItem["method"] = CalendarInviteMethod.Request,
357
359
  ): Promise<CalendarSuggestionItem> =>
358
360
  client.calendarSuggestion.put({
359
361
  accountConfigId,
@@ -361,7 +363,7 @@ const putSuggestion = (
361
363
  bodyPartId: "part-1",
362
364
  icalUid: "invite@example.test",
363
365
  sequence: 0,
364
- method: CalendarInviteMethod.Request,
366
+ method,
365
367
  source: CalendarSuggestionSource.IcalendarPart,
366
368
  summary: "Quarterly review",
367
369
  dtStart: "2026-09-01T10:00:00+02:00",
@@ -506,6 +508,45 @@ describe("POST /calendar-suggestions/{suggestionId}/accept", () => {
506
508
  assert.equal(untouched.state, CalendarSuggestionState.Pending);
507
509
  assert.equal(untouched.acceptedCalendarObjectId, "");
508
510
  });
511
+
512
+ test("refuses a maybe to a cancellation, before writing anything", async () => {
513
+ const { accountConfigId, event } = anAccount();
514
+ const calendar = await client.calendarCollection.create({
515
+ accountConfigId,
516
+ urlSegment: "default",
517
+ displayName: "Calendar",
518
+ });
519
+ const card = await putSuggestion(
520
+ accountConfigId,
521
+ "msg-cancel-maybe",
522
+ CalendarInviteMethod.Cancel,
523
+ );
524
+
525
+ await assert.rejects(
526
+ () =>
527
+ acceptSuggestion(
528
+ contextOf({
529
+ params: { suggestionId: card.suggestionId },
530
+ requestBody: {
531
+ calendarId: calendar.calendarId,
532
+ answer: CalendarInviteAnswer.Tentative,
533
+ },
534
+ }),
535
+ event,
536
+ ),
537
+ (error: unknown) => (error as { statusCode?: number }).statusCode === 400,
538
+ );
539
+
540
+ assert.deepEqual(
541
+ await client.calendarObject.listByCalendar(calendar.calendarId),
542
+ [],
543
+ );
544
+ const untouched = await client.calendarSuggestion.get(
545
+ accountConfigId,
546
+ card.suggestionId,
547
+ );
548
+ assert.equal(untouched.state, CalendarSuggestionState.Pending);
549
+ });
509
550
  });
510
551
 
511
552
  describe("POST /calendar-suggestions/{suggestionId}/dismiss", () => {
@@ -1,4 +1,7 @@
1
- import type { CalendarSuggestionResponse } from "@remit/api-openapi-types";
1
+ import type {
2
+ CalendarInviteAnswer as CalendarInviteAnswerValue,
3
+ CalendarSuggestionResponse,
4
+ } from "@remit/api-openapi-types";
2
5
  import { acceptCalendarSuggestion } from "@remit/calendar-service";
3
6
  import {
4
7
  type CalendarSuggestionItem,
@@ -9,6 +12,8 @@ import {
9
12
  } from "@remit/data-ports";
10
13
  import { BadRequestError } from "@remit/data-ports/errors";
11
14
  import {
15
+ CalendarInviteAnswer,
16
+ CalendarInviteMethod,
12
17
  CalendarSource,
13
18
  CalendarSuggestionState,
14
19
  FilterClauseField,
@@ -211,8 +216,10 @@ export const CalendarSuggestionActionOperations: Record<
211
216
  const { suggestionId } = context.request.params as {
212
217
  suggestionId: string;
213
218
  };
214
- const { calendarId } = context.request.requestBody as {
219
+ const { calendarId, answer = CalendarInviteAnswer.Accepted } = context
220
+ .request.requestBody as {
215
221
  calendarId: string;
222
+ answer?: CalendarInviteAnswerValue;
216
223
  };
217
224
 
218
225
  const client = await getClient();
@@ -220,7 +227,20 @@ export const CalendarSuggestionActionOperations: Record<
220
227
  accountConfigId,
221
228
  suggestionId,
222
229
  );
223
- assertSettleable(suggestion, CalendarSuggestionState.Accepted);
230
+ if (
231
+ answer === CalendarInviteAnswer.Tentative &&
232
+ suggestion.method === CalendarInviteMethod.Cancel
233
+ ) {
234
+ throw new BadRequestError(
235
+ "This is a cancellation, so there is nothing to answer maybe to.",
236
+ );
237
+ }
238
+ assertSettleable(
239
+ suggestion,
240
+ answer === CalendarInviteAnswer.Tentative
241
+ ? CalendarSuggestionState.Tentative
242
+ : CalendarSuggestionState.Accepted,
243
+ );
224
244
 
225
245
  // Reads the collection through the caller's own account config, so a
226
246
  // calendarId naming somebody else's collection is a 404 before anything
@@ -240,6 +260,7 @@ export const CalendarSuggestionActionOperations: Record<
240
260
  calendarId,
241
261
  suggestion,
242
262
  attendee: await accountEmailForMessage(client, suggestion.messageId),
263
+ answer,
243
264
  });
244
265
  if (!accepted.ok) {
245
266
  throw new BadRequestError(accepted.error.message);