Skip to content

Inject logs into backend#4

Merged
hugobessa merged 5 commits intomainfrom
Inject-logs-into-backend
Feb 2, 2026
Merged

Inject logs into backend#4
hugobessa merged 5 commits intomainfrom
Inject-logs-into-backend

Conversation

@hugobessa
Copy link
Collaborator

@hugobessa hugobessa commented Feb 2, 2026

Summary by Sourcery

Inject logger support into notification backends and fix incorrect logging level when creating notifications.

Enhancements:

  • Inject logger instances into notification backends that support optional logger injection for improved debugging and monitoring.

Tests:

  • Update notification service tests to assert the correct log level when notifications are created.

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Feb 2, 2026

Reviewer's Guide

Adds optional logger injection support to notification backends and ensures notification creation is logged at info level, updating the notification service, backend interface, and corresponding tests, plus repository configuration tweaks.

Sequence diagram for VintaSend initialization with logger injection

sequenceDiagram
  actor App
  participant Factory as VintaSendFactory
  participant Backend as BaseNotificationBackend
  participant Logger as BaseLogger
  participant Adapter1 as BaseNotificationAdapter_1
  participant Adapter2 as BaseNotificationAdapter_2
  participant Renderer1 as TemplateRenderer_1

  App->>Factory: create(adapters, backend, logger, contextGeneratorsMap, queueService, attachmentManager, options)
  activate Factory
  Factory->>Factory: new VintaSend(...)
  deactivate Factory

  activate Backend
  loop for each adapter in adapters
    activate Adapter1
    Adapter1->>Adapter1: injectBackend(backend)
    Adapter1->>Adapter1: injectLogger(logger)
    Adapter1->>Renderer1: injectLogger(logger)
    deactivate Adapter1
  end

  Backend->>Backend: injectLogger(logger)
  deactivate Backend

  note over App,Backend: After construction, backend and adapters share the same logger for consistent logging
Loading

Updated class diagram for notification logging and backends

