Skip to content

feat: send silent settings_changed FCM push on assignedSite update - #1689

Merged
renemadsen merged 6 commits into
stablefrom
feat/auto-settings-sync-push
Aug 26, 2026
Merged

feat: send silent settings_changed FCM push on assignedSite update#1689
renemadsen merged 6 commits into
stablefrom
feat/auto-settings-sync-push

Conversation

@renemadsen

Copy link
Copy Markdown
Member

On UpdateAssignedSite, fire a fire-and-forget data-only FCM message {type: settings_changed} to the site's devices so the flutter-time app auto-refreshes its personal-mode settings.

  • SendToSiteAsync gains data-only (silent) support: it omits the Notification payload and sets iOS content-available so the message is delivered silently.
  • A push failure never fails the settings update (fire-and-forget).

Notes:

  • No proto/JSON-parity change.
  • No EF migration.

Pairs with the flutter-time client PR.

renemadsen and others added 2 commits August 25, 2026 09:44
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ssignedSite

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 25, 2026 08:02

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR adds a silent (data-only) FCM push ({ type: settings_changed }) when an assigned site is updated, so the Flutter time app can auto-refresh personal-mode settings without a visible notification.

Changes:

  • Injects IPushNotificationService into TimeSettingService and triggers a settings_changed push during UpdateAssignedSite.
  • Adds PushNotificationService.BuildMessage(...) to support data-only pushes (no Notification payload, sets iOS content-available).
  • Extends test coverage for the new silent-push behavior and ensures settings updates still succeed if push sending fails.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Services/TimePlanningSettingService/TimeSettingService.cs Sends a settings_changed silent push during assigned-site updates.
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Services/PushNotificationService/PushNotificationService.cs Adds message builder supporting data-only (silent) FCM sends and uses it from SendToSiteAsync.
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/SettingsServiceTests.cs Adds push-service substitution and a test ensuring update succeeds even if the push task faults.
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/SettingsServicePhoneNumberTests.cs Updates TimeSettingService construction to provide IPushNotificationService.
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/SettingsServiceExtendedTests.cs Updates TimeSettingService construction to provide IPushNotificationService.
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/PushNotificationServiceTests.cs Adds unit tests validating silent vs visible message construction.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +1082 to +1092
// Fire-and-forget: tell the worker's device(s) that their assigned-site
// settings changed so personal mode can auto-refresh. Sent AFTER the row
// is committed; a push failure must NEVER fail the settings update.
try
{
await pushNotificationService.SendToSiteAsync(
dbAssignedSite.SiteId,
title: "",
body: "",
data: new Dictionary<string, string> { { "type", "settings_changed" } });
}
renemadsen and others added 4 commits August 25, 2026 14:42
Bump Microting.TimePlanningBase 10.0.57 -> 10.0.58 (adds the
AppBuildNumber column to DeviceToken).

Repurpose device_token.proto field 3 from the long-ignored sdk_site_id
to int32 build_number, matching the flutter-time client so the wire
stays identical. The C# gRPC stub regenerates at build via the existing
<Protobuf> item.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Thread the client-reported build number from the gRPC handler through
RegisterForCallerAsync/RegisterAsync and set deviceToken.AppBuildNumber
on BOTH the create and the update (re-register) branches, so a
re-register refreshes the stored build number. The param defaults to 0
(old/unknown client).

Tests: persists build number on create, refreshes it on re-register,
and stores 0 when the client omits it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add an optional minBuild param to SendToSiteAsync (interface + impl) and
filter DeviceTokens by AppBuildNumber >= minBuild. Default 0 includes
every device, so existing callers (absence-request / content-handover
notification pushes) are unaffected.

UpdateAssignedSite now passes minBuild: MinSettingsChangedPushBuild
(31221) — the first flutter-time build that both sends build_number and
handles the settings_changed silent push. Older installs report 0 and
are excluded to avoid a stray notification.

The token-selection query is extracted to an internal
ResolveTargetTokensAsync seam so the filter is unit-testable (Firebase
is not configured in tests, so SendToSiteAsync itself short-circuits).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the fully-qualified DeviceToken return type on
ResolveTargetTokensAsync with a using alias (the plain namespace import
clashes with FirebaseAdmin.Messaging.Message), and factor the repeated
PushNotificationService construction in the tests into a CreateService
helper. No behavior change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@renemadsen
renemadsen merged commit 491411c into stable Aug 26, 2026
72 of 77 checks passed
@renemadsen
renemadsen deleted the feat/auto-settings-sync-push branch August 26, 2026 06:25
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.

2 participants