Skip to content

v1.51.0 — Larawag

Choose a tag to compare

@MichaelSowah MichaelSowah released this 06 Jun 15:38
· 99 commits to main since this release
1b89fb3

Larawag — Notification subsystem refinement

A five-part refinement of the core notification subsystem. Mostly additive, with two deliberate breaking changes in channel registration/dispatch — see Upgrade Notes.

✨ Highlights

  • Real in-app database channel. DatabaseChannel is registered by default, so the framework's default ['database'] channel resolves end-to-end instead of failing as
    channel_not_found. It's an acknowledge-only channel — NotificationService still owns the notification and delivery records — and its availability tracks the notifications
    persistence capability.
  • Dispatch-time channel validation. Channel names are no longer validated against a hardcoded list at construction; they're normalized structurally (trimmed, de-duplicated,
    non-empty, case preserved) and unknown channels surface at dispatch via channel_not_found / channel_unavailable. The ChannelManager registry is the single source of
    truth — custom channels work without core changes.
  • Optional, safe persistence (NOTIFICATIONS_DATABASE_STORE=false). New NotificationStoreInterface; NotificationRepository implements it, and a NullNotificationStore
    binds when the capability is off. Reads return empty/null/zero, transient writes no-op, and durability-implying operations throw NotificationPersistenceDisabledException
    rather than silently losing state.
  • Injectable async-queue dispatch. NotificationQueueDispatcherInterface (default QueueManagerNotificationDispatcher) abstracts async dispatch so send() never requires
    a queue and queueing stays unit-testable.
  • Structured channel results. Channels may opt into sendNotification(): NotificationResult (provider message id, error code/message, retryability, latency) via
    RichNotificationChannel; the dispatcher prefers it and falls back to adapting legacy send(): bool.
  • Extension-driven channel registration. Channels/hooks register through ServiceProvider::boot() via registerNotificationChannel() / registerNotificationExtension()
    one path, no per-job glue.

⚠️ Upgrade Notes (breaking)

  • ChannelManager rename (no aliases): getAvailableChannels()getRegisteredChannelNames(); for available-only names use the new getActiveChannelNames().
    getActiveChannels() (objects) is unchanged.
  • Notification jobs/commands require an ApplicationContext: DispatchNotificationChannels, SendNotification, ProcessRetriesCommand, NotificationRetryTask throw
    NotificationContextRequiredException if constructed without a context. The queue worker and console kernel already provide one.
  • No hardcoded EmailNotification provider: channel packages must register from their ServiceProvider::boot().
  • Retry config key moved: emailnotification.* → channel-agnostic notifications.retry.
  • No new env vars, no migrations. The notifications capability default stays true.
composer update glueful/framework