classDiagram
  class BaseLogger {
  }

  class BaseNotificationTypeConfig {
    <<interface>>
    ContextMap
    NotificationIdType
  }

  class BaseNotificationTemplateRenderer {
    <<interface>>
    +generate(notification, context) Promise~any~
  }

  class BaseEmailTemplateRenderer {
    <<interface>>
    +render(notification, context) Promise~EmailTemplate~
    +injectLogger(logger) void
  }

  class BaseNotificationAdapter {
    <<interface>>
    +notificationType
    +key
    +enqueueNotifications
    +injectBackend(backend) void
    +injectLogger(logger) void
    +send(notification, context) Promise~void~
  }

  class BaseNotificationBackend {
    <<interface>>
    +getAllPendingNotifications() Promise~AnyDatabaseNotification~
    +persistNotification(notification) Promise~DatabaseNotification~
    +persistNotificationUpdate(notificationId, notification) Promise~DatabaseNotification~
    +persistOneOffNotification(notification) Promise~DatabaseOneOffNotification~
    +persistOneOffNotificationUpdate(notificationId, notification) Promise~DatabaseOneOffNotification~
    +getNotification(notificationId, forUpdate) Promise~DatabaseNotification or null~
    +getOneOffNotification(notificationId, forUpdate) Promise~DatabaseOneOffNotification or null~
    +markAsFailed(notificationId, propagate) Promise~void~
    +markAsSent(notificationId, propagate) Promise~void~
    +markAsRead(notificationId, checkIsSent) Promise~DatabaseNotification~
    +cancelNotification(notificationId) Promise~void~
    +storeContextUsed(notificationId, context) Promise~void~
    +getAllFutureNotifications() Promise~AnyDatabaseNotification[]~
    +getAllFutureNotificationsFromUser(userId) Promise~AnyDatabaseNotification[]~
    +getFutureNotificationsFromUser(userId, page, pageSize) Promise~AnyDatabaseNotification[]~
    +getFutureNotifications(page, pageSize) Promise~AnyDatabaseNotification[]~
    +getPendingNotifications(page, pageSize) Promise~AnyDatabaseNotification[]~
    +bulkPersistNotifications(notifications) Promise~NotificationIdType[]~
    +getNotifications(pageNumber, batchSize) Promise~AnyDatabaseNotification[]~
    +injectLogger(logger) void
  }

  class BaseNotificationQueueService {
    <<interface>>
    +enqueueNotification(notificationId) Promise~void~
  }

  class BaseAttachmentManager {
    <<abstract>>
  }

  class NotificationContextGeneratorsMap {
    +getContextGenerator(contextName)
  }

  class VintaSendOptions {
    +raiseErrorOnFailedSend boolean
  }

  class VintaSendFactory {
    +create(adapters, backend, logger, contextGeneratorsMap, queueService, attachmentManager, options) VintaSend
  }

  class VintaSend {
    -adapters AdaptersList
    -backend Backend
    -logger Logger
    -queueService QueueService
    -attachmentManager AttachmentMgr
    -options VintaSendOptions
    -contextGeneratorsMap NotificationContextGeneratorsMap
    +constructor(adapters, backend, logger, contextGeneratorsMap, queueService, attachmentManager, options)
    +registerQueueService(queueService) void
    +send(notification) Promise~void~
    +createNotification(notification) Promise~DatabaseNotification~
    +updateNotification(notificationId, notification)
    +createOneOffNotification(notification) Promise~DatabaseOneOffNotification~
    +updateOneOffNotification(notificationId, notification) Promise~DatabaseOneOffNotification~
    +getNotificationContext(contextName, parameters) Promise~JsonObject~
    +sendPendingNotifications() Promise~void~
    +getPendingNotifications(page, pageSize)
    +getNotification(notificationId, forUpdate)
    +getOneOffNotification(notificationId, forUpdate) Promise~DatabaseOneOffNotification or null~
    +markRead(notificationId, checkIsSent) Promise~DatabaseNotification~
    +cancelNotification(notificationId) Promise~void~
    +resendNotification(notificationId, useStoredContextIfAvailable) Promise~DatabaseNotification or undefined~
    +delayedSend(notificationId) Promise~void~
    +bulkPersistNotifications(notifications) Promise~NotificationIdType[]~
    +migrateToBackend(destinationBackend, batchSize) Promise~void~
  }

  VintaSendFactory --> VintaSend : creates
  VintaSend --> BaseNotificationAdapter : uses
  VintaSend --> BaseNotificationBackend : uses
  VintaSend --> BaseNotificationQueueService : uses
  VintaSend --> BaseAttachmentManager : uses
  VintaSend --> NotificationContextGeneratorsMap : uses
  VintaSend --> BaseLogger : uses

  BaseNotificationAdapter --> BaseNotificationTemplateRenderer : uses
  BaseEmailTemplateRenderer ..|> BaseNotificationTemplateRenderer : extends

  BaseNotificationBackend --> BaseLogger : injectLogger
  BaseNotificationAdapter --> BaseLogger : injectLogger
  BaseEmailTemplateRenderer --> BaseLogger : injectLogger
Loading

File-Level Changes

Change Details Files
Inject logger into notification backend and template renderers during VintaSend initialization for improved observability.
  • Extend VintaSend constructor to call injectLogger on each adapter’s template renderer when supported.
  • Add a conditional call to backend.injectLogger(logger) if the backend implementation provides this optional method.
  • Retain existing attachment manager injection logic after logger injection.
src/services/notification-service.ts
Extend BaseNotificationBackend interface to optionally accept a logger instance.
  • Import BaseLogger into the backend interface module.
  • Add an optional injectLogger(logger: BaseLogger): void method to BaseNotificationBackend for debugging and monitoring.
src/services/notification-backends/base-notification-backend.ts
Adjust notification creation logging level and align tests with the new behavior.
  • Change the log level when a notification is created from error to info in createNotification.
  • Update the unit test description and expectation to assert info-level logging instead of error-level logging for notification creation.
src/services/__tests__/notification-service.test.ts
src/services/notification-service.ts
Add Git attributes configuration file.
  • Introduce a .gitattributes file to configure repository-specific Git behavior (exact rules not shown in diff).
.gitattributes

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@hugobessa hugobessa merged commit a2c6293 into main Feb 2, 2026
1 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant