Skip to content

Queues and external services ​

BullMQ and Redis ​

The queue proof of concept uses BullMQ with Redis:

  • Queue name: notification
  • Producer: src/lib/mq/producer.ts
  • Worker: src/lib/mq/worker.ts
  • Connection: src/lib/mq/config.ts
  • Redis is exposed locally on port 6311 by Compose and maps to Redis's container port.

The API enqueues a health-check job from the health route. The worker logs the job, simulates two seconds of work, and emits completed, failed, and error events.

The worker sets maxRetriesPerRequest: null, which is required for BullMQ workers that issue blocking Redis commands. The API and worker must use the same queue name and compatible Redis connection.

Designing real jobs ​

A production-quality job should define:

  • stable job names and versioned payloads
  • retry and backoff policy
  • idempotency behavior
  • remove-on-complete and remove-on-fail policy
  • timeout and dead-letter strategy
  • correlation id and structured logs
  • graceful shutdown and readiness reporting

Do not put large payloads or secrets in Redis jobs. Prefer ids and fetch current data in the worker.

Email delivery ​

The project contains Nodemailer SMTP support, a Resend provider, and welcome and workspace invitation templates. Registration currently dispatches a welcome email synchronously through the selected email service. This makes SMTP availability part of the registration request path.

For a more resilient design, persist the business operation first and enqueue email delivery. The worker can retry transient provider failures without making user registration fail solely because an email provider is unavailable. Record delivery status and avoid duplicate sends with an idempotency key.

Email checklist:

  • Verify the sender domain with the provider.
  • Keep provider keys in environment variables.
  • Use templates that escape user-controlled text.
  • Set connection and request timeouts.
  • Distinguish transient from permanent failures.
  • Avoid logging message bodies or recipient data unnecessarily.

Swagger and OpenAPI ​

Swagger is generated by swagger-jsdoc from comments in routers and schemas and served with swagger-ui-express at /docs. Keep the documentation beside the endpoint so it changes with the implementation. Ensure server URLs and security schemes match the active environment.

Logging ​

The logger writes application logs to logs/app.log and access logs to logs/access.log. Logs are ignored by Git. Configure external rotation for long-running services. Example Linux policy:

text
/path/to/logs/*.log {
    weekly
    rotate 4
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
}

Prefer structured fields such as request id, user id, job id, route, duration, and error code. Redact secrets and personal data.

Released under the MIT License.