Keeps develop's per-user Slack delivery, escalation and mute work; the
in_app_min_severity changeset moves to qbit-alerts:29; the Notifications
preferences section gains Slack per category; pause also skips non-security
Slack; the summary schema carries preferencesSection (alerts extension 1.1.0).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NotificationSlackSender runs after the emailer: core SendMessageAction to the
configured provider (default "slack") with user:<id>, no qbit-slack import.
Pause and quiet hours apply (CRITICAL bypasses quiet hours), SECURITY sends
title and link only, daily digest DMs, SKIPPED without a provider or on a
user-facing refusal. Supersedes the 2026-10-13 "Slack never per user"
decision (owner, 2026-10-14; QRun-IO/qbit-slack DESIGN section 10).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
An alert about a record now also reaches the record's followers, from
core RecordFollowers.get(instance, ref, FollowEvent.ALERT) (QRun-IO/qqq#1164,
QQQ 4.1.0-RC.6). Followers are deduplicated with existing recipients by
user and channel. They must pass the source-record permission and lock
checks, and they get the same preferences and suppression as any other
recipient. With no provider registered, routing is unchanged. There is no
dependency on qbit-collaboration, and the #1164 stand-in marker is gone.
Also adopt qbit-build-parent 2.1.0 with the guardrails enforced and strict
raw-route mode. Comments that only used the word "stand-in" are reworded.
Refs #16 (architecture review QRun-IO/qqq#1150, finding F12).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Core 4.1.0-RC.6 ships user notifications (QAlerts.notify,
NotificationSignal and friends; QRun-IO/qqq#1125). The qbit's sink now
implements core's notify path, so a QAlerts.notify from any qbit reaches
the notification queue, inbox, channels, quiet hours and preferences.
The rest of the stand-in package com.kingsrook.qbits.alerts.spi goes
(NotificationSignal, NotificationAudience, NotificationCategory,
NotificationSeverity, AlertLink, package-info), and so does
AlertsRuntime.sink().
Breaking for anything that used com.kingsrook.qbits.alerts.spi; its only
consumer, qbit-easypost-tracking, moved to core in #16 there.
Closes#15 (architecture review QRun-IO/qqq#1150, F3 and F12).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#13: the six inbox and record-panel routes move from the raw
AlertsRouteProvider onto a MiddlewareSpecExtension "alerts" (prefix
/alerts). Paths are unchanged. The committed fragment
openapi/qqq-v1/alerts.yaml is checked by a contract test, and the server
tests run in strict mode. Additive fields let Next stop hard-coding
alerts names: the summary has inboxHref, and inbox items and panel
alerts have actions with process names and hrefs.
#14: the Alertmanager webhook moves to POST /qqq/hooks/alerts/alertmanager.
The old /qqq/v1 path is an opt-in deprecated alias (legacyAlertmanagerPath,
default off; it needs non-strict mode). The alias sends Deprecation and
Sunset headers and logs a warning per call.
#16: POST /alerts/record-panel/watch is removed; collaboration owns
following a record. The record panel reports follow.available when the
collaboration extension is registered. Existing record-scoped watch
subscriptions stay readable and are deprecated. Follower fan-out waits for
core RecordFollowersProviderInterface (STAND-IN(core=QRun-IO/qqq#1164,
removeBy=4.1.0-RC.7)).
The checkstyle header template now matches the short Apache header that
the sources already use. The core baseline becomes 4.1.0-RC.6.
Closes#13, closes#14, closes#16 (architecture review QRun-IO/qqq#1150,
F2, F7, F12, F20).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Registers a core Preferences section 'notifications' backed by
alerts_user_preference, alerts_notification_preference and the user's own
alerts_subscription rows: pause, digest time and time zone, alert email and
in-app switches, per-category in-app/email settings (security can't be
muted) and per-subscription overrides. Adds in_app_min_severity
(changeset qbit-alerts:21), honours it for in-app delivery, and skips
non-security emails while paused. The inbox summary returns
preferencesSection.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bump the core baseline to 4.1.0-RC.5 and delete the alert-side copies in
the spi package. The qbit now registers its sink in core's
AlertsInstanceMetaData, so core QAlerts.raise/resolve/heartbeat from any
host qbit reaches it. The alertsQBitStandIn name is gone.
The notification types (NotificationSignal and friends) and
AlertsRuntime.sink().notify stay, binary compatible, for the released
qbit-easypost-tracking. They are tagged
STAND-IN(core=QRun-IO/qqq#1125, removeBy=4.1.0-RC.6).
StandardWebhookSigner delegates to core WebhookSigner. The wire format is
unchanged. Legacy secrets shorter than core's 16-byte minimum are
zero-padded, which gives an identical HMAC-SHA256.
Refs #15 (architecture review QRun-IO/qqq#1150, F3 and F11).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Extends the alerts model with admin-authored and producer-emitted user
notifications, per-user recipient rows, dynamic audiences, the Next UI
notification center, and QAlerts.notify in the core SPI.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>