81da0d483e
Idempotent message persistence via prisma.message.upsert. Uses URL parsing to pass connection options to BullMQ, avoiding ioredis version conflicts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
38 lines
1.0 KiB
TypeScript
38 lines
1.0 KiB
TypeScript
import { Worker } from 'bullmq';
|
|
import { IngestJobData } from '@tower/types';
|
|
|
|
function parseRedisUrl(url: string) {
|
|
const { hostname, port } = new URL(url);
|
|
return { host: hostname, port: parseInt(port || '6379', 10), maxRetriesPerRequest: null };
|
|
}
|
|
|
|
export async function processIngestJob(job: IngestJobData, prisma: any): Promise<void> {
|
|
await prisma.message.upsert({
|
|
where: {
|
|
platform_platformMsgId: {
|
|
platform: job.platform,
|
|
platformMsgId: job.platformMsgId,
|
|
},
|
|
},
|
|
create: {
|
|
platform: job.platform,
|
|
platformMsgId: job.platformMsgId,
|
|
sourceGroupId: job.sourceGroupId,
|
|
senderJid: job.senderJid,
|
|
senderName: job.senderName,
|
|
content: job.content,
|
|
tags: job.tags,
|
|
status: 'PENDING',
|
|
},
|
|
update: {},
|
|
});
|
|
}
|
|
|
|
export function createIngestWorker(redisUrl: string, prisma: any): Worker<IngestJobData> {
|
|
return new Worker<IngestJobData>(
|
|
'tower:ingest',
|
|
async (job) => processIngestJob(job.data, prisma),
|
|
{ connection: parseRedisUrl(redisUrl) },
|
|
);
|
|
}
|