v0.9.5
Released
Fix
Multi-Engine Metadata Filters, Error Notification Throttle & Dependency Security
Metadata filters now work on ClickHouse and MongoDB, error notifications are throttled per group to stop email storms, the notification-channels defaults endpoint accepts monitoring, plus 19 Dependabot advisories resolved.
- Metadata filters now translated on ClickHouse and MongoDB, not just TimescaleDB (#226, #224)
- Error notifications throttled per error group via a race-safe cooldown (ERROR_NOTIFICATION_COOLDOWN_MINUTES, default 15)
- notification-channels defaults endpoint now accepts the monitoring event type
- Migration 043 adds last_notified_at to error_groups
- Security: 19 Dependabot advisories resolved (8 high, 11 moderate)
Fixed
- Metadata filters were silently ignored on ClickHouse and MongoDB (#226, issue #224): the metadata filter operators (
equals,not_equals,in,not_in,exists,not_exists,contains) were only translated by the TimescaleDB query builder. The ClickHouse and MongoDB query translators never readparams.metadataFilters, so any log search or alert rule that relied on ametadata.*filter came back unfiltered on those engines (the filter appeared to do nothing). ClickHouse now translates each filter to a predicate over the JSONmetadatacolumn usingJSONExtractStringpaired withJSONHasto distinguish a missing key from an empty string (not_in/not_equalssplit on whether the key is present,containsusespositionCaseInsensitive). MongoDB builds one clause per filter keyed onmetadata.<key>, all wrapped in$andso repeated filters on the same key don’t overwrite each other, withinclude_missingcontrolling whethernot_equals/not_inalso match documents where the field is absent ($exists). Covered by new per-engine translator tests - Error notifications spammed one email per occurrence:
processErrorNotificationsent an in-app notification, email and webhook for every exception occurrence, suppressed only when the error group’s status wasignored. A high-frequency client error (e.g. a Svelteeffect_update_depth_exceededloop firing thousands of times) produced one exception row per occurrence and therefore thousands of identical alert emails. The job now throttles per error group: it atomically claims a notification slot viaUPDATE error_groups SET last_notified_at = now() WHERE status != 'ignored' AND (last_notified_at IS NULL OR last_notified_at <= cutoff) RETURNING id, so only the first occurrence inside the cooldown window notifies and the rest are skipped. The conditional UPDATE is race-safe (concurrent jobs serialize on the row lock and re-evaluate the predicate against the freshly written timestamp), so even a burst of thousands collapses to a single notification per window. Cooldown is configurable viaERROR_NOTIFICATION_COOLDOWN_MINUTES(default 15, set0to notify on every occurrence). Occurrence counts on the error group and in-app dashboards are unaffected monitoringrejected by the notification-channels defaults endpoint:PUT/GET /api/v1/notification-channels/defaults/:eventTypevalidated:eventTypeagainst a local Zod enum of['alert', 'sigma', 'incident', 'error']that was missingmonitoring, even though the sharedNotificationEventTypetype, the DBorganization_default_channelsconstraint (migration 037) and the service all support it. Setting a default monitoring channel returned400 Validation error(“received ‘monitoring’”). Addedmonitoringto the route enum so the five event types are consistent across the stack
Added
- Migration 043
error_notification_throttle: adds a nullablelast_notified_at TIMESTAMPTZcolumn toerror_groups, used as the per-group notification cooldown anchor (see the error-notification throttle fix above)
Security
- Resolved 19 Dependabot advisories (8 high, 11 moderate) by bumping direct dependencies and pinning patched versions through the root pnpm
overrides.protobufjs→7.6.1(kept on the 7.x line via>=7.5.8 <8; covers code injection, prototype-pollution gadget, unbounded-recursion DoS, unsafe option paths, crafted-field DoS, overlong UTF-8 in@protobufjs/utf8 >=1.1.1).kysely→0.28.17(bounded>=0.28.17 <0.29; JSON-path traversal injection inJSONPathBuilder.key()/.at()).svelte→5.55.9(>=5.55.7; SSR XSS via spread attributes and promise serialization, DOM-clobbering XSS,<svelte:element>ReDoS).@sveltejs/kit→2.61.1(>=2.60.1;query.batchcross-talk).fast-uri→3.1.2(path traversal + host confusion via percent-encoded segments).qs→6.15.2(DoS inqs.stringify),devalue→5.8.1(sparse-array DoS),brace-expansion→5.0.6(numeric-range DoS),ws→8.21.0(uninitialized memory disclosure).protobufjsandkyselywere deliberately held on their current major/minor lines (their “latest” is a breaking jump) while still landing on the patched release