@remit/data-ports 0.0.77 → 0.0.78

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/data-ports",
3
- "version": "0.0.77",
3
+ "version": "0.0.78",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -234,12 +234,38 @@ export function calendarSuggestionRepositoryConformance(
234
234
  suggestion(accountConfigId, harness.makeId(), harness.makeId(), "uid"),
235
235
  );
236
236
 
237
+ const newerMessageId = harness.makeId();
237
238
  const retired = await repo.supersedeIfPending(
238
239
  accountConfigId,
239
240
  written.suggestionId,
241
+ newerMessageId,
240
242
  );
241
243
 
242
244
  assert.equal(retired?.state, CalendarSuggestionState.Superseded);
245
+ const reread = await repo.get(accountConfigId, written.suggestionId);
246
+ assert.equal(reread.supersededByMessageId, newerMessageId);
247
+ });
248
+
249
+ test("a re-read of the retired message keeps the revision that retired it", async () => {
250
+ const accountConfigId = harness.makeId();
251
+ const input = suggestion(
252
+ accountConfigId,
253
+ harness.makeId(),
254
+ harness.makeId(),
255
+ "uid",
256
+ );
257
+ const written = await repo.put(input);
258
+ const newerMessageId = harness.makeId();
259
+ await repo.supersedeIfPending(
260
+ accountConfigId,
261
+ written.suggestionId,
262
+ newerMessageId,
263
+ );
264
+
265
+ const rewritten = await repo.put(input);
266
+
267
+ assert.equal(rewritten.state, CalendarSuggestionState.Superseded);
268
+ assert.equal(rewritten.supersededByMessageId, newerMessageId);
243
269
  });
244
270
 
245
271
  test("supersedeIfPending leaves an answered card alone and says so", async () => {
@@ -258,11 +284,13 @@ export function calendarSuggestionRepositoryConformance(
258
284
  const retired = await repo.supersedeIfPending(
259
285
  accountConfigId,
260
286
  written.suggestionId,
287
+ harness.makeId(),
261
288
  );
262
289
 
263
290
  assert.equal(retired, null);
264
291
  const reread = await repo.get(accountConfigId, written.suggestionId);
265
292
  assert.equal(reread.state, CalendarSuggestionState.Accepted);
293
+ assert.equal(reread.supersededByMessageId, "");
266
294
  assert.equal(reread.acceptedCalendarObjectId, "cal-object-7");
267
295
  });
268
296
 
@@ -273,11 +301,58 @@ export function calendarSuggestionRepositoryConformance(
273
301
  );
274
302
 
275
303
  assert.equal(
276
- await repo.supersedeIfPending(harness.makeId(), written.suggestionId),
304
+ await repo.supersedeIfPending(
305
+ harness.makeId(),
306
+ written.suggestionId,
307
+ harness.makeId(),
308
+ ),
277
309
  null,
278
310
  );
279
311
  });
280
312
 
313
+ test("repointSuperseded moves a retired card to a later revision", async () => {
314
+ const accountConfigId = harness.makeId();
315
+ const written = await repo.put(
316
+ suggestion(accountConfigId, harness.makeId(), harness.makeId(), "uid"),
317
+ );
318
+ await repo.supersedeIfPending(
319
+ accountConfigId,
320
+ written.suggestionId,
321
+ harness.makeId(),
322
+ );
323
+ const newest = harness.makeId();
324
+
325
+ const repointed = await repo.repointSuperseded(
326
+ accountConfigId,
327
+ written.suggestionId,
328
+ newest,
329
+ );
330
+
331
+ assert.equal(repointed?.supersededByMessageId, newest);
332
+ const reread = await repo.get(accountConfigId, written.suggestionId);
333
+ assert.equal(reread.state, CalendarSuggestionState.Superseded);
334
+ assert.equal(reread.supersededByMessageId, newest);
335
+ });
336
+
337
+ test("repointSuperseded leaves a card that is not superseded alone", async () => {
338
+ const accountConfigId = harness.makeId();
339
+ const written = await repo.put(
340
+ suggestion(accountConfigId, harness.makeId(), harness.makeId(), "uid"),
341
+ );
342
+
343
+ assert.equal(
344
+ await repo.repointSuperseded(
345
+ accountConfigId,
346
+ written.suggestionId,
347
+ harness.makeId(),
348
+ ),
349
+ null,
350
+ );
351
+ const reread = await repo.get(accountConfigId, written.suggestionId);
352
+ assert.equal(reread.state, CalendarSuggestionState.Pending);
353
+ assert.equal(reread.supersededByMessageId, "");
354
+ });
355
+
281
356
  test("settle rejects a suggestion that is not there", async () => {
282
357
  const accountConfigId = harness.makeId();
283
358
  await assert.rejects(
@@ -56,8 +56,9 @@ export interface ICalendarSuggestionRepository {
56
56
  input: SettleCalendarSuggestionInput,
57
57
  ): Promise<CalendarSuggestionItem>;
58
58
  /**
59
- * Retires a card as `Superseded`, but only while it is still `Pending`.
60
- * Returns the retired row, or `null` when the card had already been
59
+ * Retires a card as `Superseded`, but only while it is still `Pending`, and
60
+ * records the message whose revision retired it so the card can open that
61
+ * one. Returns the retired row, or `null` when the card had already been
61
62
  * answered and nothing was written.
62
63
  *
63
64
  * A compare-and-set rather than a plain `settle` because the producer reads
@@ -69,5 +70,16 @@ export interface ICalendarSuggestionRepository {
69
70
  supersedeIfPending(
70
71
  accountConfigId: string,
71
72
  suggestionId: string,
73
+ supersededByMessageId: string,
74
+ ): Promise<CalendarSuggestionItem | null>;
75
+ /**
76
+ * Points a card already `Superseded` at a later revision, so every retired
77
+ * revision of an event opens the newest one. Returns the updated row, or
78
+ * `null` when the card is not superseded and nothing was written.
79
+ */
80
+ repointSuperseded(
81
+ accountConfigId: string,
82
+ suggestionId: string,
83
+ supersededByMessageId: string,
72
84
  ): Promise<CalendarSuggestionItem | null>;
73
85
  }
package/src/types.ts CHANGED
@@ -788,13 +788,15 @@ export type CalendarSuggestionItem = z.infer<typeof CalendarSuggestionSchema>;
788
788
  * `state` and `acceptedCalendarObjectId` are excluded: a producer only ever
789
789
  * writes a `Pending` suggestion, and the two fields that record what a person
790
790
  * decided move exclusively through `settle`, so a re-sync can never walk an
791
- * answered card back to Pending.
791
+ * answered card back to Pending. `supersededByMessageId` moves only through
792
+ * `supersedeIfPending`, with the state it explains.
792
793
  */
793
794
  export type PutCalendarSuggestionInput = Omit<
794
795
  CalendarSuggestionItem,
795
796
  | "suggestionId"
796
797
  | "state"
797
798
  | "acceptedCalendarObjectId"
799
+ | "supersededByMessageId"
798
800
  | "createdAt"
799
801
  | "updatedAt"
800
802
  >;