/** * @fileoverview In-process job watch queue (NATS_ENABLED=false path). * @module store/jobWatchers */ import { randomUUID } from 'node:crypto'; import { getStore, persist } from './db.js'; import { createDebugger } from '../debug/logger.js'; const log = createDebugger('jobs'); /** * @typedef {Object} JobWatcher * @property {string} id * @property {string} tenantId * @property {string} jobId * @property {string} veraeToken * @property {string} status * @property {number} attempts * @property {string} createdAt * @property {string} updatedAt * @property {string} [traceId] */ /** * @param {object} params * @param {string} params.tenantId * @param {string} params.jobId * @param {string} params.veraeToken * @param {string} [params.traceId] * @returns {JobWatcher} */ export function enqueueJob({ tenantId, jobId, veraeToken, traceId }) { /** @type {JobWatcher} */ const watcher = { id: randomUUID(), tenantId, jobId, veraeToken, status: 'pending', attempts: 0, createdAt: new Date().toISOString(), updatedAt: new Date().toISOString(), traceId, }; const store = getStore(); store.jobWatchers.push(watcher); persist(); log.debug('job enqueued', { watcherId: watcher.id, jobId, tenantId }); return watcher; } /** * @returns {JobWatcher[]} */ export function listPendingJobs() { return getStore().jobWatchers.filter((job) => job.status === 'pending'); } /** * @param {string} id * @param {Partial} patch * @returns {JobWatcher|null} */ export function updateJobWatcher(id, patch) { const store = getStore(); const index = store.jobWatchers.findIndex((job) => job.id === id); if (index === -1) return null; store.jobWatchers[index] = { ...store.jobWatchers[index], ...patch, updatedAt: new Date().toISOString(), }; persist(); return store.jobWatchers[index]; } /** * @param {string} id * @returns {void} */ export function removeJobWatcher(id) { const store = getStore(); store.jobWatchers = store.jobWatchers.filter((job) => job.id !== id); persist(); log.debug('job watcher removed', { id }); }