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>
Adds apps/worker with TypeScript config, BullMQ/ioredis dependencies,
pino logger bootstrap, and a smoke test. Queue consumers wired in later phases.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>