2025-05-05
Summary
This release delivers end-to-end push notification deep-linking for the native app (Android + iOS), fixes two critical server-side bugs that were silently dropping all device notifications, and ships a structured logfmt observability improvement for BetterStack. A batch of security and maintenance dependency upgrades is also included.
Changes
Critical Bug Fixes — #331
AlertMethodMethodtype-only import — enum was erased at compile time, causing a silentReferenceErrorthat skipped all device notifications. Fixed to a value import.- Unfiltered notification iteration —
Promise.allwas iterating the originalnotificationsarray instead offilteredNotifications, sending pushes to disabled alert methods. Fixed. - Logger debug level leaking to Logtail — debug entries were routed as INFO in production. Now gated to
NODE_ENV === 'development'.
Deep-Linking for Push Notifications — #331
firealert://custom scheme — notifications now usefirealert://alert/:alertId, bypassing iOS Safari intercept.- Cold-start queuing — notification tap events are queued if
NavigationContainerisn't ready yet, then flushed ononReady. - Map zoom on tap — Home screen locates the tapped alert and calls
camera.setCameraviacalculateAlertCamera; skips default user-location zoom whenalertId/incidentIdis in params. - Re-tap support —
__tsnonce in deep-link params forcesuseEffectto re-fire on repeated taps. - OneSignal URL suppression —
OneSignal_suppress_launch_urls = trueadded to iOSInfo.plist, mirroring Android's existing config. - Platform config — Android intent-filters (
/incident,/verify,firealert://),MainActivity.onNewIntent; iOSAppDelegateURL bridging, app group entitlement, AASA headers via Next.js config; server serves/.well-known/apple-app-site-associationandassetlinks.json.
Android: OneSignal Permission Fix — #338 / #339
- Fixed permission state not being correctly propagated to OneSignal, causing push registration failures on some Android devices.
- Version bump and CodeRabbit feedback addressed.
Observability: Reduced BetterStack Log Volume — #340
- Collapsed per-provider/per-incident/per-notification info lines into single logfmt summaries (
stage=... event=...); verbose logs are dev-only. - Added
escapeLogfmt()helper to prevent stack traces from fragmenting log records. - Removed
clientApiKeyand rawdestination(PII) from log tags. - Fixed unsafe
(error as Error)casts witherror instanceof Errorguards. - Fixed GEO provider tags in site alert logs; notification sender no longer halts after skipped batches.
Tooling — #329
- Added
.claude/config for Claude Code worktree management; cleaned up older feature instruction files.
Dependency Updates
#328 + Dependabot
apps/server
| Package | From | To |
|---|---|---|
next |
^16.1.5 |
^16.2.3 |
nodemailer |
^6.9.1 |
^8.0.5 |
postcss |
^8.5.6 |
^8.5.10 |
@types/nodemailer |
^6.4.7 |
^8.0.0 |
apps/nativeapp (v1.9)
| Package | From | To |
|---|---|---|
axios |
^1.13.5 |
^1.15.0 |
| Android versionCode | 24 |
26 |
| iOS build number | 28 |
31 |
activesupport (Ruby) |
7.2.2.1 |
7.2.3.1 |
addressable (Ruby) |
2.8.7 |
2.9.0 |
Indirect / Security
ajv6.12.6→6.14.0rollup4.54.0→4.59.0minimatch3.1.2→3.1.5flatted3.3.3→3.4.2node-forge1.3.2→1.4.0follow-redirects1.15.11→1.16.0brace-expansion1.1.12→1.1.14fast-xml-parser4.5.3→4.5.6lodash4.17.23→4.18.1yaml2.8.1→2.8.3picomatch2.3.1→2.3.2protocol-buffers-schema3.6.0→3.6.1
Tooling
.yarnrc: enabled--install.frozen-lockfile truefor reproducible installs.package-lock.jsonremoved — yarn.lock is the single source of truth.
📜 Full Changelog
| PR | Type | Title |
|---|---|---|
| #328 | chore | Update multiple dependencies to latest versions |
| #329 | chore | Configure Claude Code worktree management |
| #331 | fix | Resolve notification delivery failures and complete deep-link flow |
| #338 | fix | Fix Android OneSignal permission propagation |
| #339 | chore | Version bump & CodeRabbit feedback |
| #340 | perf | Reduce BetterStack log volume with logfmt summaries |
| #337 | release | Release: Update dependencies and Claude Config & DeepLinking |
Full diff: develop...main