@nicnocquee/dataqueue 1.16.0 → 1.18.0

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.
@@ -51,7 +51,7 @@ describe('processor integration', () => {
51
51
  typeC: vi.fn(async () => {}),
52
52
  };
53
53
  const jobId = await queue.addJob<TestPayloadMap, 'test'>(pool, {
54
- job_type: 'test',
54
+ jobType: 'test',
55
55
  payload: { foo: 'bar' },
56
56
  });
57
57
  const job = await queue.getJob<TestPayloadMap, 'test'>(pool, jobId);
@@ -80,7 +80,7 @@ describe('processor integration', () => {
80
80
  typeC: vi.fn(async () => {}),
81
81
  };
82
82
  const jobId = await queue.addJob<TestPayloadMap, 'fail'>(pool, {
83
- job_type: 'fail',
83
+ jobType: 'fail',
84
84
  payload: {},
85
85
  });
86
86
  const job = await queue.getJob<TestPayloadMap, 'fail'>(pool, jobId);
@@ -88,8 +88,8 @@ describe('processor integration', () => {
88
88
  await processJobWithHandlers(pool, job!, handlers);
89
89
  const failed = await queue.getJob(pool, jobId);
90
90
  expect(failed?.status).toBe('failed');
91
- expect(failed?.error_history?.[0]?.message).toBe('fail!');
92
- expect(failed?.failure_reason).toBe('handler_error');
91
+ expect(failed?.errorHistory?.[0]?.message).toBe('fail!');
92
+ expect(failed?.failureReason).toBe('handler_error');
93
93
  });
94
94
 
95
95
  it('should mark job as failed if no handler registered', async () => {
@@ -106,7 +106,7 @@ describe('processor integration', () => {
106
106
  typeC: vi.fn(async () => {}),
107
107
  };
108
108
  const jobId = await queue.addJob<TestPayloadMap, 'missing'>(pool, {
109
- job_type: 'missing',
109
+ jobType: 'missing',
110
110
  payload: {},
111
111
  });
112
112
  const job = await queue.getJob<TestPayloadMap, 'missing'>(pool, jobId);
@@ -115,10 +115,10 @@ describe('processor integration', () => {
115
115
  await processJobWithHandlers(pool, job!, handlers);
116
116
  const failed = await queue.getJob(pool, jobId);
117
117
  expect(failed?.status).toBe('failed');
118
- expect(failed?.error_history?.[0]?.message).toContain(
118
+ expect(failed?.errorHistory?.[0]?.message).toContain(
119
119
  'No handler registered',
120
120
  );
121
- expect(failed?.failure_reason).toBe('no_handler');
121
+ expect(failed?.failureReason).toBe('no_handler');
122
122
  });
123
123
 
124
124
  it('should process a batch of jobs', async () => {
@@ -135,11 +135,11 @@ describe('processor integration', () => {
135
135
  };
136
136
  const ids = await Promise.all([
137
137
  queue.addJob<TestPayloadMap, 'batch'>(pool, {
138
- job_type: 'batch',
138
+ jobType: 'batch',
139
139
  payload: { i: 1 },
140
140
  }),
141
141
  queue.addJob<TestPayloadMap, 'batch'>(pool, {
142
- job_type: 'batch',
142
+ jobType: 'batch',
143
143
  payload: { i: 2 },
144
144
  }),
145
145
  ]);
@@ -172,7 +172,7 @@ describe('processor integration', () => {
172
172
  typeC: vi.fn(async () => {}),
173
173
  };
174
174
  await queue.addJob<TestPayloadMap, 'proc'>(pool, {
175
- job_type: 'proc',
175
+ jobType: 'proc',
176
176
  payload: { x: 1 },
177
177
  });
178
178
  const processor = createProcessor(pool, handlers, { pollInterval: 200 });
@@ -182,7 +182,7 @@ describe('processor integration', () => {
182
182
  processor.stop();
183
183
  expect(processor.isRunning()).toBe(false);
184
184
  const jobs = await queue.getJobsByStatus(pool, 'completed');
185
- expect(jobs.some((j) => j.job_type === 'proc')).toBe(true);
185
+ expect(jobs.some((j) => j.jobType === 'proc')).toBe(true);
186
186
  });
187
187
 
188
188
  it('should process only jobs of a specific job type with processBatch', async () => {
@@ -199,15 +199,15 @@ describe('processor integration', () => {
199
199
  typeC: vi.fn(async () => {}),
200
200
  };
201
201
  const idA1 = await queue.addJob<TestPayloadMap, 'typeA'>(pool, {
202
- job_type: 'typeA',
202
+ jobType: 'typeA',
203
203
  payload: { n: 1 },
204
204
  });
205
205
  const idA2 = await queue.addJob<TestPayloadMap, 'typeA'>(pool, {
206
- job_type: 'typeA',
206
+ jobType: 'typeA',
207
207
  payload: { n: 2 },
208
208
  });
209
209
  const idB1 = await queue.addJob<TestPayloadMap, 'typeB'>(pool, {
210
- job_type: 'typeB',
210
+ jobType: 'typeB',
211
211
  payload: { n: 3 },
212
212
  });
213
213
  // Only process typeA
@@ -246,15 +246,15 @@ describe('processor integration', () => {
246
246
  typeC: handlerC,
247
247
  };
248
248
  const idA = await queue.addJob<TestPayloadMap, 'typeA'>(pool, {
249
- job_type: 'typeA',
249
+ jobType: 'typeA',
250
250
  payload: { n: 1 },
251
251
  });
252
252
  const idB = await queue.addJob<TestPayloadMap, 'typeB'>(pool, {
253
- job_type: 'typeB',
253
+ jobType: 'typeB',
254
254
  payload: { n: 2 },
255
255
  });
256
256
  const idC = await queue.addJob<TestPayloadMap, 'typeC'>(pool, {
257
- job_type: 'typeC',
257
+ jobType: 'typeC',
258
258
  payload: { n: 3 },
259
259
  });
260
260
  // Only process typeA and typeC
@@ -293,11 +293,11 @@ describe('processor integration', () => {
293
293
  typeC: vi.fn(async () => {}),
294
294
  };
295
295
  const idA = await queue.addJob<TestPayloadMap, 'typeA'>(pool, {
296
- job_type: 'typeA',
296
+ jobType: 'typeA',
297
297
  payload: { n: 1 },
298
298
  });
299
299
  const idB = await queue.addJob<TestPayloadMap, 'typeB'>(pool, {
300
- job_type: 'typeB',
300
+ jobType: 'typeB',
301
301
  payload: { n: 2 },
302
302
  });
303
303
  const processor = createProcessor(pool, handlers, {
@@ -335,7 +335,7 @@ describe('concurrency option', () => {
335
335
  async function addJobs(n: number) {
336
336
  for (let i = 0; i < n; i++) {
337
337
  await queue.addJob<{ test: {} }, 'test'>(pool, {
338
- job_type: 'test',
338
+ jobType: 'test',
339
339
  payload: {},
340
340
  });
341
341
  }
@@ -444,7 +444,7 @@ describe('per-job timeout', () => {
444
444
  test: handler,
445
445
  };
446
446
  const jobId = await queue.addJob<{ test: {} }, 'test'>(pool, {
447
- job_type: 'test',
447
+ jobType: 'test',
448
448
  payload: {},
449
449
  timeoutMs: 50, // 50ms
450
450
  });
@@ -453,8 +453,8 @@ describe('per-job timeout', () => {
453
453
  await processJobWithHandlers(pool, job!, handlers);
454
454
  const failed = await queue.getJob(pool, jobId);
455
455
  expect(failed?.status).toBe('failed');
456
- expect(failed?.error_history?.[0]?.message).toContain('timed out');
457
- expect(failed?.failure_reason).toBe(FailureReason.Timeout);
456
+ expect(failed?.errorHistory?.[0]?.message).toContain('timed out');
457
+ expect(failed?.failureReason).toBe(FailureReason.Timeout);
458
458
  });
459
459
 
460
460
  it('should complete the job if handler finishes before timeoutMs', async () => {
@@ -465,7 +465,7 @@ describe('per-job timeout', () => {
465
465
  test: handler,
466
466
  };
467
467
  const jobId = await queue.addJob<{ test: {} }, 'test'>(pool, {
468
- job_type: 'test',
468
+ jobType: 'test',
469
469
  payload: {},
470
470
  timeoutMs: 200, // 200ms
471
471
  });
package/src/processor.ts CHANGED
@@ -27,25 +27,25 @@ export async function processJobWithHandlers<
27
27
  job: JobRecord<PayloadMap, T>,
28
28
  jobHandlers: JobHandlers<PayloadMap>,
29
29
  ): Promise<void> {
30
- const handler = jobHandlers[job.job_type];
30
+ const handler = jobHandlers[job.jobType];
31
31
 
32
32
  if (!handler) {
33
33
  await setPendingReasonForUnpickedJobs(
34
34
  pool,
35
- `No handler registered for job type: ${job.job_type}`,
36
- job.job_type,
35
+ `No handler registered for job type: ${job.jobType}`,
36
+ job.jobType,
37
37
  );
38
38
  await failJob(
39
39
  pool,
40
40
  job.id,
41
- new Error(`No handler registered for job type: ${job.job_type}`),
41
+ new Error(`No handler registered for job type: ${job.jobType}`),
42
42
  FailureReason.NoHandler,
43
43
  );
44
44
  return;
45
45
  }
46
46
 
47
47
  // Per-job timeout logic
48
- const timeoutMs = job.timeout_ms ?? undefined;
48
+ const timeoutMs = job.timeoutMs ?? undefined;
49
49
  let timeoutId: NodeJS.Timeout | undefined;
50
50
  const controller = new AbortController();
51
51
  try {
package/src/queue.test.ts CHANGED
@@ -2,7 +2,8 @@ import { Pool } from 'pg';
2
2
  import { describe, expect, it, beforeEach, afterEach } from 'vitest';
3
3
  import * as queue from './queue.js';
4
4
  import { createTestDbAndPool, destroyTestDb } from './test-util.js';
5
- import { JobEventType } from './types.js';
5
+ import { JobEvent, JobEventType } from './types.js';
6
+ import { objectKeysToCamelCase } from './utils.js';
6
7
 
7
8
  // Example integration test setup
8
9
 
@@ -23,13 +24,13 @@ describe('queue integration', () => {
23
24
 
24
25
  it('should add a job and retrieve it', async () => {
25
26
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
26
- job_type: 'email',
27
+ jobType: 'email',
27
28
  payload: { to: 'test@example.com' },
28
29
  });
29
30
  expect(typeof jobId).toBe('number');
30
31
  const job = await queue.getJob(pool, jobId);
31
32
  expect(job).not.toBeNull();
32
- expect(job?.job_type).toBe('email');
33
+ expect(job?.jobType).toBe('email');
33
34
  expect(job?.payload).toEqual({ to: 'test@example.com' });
34
35
  });
35
36
 
@@ -38,12 +39,12 @@ describe('queue integration', () => {
38
39
  const jobId1 = await queue.addJob<{ email: { to: string } }, 'email'>(
39
40
  pool,
40
41
  {
41
- job_type: 'email',
42
+ jobType: 'email',
42
43
  payload: { to: 'a@example.com' },
43
44
  },
44
45
  );
45
46
  const jobId2 = await queue.addJob<{ sms: { to: string } }, 'sms'>(pool, {
46
- job_type: 'sms',
47
+ jobType: 'sms',
47
48
  payload: { to: 'b@example.com' },
48
49
  });
49
50
  // All jobs should be 'pending' by default
@@ -55,7 +56,7 @@ describe('queue integration', () => {
55
56
 
56
57
  it('should retry a failed job', async () => {
57
58
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
58
- job_type: 'email',
59
+ jobType: 'email',
59
60
  payload: { to: 'fail@example.com' },
60
61
  });
61
62
  // Mark as failed
@@ -70,7 +71,7 @@ describe('queue integration', () => {
70
71
 
71
72
  it('should mark a job as completed', async () => {
72
73
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
73
- job_type: 'email',
74
+ jobType: 'email',
74
75
  payload: { to: 'done@example.com' },
75
76
  });
76
77
  await queue.completeJob(pool, jobId);
@@ -79,18 +80,18 @@ describe('queue integration', () => {
79
80
  });
80
81
 
81
82
  it('should get the next batch of jobs to process', async () => {
82
- // Add jobs (do not set run_at, use DB default)
83
+ // Add jobs (do not set runAt, use DB default)
83
84
  const jobId1 = await queue.addJob<{ email: { to: string } }, 'email'>(
84
85
  pool,
85
86
  {
86
- job_type: 'email',
87
+ jobType: 'email',
87
88
  payload: { to: 'batch1@example.com' },
88
89
  },
89
90
  );
90
91
  const jobId2 = await queue.addJob<{ email: { to: string } }, 'email'>(
91
92
  pool,
92
93
  {
93
- job_type: 'email',
94
+ jobType: 'email',
94
95
  payload: { to: 'batch2@example.com' },
95
96
  },
96
97
  );
@@ -107,9 +108,9 @@ describe('queue integration', () => {
107
108
  // Add a job scheduled 1 day in the future
108
109
  const futureDate = new Date(Date.now() + 24 * 60 * 60 * 1000);
109
110
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
110
- job_type: 'email',
111
+ jobType: 'email',
111
112
  payload: { to: 'future@example.com' },
112
- run_at: futureDate,
113
+ runAt: futureDate,
113
114
  });
114
115
  const jobs = await queue.getNextBatch(pool, 'worker-2', 1);
115
116
  const ids = jobs.map((j) => j.id);
@@ -122,7 +123,7 @@ describe('queue integration', () => {
122
123
  it('should cleanup old completed jobs', async () => {
123
124
  // Add and complete a job
124
125
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
125
- job_type: 'email',
126
+ jobType: 'email',
126
127
  payload: { to: 'cleanup@example.com' },
127
128
  });
128
129
  await queue.completeJob(pool, jobId);
@@ -140,7 +141,7 @@ describe('queue integration', () => {
140
141
 
141
142
  it('should cancel a scheduled job', async () => {
142
143
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
143
- job_type: 'email',
144
+ jobType: 'email',
144
145
  payload: { to: 'cancelme@example.com' },
145
146
  });
146
147
  await queue.cancelJob(pool, jobId);
@@ -151,7 +152,7 @@ describe('queue integration', () => {
151
152
  const jobId2 = await queue.addJob<{ email: { to: string } }, 'email'>(
152
153
  pool,
153
154
  {
154
- job_type: 'email',
155
+ jobType: 'email',
155
156
  payload: { to: 'done@example.com' },
156
157
  },
157
158
  );
@@ -166,21 +167,21 @@ describe('queue integration', () => {
166
167
  const jobId1 = await queue.addJob<{ email: { to: string } }, 'email'>(
167
168
  pool,
168
169
  {
169
- job_type: 'email',
170
+ jobType: 'email',
170
171
  payload: { to: 'cancelall1@example.com' },
171
172
  },
172
173
  );
173
174
  const jobId2 = await queue.addJob<{ email: { to: string } }, 'email'>(
174
175
  pool,
175
176
  {
176
- job_type: 'email',
177
+ jobType: 'email',
177
178
  payload: { to: 'cancelall2@example.com' },
178
179
  },
179
180
  );
180
181
  const jobId3 = await queue.addJob<{ email: { to: string } }, 'email'>(
181
182
  pool,
182
183
  {
183
- job_type: 'email',
184
+ jobType: 'email',
184
185
  payload: { to: 'cancelall3@example.com' },
185
186
  },
186
187
  );
@@ -188,7 +189,7 @@ describe('queue integration', () => {
188
189
  const jobId4 = await queue.addJob<{ email: { to: string } }, 'email'>(
189
190
  pool,
190
191
  {
191
- job_type: 'email',
192
+ jobType: 'email',
192
193
  payload: { to: 'done@example.com' },
193
194
  },
194
195
  );
@@ -211,17 +212,17 @@ describe('queue integration', () => {
211
212
  expect(completedJob?.status).toBe('completed');
212
213
  });
213
214
 
214
- it('should store and retrieve run_at in UTC without timezone shift', async () => {
215
+ it('should store and retrieve runAt in UTC without timezone shift', async () => {
215
216
  const utcDate = new Date(Date.UTC(2030, 0, 1, 12, 0, 0, 0)); // 2030-01-01T12:00:00.000Z
216
217
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
217
- job_type: 'email',
218
+ jobType: 'email',
218
219
  payload: { to: 'utc@example.com' },
219
- run_at: utcDate,
220
+ runAt: utcDate,
220
221
  });
221
222
  const job = await queue.getJob(pool, jobId);
222
223
  expect(job).not.toBeNull();
223
- // The run_at value should match exactly (toISOString) what we inserted
224
- expect(job?.run_at.toISOString()).toBe(utcDate.toISOString());
224
+ // The runAt value should match exactly (toISOString) what we inserted
225
+ expect(job?.runAt.toISOString()).toBe(utcDate.toISOString());
225
226
  });
226
227
 
227
228
  it('should get all jobs', async () => {
@@ -229,16 +230,16 @@ describe('queue integration', () => {
229
230
  const jobId1 = await queue.addJob<{ email: { to: string } }, 'email'>(
230
231
  pool,
231
232
  {
232
- job_type: 'email',
233
+ jobType: 'email',
233
234
  payload: { to: 'all1@example.com' },
234
235
  },
235
236
  );
236
237
  const jobId2 = await queue.addJob<{ sms: { to: string } }, 'sms'>(pool, {
237
- job_type: 'sms',
238
+ jobType: 'sms',
238
239
  payload: { to: 'all2@example.com' },
239
240
  });
240
241
  const jobId3 = await queue.addJob<{ push: { to: string } }, 'push'>(pool, {
241
- job_type: 'push',
242
+ jobType: 'push',
242
243
  payload: { to: 'all3@example.com' },
243
244
  });
244
245
  // Get all jobs
@@ -249,26 +250,26 @@ describe('queue integration', () => {
249
250
  expect(ids).toContain(jobId3);
250
251
  // Should return correct job data
251
252
  const job1 = jobs.find((j) => j.id === jobId1);
252
- expect(job1?.job_type).toBe('email');
253
+ expect(job1?.jobType).toBe('email');
253
254
  expect(job1?.payload).toEqual({ to: 'all1@example.com' });
254
255
  });
255
256
 
256
257
  it('should support pagination in getAllJobs', async () => {
257
258
  // Add four jobs
258
259
  await queue.addJob<{ a: { n: number } }, 'a'>(pool, {
259
- job_type: 'a',
260
+ jobType: 'a',
260
261
  payload: { n: 1 },
261
262
  });
262
263
  await queue.addJob<{ b: { n: number } }, 'b'>(pool, {
263
- job_type: 'b',
264
+ jobType: 'b',
264
265
  payload: { n: 2 },
265
266
  });
266
267
  await queue.addJob<{ c: { n: number } }, 'c'>(pool, {
267
- job_type: 'c',
268
+ jobType: 'c',
268
269
  payload: { n: 3 },
269
270
  });
270
271
  await queue.addJob<{ d: { n: number } }, 'd'>(pool, {
271
- job_type: 'd',
272
+ jobType: 'd',
272
273
  payload: { n: 4 },
273
274
  });
274
275
  // Get first two jobs
@@ -285,7 +286,7 @@ describe('queue integration', () => {
285
286
 
286
287
  it('should track error history for failed jobs', async () => {
287
288
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
288
- job_type: 'email',
289
+ jobType: 'email',
289
290
  payload: { to: 'failhistory@example.com' },
290
291
  });
291
292
  // Fail the job twice with different errors
@@ -293,18 +294,18 @@ describe('queue integration', () => {
293
294
  await queue.failJob(pool, jobId, new Error('second error'));
294
295
  const job = await queue.getJob(pool, jobId);
295
296
  expect(job?.status).toBe('failed');
296
- expect(Array.isArray(job?.error_history)).toBe(true);
297
- expect(job?.error_history?.length).toBeGreaterThanOrEqual(2);
298
- expect(job?.error_history?.[0].message).toBe('first error');
299
- expect(job?.error_history?.[1].message).toBe('second error');
300
- expect(typeof job?.error_history?.[0].timestamp).toBe('string');
301
- expect(typeof job?.error_history?.[1].timestamp).toBe('string');
297
+ expect(Array.isArray(job?.errorHistory)).toBe(true);
298
+ expect(job?.errorHistory?.length).toBeGreaterThanOrEqual(2);
299
+ expect(job?.errorHistory?.[0].message).toBe('first error');
300
+ expect(job?.errorHistory?.[1].message).toBe('second error');
301
+ expect(typeof job?.errorHistory?.[0].timestamp).toBe('string');
302
+ expect(typeof job?.errorHistory?.[1].timestamp).toBe('string');
302
303
  });
303
304
 
304
305
  it('should reclaim stuck processing jobs', async () => {
305
306
  // Add a job and set it to processing with an old locked_at
306
307
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
307
- job_type: 'email',
308
+ jobType: 'email',
308
309
  payload: { to: 'stuck@example.com' },
309
310
  });
310
311
  await pool.query(
@@ -319,8 +320,8 @@ describe('queue integration', () => {
319
320
  expect(reclaimed).toBeGreaterThanOrEqual(1);
320
321
  job = await queue.getJob(pool, jobId);
321
322
  expect(job?.status).toBe('pending');
322
- expect(job?.locked_at).toBeNull();
323
- expect(job?.locked_by).toBeNull();
323
+ expect(job?.lockedAt).toBeNull();
324
+ expect(job?.lockedBy).toBeNull();
324
325
  });
325
326
  });
326
327
 
@@ -344,18 +345,18 @@ describe('job event tracking', () => {
344
345
  'SELECT * FROM job_events WHERE job_id = $1 ORDER BY created_at ASC',
345
346
  [jobId],
346
347
  );
347
- return res.rows;
348
+ return res.rows.map((row) => objectKeysToCamelCase(row) as JobEvent);
348
349
  }
349
350
 
350
351
  it('records added and processing events', async () => {
351
352
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
352
- job_type: 'email',
353
+ jobType: 'email',
353
354
  payload: { to: 'event1@example.com' },
354
355
  });
355
356
  // Pick up for processing
356
357
  await queue.getNextBatch(pool, 'worker-evt', 1);
357
358
  const events = await getEvents(jobId);
358
- expect(events.map((e) => e.event_type)).toEqual([
359
+ expect(events.map((e) => e.eventType)).toEqual([
359
360
  JobEventType.Added,
360
361
  JobEventType.Processing,
361
362
  ]);
@@ -363,39 +364,39 @@ describe('job event tracking', () => {
363
364
 
364
365
  it('records completed event', async () => {
365
366
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
366
- job_type: 'email',
367
+ jobType: 'email',
367
368
  payload: { to: 'event2@example.com' },
368
369
  });
369
370
  await queue.getNextBatch(pool, 'worker-evt', 1);
370
371
  await queue.completeJob(pool, jobId);
371
372
  const events = await getEvents(jobId);
372
- expect(events.map((e) => e.event_type)).toContain(JobEventType.Completed);
373
+ expect(events.map((e) => e.eventType)).toContain(JobEventType.Completed);
373
374
  });
374
375
 
375
376
  it('records failed and retried events', async () => {
376
377
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
377
- job_type: 'email',
378
+ jobType: 'email',
378
379
  payload: { to: 'event3@example.com' },
379
380
  });
380
381
  await queue.getNextBatch(pool, 'worker-evt', 1);
381
382
  await queue.failJob(pool, jobId, new Error('fail for event'));
382
383
  await queue.retryJob(pool, jobId);
383
384
  const events = await getEvents(jobId);
384
- expect(events.map((e) => e.event_type)).toEqual(
385
+ expect(events.map((e) => e.eventType)).toEqual(
385
386
  expect.arrayContaining([JobEventType.Failed, JobEventType.Retried]),
386
387
  );
387
- const failEvent = events.find((e) => e.event_type === JobEventType.Failed);
388
- expect(failEvent.metadata).toMatchObject({ message: 'fail for event' });
388
+ const failEvent = events.find((e) => e.eventType === JobEventType.Failed);
389
+ expect(failEvent?.metadata).toMatchObject({ message: 'fail for event' });
389
390
  });
390
391
 
391
392
  it('records cancelled event', async () => {
392
393
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
393
- job_type: 'email',
394
+ jobType: 'email',
394
395
  payload: { to: 'event4@example.com' },
395
396
  });
396
397
  await queue.cancelJob(pool, jobId);
397
398
  const events = await getEvents(jobId);
398
- expect(events.map((e) => e.event_type)).toContain(JobEventType.Cancelled);
399
+ expect(events.map((e) => e.eventType)).toContain(JobEventType.Cancelled);
399
400
  });
400
401
  });
401
402
 
@@ -421,41 +422,41 @@ describe('job lifecycle timestamp columns', () => {
421
422
  return res.rows[0];
422
423
  }
423
424
 
424
- it('sets started_at when job is picked up for processing', async () => {
425
+ it('sets startedAt when job is picked up for processing', async () => {
425
426
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
426
- job_type: 'email',
427
+ jobType: 'email',
427
428
  payload: { to: 'ts1@example.com' },
428
429
  });
429
430
  await queue.getNextBatch(pool, 'worker-ts', 1);
430
431
  const job = await getJobRow(jobId);
431
- expect(job.started_at).not.toBeNull();
432
+ expect(job.startedAt).not.toBeNull();
432
433
  });
433
434
 
434
- it('sets completed_at when job is completed', async () => {
435
+ it('sets completedAt when job is completed', async () => {
435
436
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
436
- job_type: 'email',
437
+ jobType: 'email',
437
438
  payload: { to: 'ts2@example.com' },
438
439
  });
439
440
  await queue.getNextBatch(pool, 'worker-ts', 1);
440
441
  await queue.completeJob(pool, jobId);
441
442
  const job = await getJobRow(jobId);
442
- expect(job.completed_at).not.toBeNull();
443
+ expect(job.completedAt).not.toBeNull();
443
444
  });
444
445
 
445
- it('sets last_failed_at when job fails', async () => {
446
+ it('sets lastFailedAt when job fails', async () => {
446
447
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
447
- job_type: 'email',
448
+ jobType: 'email',
448
449
  payload: { to: 'ts3@example.com' },
449
450
  });
450
451
  await queue.getNextBatch(pool, 'worker-ts', 1);
451
452
  await queue.failJob(pool, jobId, new Error('fail for ts'));
452
453
  const job = await getJobRow(jobId);
453
- expect(job.last_failed_at).not.toBeNull();
454
+ expect(job.lastFailedAt).not.toBeNull();
454
455
  });
455
456
 
456
- it('sets last_retried_at when job is retried', async () => {
457
+ it('sets lastRetriedAt when job is retried', async () => {
457
458
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
458
- job_type: 'email',
459
+ jobType: 'email',
459
460
  payload: { to: 'ts4@example.com' },
460
461
  });
461
462
  await queue.getNextBatch(pool, 'worker-ts', 1);
@@ -465,25 +466,25 @@ describe('job lifecycle timestamp columns', () => {
465
466
  'UPDATE job_queue SET next_attempt_at = NOW() WHERE id = $1',
466
467
  [jobId],
467
468
  );
468
- // Pick up for processing again (should increment attempts and set last_retried_at)
469
+ // Pick up for processing again (should increment attempts and set lastRetriedAt)
469
470
  await queue.getNextBatch(pool, 'worker-ts', 1);
470
471
  const job = await getJobRow(jobId);
471
- expect(job.last_retried_at).not.toBeNull();
472
+ expect(job.lastRetriedAt).not.toBeNull();
472
473
  });
473
474
 
474
- it('sets last_cancelled_at when job is cancelled', async () => {
475
+ it('sets lastCancelledAt when job is cancelled', async () => {
475
476
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
476
- job_type: 'email',
477
+ jobType: 'email',
477
478
  payload: { to: 'ts5@example.com' },
478
479
  });
479
480
  await queue.cancelJob(pool, jobId);
480
481
  const job = await getJobRow(jobId);
481
- expect(job.last_cancelled_at).not.toBeNull();
482
+ expect(job.lastCancelledAt).not.toBeNull();
482
483
  });
483
484
 
484
- it('sets last_retried_at when job is picked up for processing again (attempts > 0)', async () => {
485
+ it('sets lastRetriedAt when job is picked up for processing again (attempts > 0)', async () => {
485
486
  const jobId = await queue.addJob<{ email: { to: string } }, 'email'>(pool, {
486
- job_type: 'email',
487
+ jobType: 'email',
487
488
  payload: { to: 'ts6@example.com' },
488
489
  });
489
490
  // First pick up and fail the job
@@ -494,9 +495,9 @@ describe('job lifecycle timestamp columns', () => {
494
495
  'UPDATE job_queue SET next_attempt_at = NOW() WHERE id = $1',
495
496
  [jobId],
496
497
  );
497
- // Pick up for processing again (should increment attempts and set last_retried_at)
498
+ // Pick up for processing again (should increment attempts and set lastRetriedAt)
498
499
  await queue.getNextBatch(pool, 'worker-ts', 1);
499
500
  const job = await getJobRow(jobId);
500
- expect(job.last_retried_at).not.toBeNull();
501
+ expect(job.lastRetriedAt).not.toBeNull();
501
502
  });
502
503
  });