@volontariapp/domain-storage 0.6.0 → 0.7.0-snap-e10ff55

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.
Files changed (93) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/repositories/file-outbox.builders.d.ts +10 -0
  3. package/dist/repositories/file-outbox.builders.d.ts.map +1 -0
  4. package/dist/repositories/file-outbox.builders.js +45 -0
  5. package/dist/repositories/file-outbox.builders.js.map +1 -0
  6. package/dist/repositories/file-repository.types.d.ts +44 -0
  7. package/dist/repositories/file-repository.types.d.ts.map +1 -0
  8. package/dist/repositories/file-repository.types.js +2 -0
  9. package/dist/repositories/file-repository.types.js.map +1 -0
  10. package/dist/repositories/index.d.ts +4 -0
  11. package/dist/repositories/index.d.ts.map +1 -0
  12. package/dist/repositories/index.js +4 -0
  13. package/dist/repositories/index.js.map +1 -0
  14. package/dist/repositories/postgres-file.repository.d.ts +19 -0
  15. package/dist/repositories/postgres-file.repository.d.ts.map +1 -0
  16. package/dist/repositories/postgres-file.repository.js +127 -0
  17. package/dist/repositories/postgres-file.repository.js.map +1 -0
  18. package/dist/test/data-source.d.ts.map +1 -1
  19. package/dist/test/data-source.js +24 -4
  20. package/dist/test/data-source.js.map +1 -1
  21. package/dist/test/file-outbox.builders.unit.spec.d.ts +2 -0
  22. package/dist/test/file-outbox.builders.unit.spec.d.ts.map +1 -0
  23. package/dist/test/file-outbox.builders.unit.spec.js +61 -0
  24. package/dist/test/file-outbox.builders.unit.spec.js.map +1 -0
  25. package/dist/test/helpers/file-db.helper.d.ts +10 -0
  26. package/dist/test/helpers/file-db.helper.d.ts.map +1 -0
  27. package/dist/test/helpers/file-db.helper.js +20 -0
  28. package/dist/test/helpers/file-db.helper.js.map +1 -0
  29. package/dist/test/integration/file.model.int.spec.js +4 -1
  30. package/dist/test/integration/file.model.int.spec.js.map +1 -1
  31. package/dist/test/integration/postgres-file.repository.int.spec.d.ts +2 -0
  32. package/dist/test/integration/postgres-file.repository.int.spec.d.ts.map +1 -0
  33. package/dist/test/integration/postgres-file.repository.int.spec.js +452 -0
  34. package/dist/test/integration/postgres-file.repository.int.spec.js.map +1 -0
  35. package/dist/test/migrations/common/1776786226145-JobsOutboxAndEventQueue.d.ts +7 -0
  36. package/dist/test/migrations/common/1776786226145-JobsOutboxAndEventQueue.d.ts.map +1 -0
  37. package/dist/test/migrations/common/1776786226145-JobsOutboxAndEventQueue.js +12 -0
  38. package/dist/test/migrations/common/1776786226145-JobsOutboxAndEventQueue.js.map +1 -0
  39. package/dist/test/migrations/common/1776974876099-JobsOutboxAndEventQueueWithTraceId.d.ts +7 -0
  40. package/dist/test/migrations/common/1776974876099-JobsOutboxAndEventQueueWithTraceId.d.ts.map +1 -0
  41. package/dist/test/migrations/common/1776974876099-JobsOutboxAndEventQueueWithTraceId.js +12 -0
  42. package/dist/test/migrations/common/1776974876099-JobsOutboxAndEventQueueWithTraceId.js.map +1 -0
  43. package/dist/test/migrations/common/1777630647718-UpdateOutboxModels.d.ts +7 -0
  44. package/dist/test/migrations/common/1777630647718-UpdateOutboxModels.d.ts.map +1 -0
  45. package/dist/test/migrations/common/1777630647718-UpdateOutboxModels.js +12 -0
  46. package/dist/test/migrations/common/1777630647718-UpdateOutboxModels.js.map +1 -0
  47. package/dist/test/migrations/common/1777985367963-AddTargetServicesToEventQueue.d.ts +6 -0
  48. package/dist/test/migrations/common/1777985367963-AddTargetServicesToEventQueue.d.ts.map +1 -0
  49. package/dist/test/migrations/common/1777985367963-AddTargetServicesToEventQueue.js +76 -0
  50. package/dist/test/migrations/common/1777985367963-AddTargetServicesToEventQueue.js.map +1 -0
  51. package/dist/test/migrations/common/1779114963391-AddJobAudit.d.ts +7 -0
  52. package/dist/test/migrations/common/1779114963391-AddJobAudit.d.ts.map +1 -0
  53. package/dist/test/migrations/common/1779114963391-AddJobAudit.js +18 -0
  54. package/dist/test/migrations/common/1779114963391-AddJobAudit.js.map +1 -0
  55. package/dist/test/migrations/common/1779115100001-AddJobAuditStatusTrigger.d.ts +7 -0
  56. package/dist/test/migrations/common/1779115100001-AddJobAuditStatusTrigger.d.ts.map +1 -0
  57. package/dist/test/migrations/common/1779115100001-AddJobAuditStatusTrigger.js +45 -0
  58. package/dist/test/migrations/common/1779115100001-AddJobAuditStatusTrigger.js.map +1 -0
  59. package/dist/test/migrations/common/1779353596425-AddEmitterToJobAudit.d.ts +7 -0
  60. package/dist/test/migrations/common/1779353596425-AddEmitterToJobAudit.d.ts.map +1 -0
  61. package/dist/test/migrations/common/1779353596425-AddEmitterToJobAudit.js +18 -0
  62. package/dist/test/migrations/common/1779353596425-AddEmitterToJobAudit.js.map +1 -0
  63. package/dist/test/migrations/common/1779360000000-FixEventQueueStatusDefault.d.ts +7 -0
  64. package/dist/test/migrations/common/1779360000000-FixEventQueueStatusDefault.d.ts.map +1 -0
  65. package/dist/test/migrations/common/1779360000000-FixEventQueueStatusDefault.js +12 -0
  66. package/dist/test/migrations/common/1779360000000-FixEventQueueStatusDefault.js.map +1 -0
  67. package/dist/test/migrations/common/1779542033290-AddEmitterIdToOutbox.d.ts +6 -0
  68. package/dist/test/migrations/common/1779542033290-AddEmitterIdToOutbox.d.ts.map +1 -0
  69. package/dist/test/migrations/common/1779542033290-AddEmitterIdToOutbox.js +13 -0
  70. package/dist/test/migrations/common/1779542033290-AddEmitterIdToOutbox.js.map +1 -0
  71. package/dist/test/migrations/common/1779700000000-UpdateEventQueueTriggerTargetService.d.ts +6 -0
  72. package/dist/test/migrations/common/1779700000000-UpdateEventQueueTriggerTargetService.d.ts.map +1 -0
  73. package/dist/test/migrations/common/1779700000000-UpdateEventQueueTriggerTargetService.js +151 -0
  74. package/dist/test/migrations/common/1779700000000-UpdateEventQueueTriggerTargetService.js.map +1 -0
  75. package/dist/test/migrations/common/1779800000000-UpdateJobAuditStatusTrigger.d.ts +7 -0
  76. package/dist/test/migrations/common/1779800000000-UpdateJobAuditStatusTrigger.d.ts.map +1 -0
  77. package/dist/test/migrations/common/1779800000000-UpdateJobAuditStatusTrigger.js +72 -0
  78. package/dist/test/migrations/common/1779800000000-UpdateJobAuditStatusTrigger.js.map +1 -0
  79. package/dist/test/migrations/common/1781000000000-AddCorrelationIdToEventQueue.d.ts +7 -0
  80. package/dist/test/migrations/common/1781000000000-AddCorrelationIdToEventQueue.d.ts.map +1 -0
  81. package/dist/test/migrations/common/1781000000000-AddCorrelationIdToEventQueue.js +12 -0
  82. package/dist/test/migrations/common/1781000000000-AddCorrelationIdToEventQueue.js.map +1 -0
  83. package/dist/test/migrations/domain/1775000000000-EnableUuidExtension.d.ts +7 -0
  84. package/dist/test/migrations/domain/1775000000000-EnableUuidExtension.d.ts.map +1 -0
  85. package/dist/test/migrations/domain/1775000000000-EnableUuidExtension.js +9 -0
  86. package/dist/test/migrations/domain/1775000000000-EnableUuidExtension.js.map +1 -0
  87. package/dist/test/mocks/outbox-write-failure.mock.d.ts +4 -0
  88. package/dist/test/mocks/outbox-write-failure.mock.d.ts.map +1 -0
  89. package/dist/test/mocks/outbox-write-failure.mock.js +13 -0
  90. package/dist/test/mocks/outbox-write-failure.mock.js.map +1 -0
  91. package/dist/test/root-entrypoint.unit.spec.js +6 -0
  92. package/dist/test/root-entrypoint.unit.spec.js.map +1 -1
  93. package/package.json +10 -2
@@ -0,0 +1,452 @@
1
+ import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, jest, } from '@jest/globals';
2
+ import { StorageEventMessagingType, StorageJobType, StorageQueue } from '@volontariapp/messaging';
3
+ import { EntityType, FileId, FileStatus, RejectionReason, ScanStatus, ValidationMode, } from '../../index.js';
4
+ import { PostgresFileRepository, RESET_UPLOAD_DELAY_MINUTES } from '../../repositories/index.js';
5
+ import { closeTestDb, initializeTestDb, testDataSource, truncateAll } from '../data-source.js';
6
+ import { attachDirectly, insertFile, readEvents, readFile, readJobs, } from '../helpers/file-db.helper.js';
7
+ import { mockOutboxInsertFailure } from '../mocks/outbox-write-failure.mock.js';
8
+ const ONE_HOUR_MS = 60 * 60 * 1000;
9
+ const newId = () => FileId.generate().getValue();
10
+ const minutesUntilExpiry = async (fileId) => {
11
+ const rows = await testDataSource.query(`SELECT EXTRACT(EPOCH FROM (upload_expires_at - now())) / 60 AS minutes FROM files WHERE id = $1`, [fileId]);
12
+ return Number(rows.at(0)?.minutes);
13
+ };
14
+ describe('PostgresFileRepository (integration)', () => {
15
+ let repository;
16
+ let restoreOutbox;
17
+ beforeAll(async () => {
18
+ await initializeTestDb();
19
+ repository = new PostgresFileRepository(testDataSource);
20
+ });
21
+ afterAll(async () => {
22
+ await closeTestDb();
23
+ });
24
+ beforeEach(async () => {
25
+ await truncateAll();
26
+ });
27
+ afterEach(async () => {
28
+ jest.restoreAllMocks();
29
+ await restoreOutbox?.();
30
+ restoreOutbox = undefined;
31
+ });
32
+ describe('createPending()', () => {
33
+ it('inserts a PENDING file awaiting its upload, with no scan attempt', async () => {
34
+ const id = newId();
35
+ const ownerId = newId();
36
+ const uploadExpiresAt = new Date(Date.now() + ONE_HOUR_MS);
37
+ const created = await repository.createPending({
38
+ id,
39
+ ownerId,
40
+ entityType: EntityType.POST,
41
+ declaredMimeType: 'image/png',
42
+ declaredSize: 2048,
43
+ quarantineKey: `quarantine/${id}`,
44
+ validationMode: ValidationMode.ASYNC,
45
+ uploadExpiresAt,
46
+ });
47
+ expect(created.id).toBe(id);
48
+ const row = await readFile(id);
49
+ expect(row.ownerId).toBe(ownerId);
50
+ expect(row.status).toBe(FileStatus.PENDING);
51
+ expect(row.scanStatus).toBe(ScanStatus.AWAITING_UPLOAD);
52
+ expect(row.validationMode).toBe(ValidationMode.ASYNC);
53
+ expect(row.scanAttempts).toBe(0);
54
+ expect(row.entityId).toBeNull();
55
+ expect(row.declaredSize).toBe(2048);
56
+ expect(row.uploadExpiresAt.getTime()).toBe(uploadExpiresAt.getTime());
57
+ });
58
+ it('refuses an id that already exists', async () => {
59
+ const file = await insertFile();
60
+ await expect(repository.createPending({
61
+ id: file.id,
62
+ ownerId: file.ownerId,
63
+ entityType: file.entityType,
64
+ declaredMimeType: file.declaredMimeType,
65
+ declaredSize: file.declaredSize,
66
+ quarantineKey: file.quarantineKey,
67
+ validationMode: file.validationMode,
68
+ uploadExpiresAt: file.uploadExpiresAt,
69
+ })).rejects.toThrow();
70
+ });
71
+ });
72
+ describe('confirmUpload()', () => {
73
+ it('moves a SYNC file to SCANNING, counts the attempt and writes no job', async () => {
74
+ const file = await insertFile({ validationMode: ValidationMode.SYNC });
75
+ const result = await repository.confirmUpload({
76
+ fileId: file.id,
77
+ ownerId: file.ownerId,
78
+ actualSize: 1000,
79
+ });
80
+ expect(result).toEqual({ id: file.id, validationMode: ValidationMode.SYNC });
81
+ const row = await readFile(file.id);
82
+ expect(row.scanStatus).toBe(ScanStatus.SCANNING);
83
+ expect(row.actualSize).toBe(1000);
84
+ expect(row.scanAttempts).toBe(1);
85
+ expect(row.confirmedAt).toBeInstanceOf(Date);
86
+ expect(await readJobs()).toHaveLength(0);
87
+ });
88
+ it('writes one storage.scan_file job in the same transaction for an ASYNC file', async () => {
89
+ const file = await insertFile({ validationMode: ValidationMode.ASYNC });
90
+ const result = await repository.confirmUpload({
91
+ fileId: file.id,
92
+ ownerId: file.ownerId,
93
+ actualSize: 5_000_000,
94
+ });
95
+ expect(result?.validationMode).toBe(ValidationMode.ASYNC);
96
+ const jobs = await readJobs();
97
+ expect(jobs).toHaveLength(1);
98
+ expect(jobs[0]?.type).toBe(StorageJobType.SCAN_FILE);
99
+ expect(jobs[0]?.target).toBe(StorageQueue.STORAGE);
100
+ expect(jobs[0]?.payload).toEqual({ fileId: file.id });
101
+ expect(jobs[0]?.emitterId).toBe(file.ownerId);
102
+ });
103
+ it('is refused for another owner and for an unknown file, and changes nothing', async () => {
104
+ const file = await insertFile();
105
+ const otherOwner = await repository.confirmUpload({
106
+ fileId: file.id,
107
+ ownerId: newId(),
108
+ actualSize: 1,
109
+ });
110
+ const unknown = await repository.confirmUpload({
111
+ fileId: newId(),
112
+ ownerId: file.ownerId,
113
+ actualSize: 1,
114
+ });
115
+ expect(otherOwner).toBeNull();
116
+ expect(unknown).toBeNull();
117
+ const row = await readFile(file.id);
118
+ expect(row.scanStatus).toBe(ScanStatus.AWAITING_UPLOAD);
119
+ expect(row.scanAttempts).toBe(0);
120
+ });
121
+ it('is refused once the upload has expired', async () => {
122
+ const file = await insertFile({ uploadExpiresAt: new Date(Date.now() - ONE_HOUR_MS) });
123
+ const result = await repository.confirmUpload({
124
+ fileId: file.id,
125
+ ownerId: file.ownerId,
126
+ actualSize: 1,
127
+ });
128
+ expect(result).toBeNull();
129
+ expect((await readFile(file.id)).scanStatus).toBe(ScanStatus.AWAITING_UPLOAD);
130
+ });
131
+ it('is idempotent: a replay changes nothing and creates no second job', async () => {
132
+ const file = await insertFile({ validationMode: ValidationMode.ASYNC });
133
+ const input = { fileId: file.id, ownerId: file.ownerId, actualSize: 10 };
134
+ const first = await repository.confirmUpload(input);
135
+ const replay = await repository.confirmUpload(input);
136
+ expect(first).not.toBeNull();
137
+ expect(replay).toBeNull();
138
+ expect((await readFile(file.id)).scanAttempts).toBe(1);
139
+ expect(await readJobs()).toHaveLength(1);
140
+ });
141
+ it('increments scan_attempts at each confirmation after a reset', async () => {
142
+ const file = await insertFile({ validationMode: ValidationMode.SYNC });
143
+ const input = { fileId: file.id, ownerId: file.ownerId, actualSize: 10 };
144
+ await repository.confirmUpload(input);
145
+ await repository.resetToAwaitingUpload(file.id);
146
+ await repository.confirmUpload(input);
147
+ expect((await readFile(file.id)).scanAttempts).toBe(2);
148
+ });
149
+ it('rolls the transition back when the job cannot be written', async () => {
150
+ const file = await insertFile({ validationMode: ValidationMode.ASYNC });
151
+ restoreOutbox = await mockOutboxInsertFailure('jobs_outbox');
152
+ await expect(repository.confirmUpload({ fileId: file.id, ownerId: file.ownerId, actualSize: 10 })).rejects.toThrow('simulated outbox failure');
153
+ const row = await readFile(file.id);
154
+ expect(row.scanStatus).toBe(ScanStatus.AWAITING_UPLOAD);
155
+ expect(row.scanAttempts).toBe(0);
156
+ expect(row.confirmedAt).toBeNull();
157
+ expect(await readJobs()).toHaveLength(0);
158
+ });
159
+ });
160
+ describe('switchToAsync()', () => {
161
+ it('switches a SCANNING SYNC file to ASYNC and writes the scan job', async () => {
162
+ const file = await insertFile({
163
+ scanStatus: ScanStatus.SCANNING,
164
+ validationMode: ValidationMode.SYNC,
165
+ });
166
+ const switched = await repository.switchToAsync(file.id);
167
+ expect(switched).toBe(true);
168
+ expect((await readFile(file.id)).validationMode).toBe(ValidationMode.ASYNC);
169
+ const jobs = await readJobs();
170
+ expect(jobs).toHaveLength(1);
171
+ expect(jobs[0]?.payload).toEqual({ fileId: file.id });
172
+ });
173
+ it('is idempotent: a replay changes nothing and creates no second job', async () => {
174
+ const file = await insertFile({
175
+ scanStatus: ScanStatus.SCANNING,
176
+ validationMode: ValidationMode.SYNC,
177
+ });
178
+ await repository.switchToAsync(file.id);
179
+ const replay = await repository.switchToAsync(file.id);
180
+ expect(replay).toBe(false);
181
+ expect(await readJobs()).toHaveLength(1);
182
+ });
183
+ it('does not touch a file that is not SCANNING, nor one already ASYNC', async () => {
184
+ const awaiting = await insertFile({ validationMode: ValidationMode.SYNC });
185
+ const asyncScanning = await insertFile({
186
+ scanStatus: ScanStatus.SCANNING,
187
+ validationMode: ValidationMode.ASYNC,
188
+ });
189
+ expect(await repository.switchToAsync(awaiting.id)).toBe(false);
190
+ expect(await repository.switchToAsync(asyncScanning.id)).toBe(false);
191
+ expect((await readFile(awaiting.id)).validationMode).toBe(ValidationMode.SYNC);
192
+ expect(await readJobs()).toHaveLength(0);
193
+ });
194
+ it('rolls the switch back when the job cannot be written', async () => {
195
+ const file = await insertFile({
196
+ scanStatus: ScanStatus.SCANNING,
197
+ validationMode: ValidationMode.SYNC,
198
+ });
199
+ restoreOutbox = await mockOutboxInsertFailure('jobs_outbox');
200
+ await expect(repository.switchToAsync(file.id)).rejects.toThrow('simulated outbox failure');
201
+ expect((await readFile(file.id)).validationMode).toBe(ValidationMode.SYNC);
202
+ expect(await readJobs()).toHaveLength(0);
203
+ });
204
+ });
205
+ describe('resetToAwaitingUpload()', () => {
206
+ it('puts a SCANNING file back to AWAITING_UPLOAD, deadline pushed back by 15 minutes', async () => {
207
+ const file = await insertFile({
208
+ scanStatus: ScanStatus.SCANNING,
209
+ uploadExpiresAt: new Date(Date.now() - ONE_HOUR_MS),
210
+ });
211
+ const reset = await repository.resetToAwaitingUpload(file.id);
212
+ expect(reset).toBe(true);
213
+ expect((await readFile(file.id)).scanStatus).toBe(ScanStatus.AWAITING_UPLOAD);
214
+ const minutes = await minutesUntilExpiry(file.id);
215
+ expect(minutes).toBeGreaterThan(RESET_UPLOAD_DELAY_MINUTES - 1);
216
+ expect(minutes).toBeLessThanOrEqual(RESET_UPLOAD_DELAY_MINUTES);
217
+ });
218
+ it('never shortens a deadline that is already further away', async () => {
219
+ const file = await insertFile({
220
+ scanStatus: ScanStatus.SCANNING,
221
+ uploadExpiresAt: new Date(Date.now() + ONE_HOUR_MS),
222
+ });
223
+ await repository.resetToAwaitingUpload(file.id);
224
+ expect(await minutesUntilExpiry(file.id)).toBeGreaterThan(55);
225
+ });
226
+ it('is idempotent and refused for a file that is not SCANNING', async () => {
227
+ const file = await insertFile({
228
+ scanStatus: ScanStatus.SCANNING,
229
+ uploadExpiresAt: new Date(Date.now() - ONE_HOUR_MS),
230
+ });
231
+ const clean = await insertFile({ scanStatus: ScanStatus.CLEAN });
232
+ expect(await repository.resetToAwaitingUpload(file.id)).toBe(true);
233
+ const afterFirst = await minutesUntilExpiry(file.id);
234
+ expect(await repository.resetToAwaitingUpload(file.id)).toBe(false);
235
+ expect(await minutesUntilExpiry(file.id)).toBeCloseTo(afterFirst, 1);
236
+ expect(await repository.resetToAwaitingUpload(clean.id)).toBe(false);
237
+ expect((await readFile(clean.id)).scanStatus).toBe(ScanStatus.CLEAN);
238
+ });
239
+ });
240
+ describe('completeScan()', () => {
241
+ it.each([FileStatus.PENDING, FileStatus.RESERVED])('marks a %s file CLEAN without emitting anything', async (status) => {
242
+ const file = await insertFile({ scanStatus: ScanStatus.SCANNING, status });
243
+ const result = await repository.completeScan({ fileId: file.id, publicKey: 'public/x' });
244
+ expect(result).toEqual({ fileId: file.id, status, eventEmitted: false });
245
+ const row = await readFile(file.id);
246
+ expect(row.scanStatus).toBe(ScanStatus.CLEAN);
247
+ expect(row.publicKey).toBe('public/x');
248
+ expect(row.scannedAt).toBeInstanceOf(Date);
249
+ expect(await readEvents()).toHaveLength(0);
250
+ });
251
+ it('emits storage.file_scanned in event_queue for an ATTACHED file', async () => {
252
+ const entityId = newId();
253
+ const file = await insertFile({
254
+ scanStatus: ScanStatus.SCANNING,
255
+ status: FileStatus.ATTACHED,
256
+ entityId,
257
+ entityType: EntityType.EVENT_COVER,
258
+ });
259
+ const result = await repository.completeScan({ fileId: file.id, publicKey: 'public/x' });
260
+ expect(result).toEqual({ fileId: file.id, status: FileStatus.ATTACHED, eventEmitted: true });
261
+ const events = await readEvents();
262
+ expect(events).toHaveLength(1);
263
+ expect(events[0]?.type).toBe(StorageEventMessagingType.FILE_SCANNED);
264
+ expect(events[0]?.emitterId).toBe(file.ownerId);
265
+ expect(events[0]?.payload.after).toEqual({
266
+ fileId: file.id,
267
+ ownerId: file.ownerId,
268
+ entityType: EntityType.EVENT_COVER,
269
+ entityId,
270
+ });
271
+ });
272
+ it.each([FileStatus.ORPHANED, FileStatus.DELETED])('refuses a %s file and changes nothing', async (status) => {
273
+ const file = await insertFile({ scanStatus: ScanStatus.SCANNING, status });
274
+ const result = await repository.completeScan({ fileId: file.id, publicKey: 'public/x' });
275
+ expect(result).toBeNull();
276
+ const row = await readFile(file.id);
277
+ expect(row.scanStatus).toBe(ScanStatus.SCANNING);
278
+ expect(row.publicKey).toBeNull();
279
+ expect(await readEvents()).toHaveLength(0);
280
+ });
281
+ it('refuses a file that is not SCANNING', async () => {
282
+ const file = await insertFile({ scanStatus: ScanStatus.AWAITING_UPLOAD });
283
+ expect(await repository.completeScan({ fileId: file.id, publicKey: 'p' })).toBeNull();
284
+ expect(await repository.completeScan({ fileId: newId(), publicKey: 'p' })).toBeNull();
285
+ });
286
+ it('is idempotent: a replay changes nothing and emits no second event', async () => {
287
+ const file = await insertFile({
288
+ scanStatus: ScanStatus.SCANNING,
289
+ status: FileStatus.ATTACHED,
290
+ entityId: newId(),
291
+ });
292
+ const first = await repository.completeScan({ fileId: file.id, publicKey: 'public/a' });
293
+ const replay = await repository.completeScan({ fileId: file.id, publicKey: 'public/b' });
294
+ expect(first?.eventEmitted).toBe(true);
295
+ expect(replay).toBeNull();
296
+ expect((await readFile(file.id)).publicKey).toBe('public/a');
297
+ expect(await readEvents()).toHaveLength(1);
298
+ });
299
+ it('rolls the transition back when the event cannot be written', async () => {
300
+ const file = await insertFile({
301
+ scanStatus: ScanStatus.SCANNING,
302
+ status: FileStatus.ATTACHED,
303
+ entityId: newId(),
304
+ });
305
+ restoreOutbox = await mockOutboxInsertFailure('event_queue');
306
+ await expect(repository.completeScan({ fileId: file.id, publicKey: 'public/x' })).rejects.toThrow('simulated outbox failure');
307
+ const row = await readFile(file.id);
308
+ expect(row.scanStatus).toBe(ScanStatus.SCANNING);
309
+ expect(row.publicKey).toBeNull();
310
+ expect(await readEvents()).toHaveLength(0);
311
+ });
312
+ it('rolls the transition back when an ATTACHED file has no entity id', async () => {
313
+ const file = await insertFile({
314
+ scanStatus: ScanStatus.SCANNING,
315
+ status: FileStatus.ATTACHED,
316
+ entityId: null,
317
+ });
318
+ await expect(repository.completeScan({ fileId: file.id, publicKey: 'public/x' })).rejects.toThrow('has no entity_id');
319
+ expect((await readFile(file.id)).scanStatus).toBe(ScanStatus.SCANNING);
320
+ });
321
+ });
322
+ describe('rejectScan()', () => {
323
+ it('marks a PENDING file REJECTED with its reason and emits nothing', async () => {
324
+ const file = await insertFile({ scanStatus: ScanStatus.SCANNING });
325
+ const result = await repository.rejectScan({
326
+ fileId: file.id,
327
+ reason: RejectionReason.MALWARE,
328
+ });
329
+ expect(result).toEqual({ fileId: file.id, status: FileStatus.PENDING, eventEmitted: false });
330
+ const row = await readFile(file.id);
331
+ expect(row.scanStatus).toBe(ScanStatus.REJECTED);
332
+ expect(row.rejectionReason).toBe(RejectionReason.MALWARE);
333
+ expect(await readEvents()).toHaveLength(0);
334
+ });
335
+ it('emits storage.file_rejected with the reason for an ATTACHED file', async () => {
336
+ const entityId = newId();
337
+ const file = await insertFile({
338
+ scanStatus: ScanStatus.SCANNING,
339
+ status: FileStatus.ATTACHED,
340
+ entityId,
341
+ entityType: EntityType.POST,
342
+ });
343
+ const result = await repository.rejectScan({
344
+ fileId: file.id,
345
+ reason: RejectionReason.SCAN_TIMEOUT,
346
+ });
347
+ expect(result?.eventEmitted).toBe(true);
348
+ const events = await readEvents();
349
+ expect(events).toHaveLength(1);
350
+ expect(events[0]?.type).toBe(StorageEventMessagingType.FILE_REJECTED);
351
+ expect(events[0]?.payload.after).toEqual({
352
+ fileId: file.id,
353
+ ownerId: file.ownerId,
354
+ entityType: EntityType.POST,
355
+ entityId,
356
+ reason: RejectionReason.SCAN_TIMEOUT,
357
+ });
358
+ });
359
+ it.each([FileStatus.ORPHANED, FileStatus.DELETED])('refuses a %s file and changes nothing', async (status) => {
360
+ const file = await insertFile({ scanStatus: ScanStatus.SCANNING, status });
361
+ const result = await repository.rejectScan({
362
+ fileId: file.id,
363
+ reason: RejectionReason.MIME_MISMATCH,
364
+ });
365
+ expect(result).toBeNull();
366
+ const row = await readFile(file.id);
367
+ expect(row.scanStatus).toBe(ScanStatus.SCANNING);
368
+ expect(row.rejectionReason).toBeNull();
369
+ });
370
+ it('is idempotent: a replay changes nothing and emits no second event', async () => {
371
+ const file = await insertFile({
372
+ scanStatus: ScanStatus.SCANNING,
373
+ status: FileStatus.ATTACHED,
374
+ entityId: newId(),
375
+ });
376
+ await repository.rejectScan({ fileId: file.id, reason: RejectionReason.MALWARE });
377
+ const replay = await repository.rejectScan({
378
+ fileId: file.id,
379
+ reason: RejectionReason.UNDECODABLE,
380
+ });
381
+ expect(replay).toBeNull();
382
+ expect((await readFile(file.id)).rejectionReason).toBe(RejectionReason.MALWARE);
383
+ expect(await readEvents()).toHaveLength(1);
384
+ });
385
+ it('rolls the transition back when the event cannot be written', async () => {
386
+ const file = await insertFile({
387
+ scanStatus: ScanStatus.SCANNING,
388
+ status: FileStatus.ATTACHED,
389
+ entityId: newId(),
390
+ });
391
+ restoreOutbox = await mockOutboxInsertFailure('event_queue');
392
+ await expect(repository.rejectScan({ fileId: file.id, reason: RejectionReason.MALWARE })).rejects.toThrow('simulated outbox failure');
393
+ const row = await readFile(file.id);
394
+ expect(row.scanStatus).toBe(ScanStatus.SCANNING);
395
+ expect(row.rejectionReason).toBeNull();
396
+ expect(await readEvents()).toHaveLength(0);
397
+ });
398
+ });
399
+ describe('emission rule, both orders', () => {
400
+ it('scan then attachment: the scan does not emit, the attachment sees a terminal scan_status', async () => {
401
+ const file = await insertFile({ scanStatus: ScanStatus.SCANNING });
402
+ const scan = await repository.completeScan({ fileId: file.id, publicKey: 'public/x' });
403
+ const scanStatusSeenByAttachment = await attachDirectly(file.id, newId());
404
+ expect(scan?.eventEmitted).toBe(false);
405
+ expect(await readEvents()).toHaveLength(0);
406
+ expect(scanStatusSeenByAttachment).toBe(ScanStatus.CLEAN);
407
+ });
408
+ it('attachment then scan: the attachment sees SCANNING, the scan emits', async () => {
409
+ const file = await insertFile({ scanStatus: ScanStatus.SCANNING });
410
+ const scanStatusSeenByAttachment = await attachDirectly(file.id, newId());
411
+ const scan = await repository.completeScan({ fileId: file.id, publicKey: 'public/x' });
412
+ expect(scanStatusSeenByAttachment).toBe(ScanStatus.SCANNING);
413
+ expect(scan?.eventEmitted).toBe(true);
414
+ expect(await readEvents()).toHaveLength(1);
415
+ });
416
+ it('rejection follows the same two orders', async () => {
417
+ const scanFirst = await insertFile({ scanStatus: ScanStatus.SCANNING });
418
+ const attachFirst = await insertFile({ scanStatus: ScanStatus.SCANNING });
419
+ const early = await repository.rejectScan({
420
+ fileId: scanFirst.id,
421
+ reason: RejectionReason.MALWARE,
422
+ });
423
+ const seenByLateAttachment = await attachDirectly(scanFirst.id, newId());
424
+ await attachDirectly(attachFirst.id, newId());
425
+ const late = await repository.rejectScan({
426
+ fileId: attachFirst.id,
427
+ reason: RejectionReason.MALWARE,
428
+ });
429
+ expect(early?.eventEmitted).toBe(false);
430
+ expect(seenByLateAttachment).toBe(ScanStatus.REJECTED);
431
+ expect(late?.eventEmitted).toBe(true);
432
+ expect(await readEvents()).toHaveLength(1);
433
+ });
434
+ it('a concurrent scan and attachment emit exactly once, whatever the interleaving', async () => {
435
+ const runs = 25;
436
+ let emissions = 0;
437
+ for (let run = 0; run < runs; run += 1) {
438
+ const file = await insertFile({ scanStatus: ScanStatus.SCANNING });
439
+ const [scan, scanStatusSeenByAttachment] = await Promise.all([
440
+ repository.completeScan({ fileId: file.id, publicKey: 'public/x' }),
441
+ attachDirectly(file.id, newId()),
442
+ ]);
443
+ const emittedByScan = scan?.eventEmitted === true ? 1 : 0;
444
+ const emittedByAttachment = scanStatusSeenByAttachment === ScanStatus.CLEAN ? 1 : 0;
445
+ expect(emittedByScan + emittedByAttachment).toBe(1);
446
+ emissions += emittedByScan;
447
+ }
448
+ expect(await readEvents()).toHaveLength(emissions);
449
+ });
450
+ });
451
+ });
452
+ //# sourceMappingURL=postgres-file.repository.int.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-file.repository.int.spec.js","sourceRoot":"","sources":["../../../src/test/integration/postgres-file.repository.int.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+ export declare class JobsOutboxAndEventQueue1776786226145 implements MigrationInterface {
3
+ name: string;
4
+ up(queryRunner: QueryRunner): Promise<void>;
5
+ down(queryRunner: QueryRunner): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=1776786226145-JobsOutboxAndEventQueue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1776786226145-JobsOutboxAndEventQueue.d.ts","sourceRoot":"","sources":["../../../../src/test/migrations/common/1776786226145-JobsOutboxAndEventQueue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE/D,qBAAa,oCAAqC,YAAW,kBAAkB;IAC7E,IAAI,SAA0C;IAEjC,EAAE,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAS3C,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAI3D"}
@@ -0,0 +1,12 @@
1
+ export class JobsOutboxAndEventQueue1776786226145 {
2
+ name = 'JobsOutboxAndEventQueue1776786226145';
3
+ async up(queryRunner) {
4
+ await queryRunner.query(`CREATE TABLE "event_queue" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "status" character varying(20) NOT NULL DEFAULT 'PENDING', "attempts" integer NOT NULL DEFAULT '0', "lastError" text, "type" character varying(100) NOT NULL, "emitter" character varying(100) NOT NULL, "updated_at" TIMESTAMP NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "version" integer NOT NULL, "payload" jsonb NOT NULL, "processed_at" TIMESTAMP, CONSTRAINT "PK_f2ab43ee6a569a89ba286db2fa6" PRIMARY KEY ("id"))`);
5
+ await queryRunner.query(`CREATE TABLE "jobs_outbox" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "status" character varying(20) NOT NULL DEFAULT 'PENDING', "attempts" integer NOT NULL DEFAULT '0', "lastError" text, "type" character varying(100) NOT NULL, "emitter" character varying(100) NOT NULL, "updated_at" TIMESTAMP NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "target" character varying(100) NOT NULL, "payload" jsonb NOT NULL, "scheduled_at" TIMESTAMP NOT NULL, CONSTRAINT "PK_7172b6dd5767f423ecb44d9fb57" PRIMARY KEY ("id"))`);
6
+ }
7
+ async down(queryRunner) {
8
+ await queryRunner.query(`DROP TABLE "jobs_outbox"`);
9
+ await queryRunner.query(`DROP TABLE "event_queue"`);
10
+ }
11
+ }
12
+ //# sourceMappingURL=1776786226145-JobsOutboxAndEventQueue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1776786226145-JobsOutboxAndEventQueue.js","sourceRoot":"","sources":["../../../../src/test/migrations/common/1776786226145-JobsOutboxAndEventQueue.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,oCAAoC;IAC/C,IAAI,GAAG,sCAAsC,CAAC;IAEvC,KAAK,CAAC,EAAE,CAAC,WAAwB;QACtC,MAAM,WAAW,CAAC,KAAK,CACrB,qfAAqf,CACtf,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,4gBAA4gB,CAC7gB,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,WAAwB;QACxC,MAAM,WAAW,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;QACpD,MAAM,WAAW,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACtD,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+ export declare class JobsOutboxAndEventQueueWithTraceId1776974876099 implements MigrationInterface {
3
+ name: string;
4
+ up(queryRunner: QueryRunner): Promise<void>;
5
+ down(queryRunner: QueryRunner): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=1776974876099-JobsOutboxAndEventQueueWithTraceId.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1776974876099-JobsOutboxAndEventQueueWithTraceId.d.ts","sourceRoot":"","sources":["../../../../src/test/migrations/common/1776974876099-JobsOutboxAndEventQueueWithTraceId.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE/D,qBAAa,+CAAgD,YAAW,kBAAkB;IACxF,IAAI,SAAqD;IAE5C,EAAE,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3C,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAI3D"}
@@ -0,0 +1,12 @@
1
+ export class JobsOutboxAndEventQueueWithTraceId1776974876099 {
2
+ name = 'JobsOutboxAndEventQueueWithTraceId1776974876099';
3
+ async up(queryRunner) {
4
+ await queryRunner.query(`ALTER TABLE "event_queue" ADD "traceId" uuid`);
5
+ await queryRunner.query(`ALTER TABLE "jobs_outbox" ADD "traceId" uuid`);
6
+ }
7
+ async down(queryRunner) {
8
+ await queryRunner.query(`ALTER TABLE "jobs_outbox" DROP COLUMN "traceId"`);
9
+ await queryRunner.query(`ALTER TABLE "event_queue" DROP COLUMN "traceId"`);
10
+ }
11
+ }
12
+ //# sourceMappingURL=1776974876099-JobsOutboxAndEventQueueWithTraceId.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1776974876099-JobsOutboxAndEventQueueWithTraceId.js","sourceRoot":"","sources":["../../../../src/test/migrations/common/1776974876099-JobsOutboxAndEventQueueWithTraceId.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,+CAA+C;IAC1D,IAAI,GAAG,iDAAiD,CAAC;IAElD,KAAK,CAAC,EAAE,CAAC,WAAwB;QACtC,MAAM,WAAW,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;QACxE,MAAM,WAAW,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAC1E,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,WAAwB;QACxC,MAAM,WAAW,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QAC3E,MAAM,WAAW,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;IAC7E,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+ export declare class UpdateOutboxModels1777630647718 implements MigrationInterface {
3
+ name: string;
4
+ up(queryRunner: QueryRunner): Promise<void>;
5
+ down(queryRunner: QueryRunner): Promise<void>;
6
+ }
7
+ //# sourceMappingURL=1777630647718-UpdateOutboxModels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1777630647718-UpdateOutboxModels.d.ts","sourceRoot":"","sources":["../../../../src/test/migrations/common/1777630647718-UpdateOutboxModels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE/D,qBAAa,+BAAgC,YAAW,kBAAkB;IACxE,IAAI,SAAqC;IAE5B,EAAE,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3C,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAI3D"}
@@ -0,0 +1,12 @@
1
+ export class UpdateOutboxModels1777630647718 {
2
+ name = 'UpdateOutboxModels1777630647718';
3
+ async up(queryRunner) {
4
+ await queryRunner.query(`ALTER TABLE "event_queue" ALTER COLUMN "updated_at" DROP NOT NULL`);
5
+ await queryRunner.query(`ALTER TABLE "jobs_outbox" ALTER COLUMN "updated_at" DROP NOT NULL`);
6
+ }
7
+ async down(queryRunner) {
8
+ await queryRunner.query(`ALTER TABLE "jobs_outbox" ALTER COLUMN "updated_at" SET NOT NULL`);
9
+ await queryRunner.query(`ALTER TABLE "event_queue" ALTER COLUMN "updated_at" SET NOT NULL`);
10
+ }
11
+ }
12
+ //# sourceMappingURL=1777630647718-UpdateOutboxModels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1777630647718-UpdateOutboxModels.js","sourceRoot":"","sources":["../../../../src/test/migrations/common/1777630647718-UpdateOutboxModels.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,+BAA+B;IAC1C,IAAI,GAAG,iCAAiC,CAAC;IAElC,KAAK,CAAC,EAAE,CAAC,WAAwB;QACtC,MAAM,WAAW,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;QAC7F,MAAM,WAAW,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC;IAC/F,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,WAAwB;QACxC,MAAM,WAAW,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;QAC5F,MAAM,WAAW,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;IAC9F,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+ export declare class AddTargetServicesToEventQueue1777985367963 implements MigrationInterface {
3
+ up(queryRunner: QueryRunner): Promise<void>;
4
+ down(queryRunner: QueryRunner): Promise<void>;
5
+ }
6
+ //# sourceMappingURL=1777985367963-AddTargetServicesToEventQueue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1777985367963-AddTargetServicesToEventQueue.d.ts","sourceRoot":"","sources":["../../../../src/test/migrations/common/1777985367963-AddTargetServicesToEventQueue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE/D,qBAAa,0CAA2C,YAAW,kBAAkB;IACtE,EAAE,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IA8D3C,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CAoB3D"}