From 08d354afe955fee28969a2c0cbee024de8159871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Schultz=20Madsen?= Date: Wed, 13 May 2026 18:13:21 +0200 Subject: [PATCH] feat(grpc): include UseOneMinuteIntervals on Site in GetRegistrationSites response Adds bool use_one_minute_intervals = 23 to the Site message in settings.proto and the matching UseOneMinuteIntervals property on the C# Site DTO. Populates the new field from AssignedSite.UseOneMinuteIntervals in both GetAvailableSites (token path) and GetAllRegistrationSitesByCurrentUser (personal/JWT path) inside TimeSettingService, so the gRPC handler maps it through automatically. Also fills the field in GetResignedSites for symmetry across the three site-builders. Mobile clients (flutter-time kiosk mode) can now select the correct site-level minute-precision behavior at the registration step, before any GetAssignedSite call is made. Extends TimePlanningSettingsGrpcServiceTests GetRegistrationSitesByCurrentUser_Success_MapsSitesToGrpcResponse to cover both UseOneMinuteIntervals=true and =false sites and assert the field round-trips through the gRPC mapper. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../GrpcServices/TimePlanningSettingsGrpcServiceTests.cs | 4 ++++ .../TimePlanning.Pn/Infrastructure/Models/Settings/Site.cs | 1 + .../TimePlanning.Pn/TimePlanning.Pn/Protos/settings.proto | 1 + .../GrpcServices/TimePlanningSettingsGrpcService.cs | 2 ++ .../TimePlanningSettingService/TimeSettingService.cs | 7 +++++-- 5 files changed, 13 insertions(+), 2 deletions(-) diff --git a/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/GrpcServices/TimePlanningSettingsGrpcServiceTests.cs b/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/GrpcServices/TimePlanningSettingsGrpcServiceTests.cs index 977c35777..6a1375ca0 100644 --- a/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/GrpcServices/TimePlanningSettingsGrpcServiceTests.cs +++ b/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/GrpcServices/TimePlanningSettingsGrpcServiceTests.cs @@ -49,6 +49,7 @@ public async Task GetRegistrationSitesByCurrentUser_Success_MapsSitesToGrpcRespo FourthShiftActive = false, FifthShiftActive = true, SnapshotEnabled = false, + UseOneMinuteIntervals = true, Resigned = false, ResignedAtDate = DateTime.SpecifyKind(DateTime.MinValue, DateTimeKind.Utc), AvatarUrl = "https://example.com/avatar1.png", @@ -74,6 +75,7 @@ public async Task GetRegistrationSitesByCurrentUser_Success_MapsSitesToGrpcRespo FourthShiftActive = true, FifthShiftActive = false, SnapshotEnabled = true, + UseOneMinuteIntervals = false, Resigned = true, ResignedAtDate = new DateTime(2024, 1, 1, 0, 0, 0, DateTimeKind.Utc), AvatarUrl = "https://example.com/avatar2.png", @@ -113,6 +115,7 @@ public async Task GetRegistrationSitesByCurrentUser_Success_MapsSitesToGrpcRespo Assert.That(site1.FourthShiftActive, Is.False); Assert.That(site1.FifthShiftActive, Is.True); Assert.That(site1.SnapshotEnabled, Is.False); + Assert.That(site1.UseOneMinuteIntervals, Is.True); Assert.That(site1.Resigned, Is.False); Assert.That(site1.AvatarUrl, Is.EqualTo("https://example.com/avatar1.png")); Assert.That(site1.PhoneNumber, Is.EqualTo("+4512345678")); @@ -136,6 +139,7 @@ public async Task GetRegistrationSitesByCurrentUser_Success_MapsSitesToGrpcRespo Assert.That(site2.FourthShiftActive, Is.True); Assert.That(site2.FifthShiftActive, Is.False); Assert.That(site2.SnapshotEnabled, Is.True); + Assert.That(site2.UseOneMinuteIntervals, Is.False); Assert.That(site2.Resigned, Is.True); Assert.That(site2.AvatarUrl, Is.EqualTo("https://example.com/avatar2.png")); Assert.That(site2.PhoneNumber, Is.EqualTo("+4587654321")); diff --git a/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Infrastructure/Models/Settings/Site.cs b/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Infrastructure/Models/Settings/Site.cs index 0fda8cf62..0c8369058 100644 --- a/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Infrastructure/Models/Settings/Site.cs +++ b/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Infrastructure/Models/Settings/Site.cs @@ -28,4 +28,5 @@ public class Site public DateTime ResignedAtDate { get; set; } public string? PhoneNumber { get; set; } + public bool UseOneMinuteIntervals { get; set; } } \ No newline at end of file diff --git a/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Protos/settings.proto b/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Protos/settings.proto index 976a4773f..608dc8d41 100644 --- a/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Protos/settings.proto +++ b/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Protos/settings.proto @@ -236,6 +236,7 @@ message Site { bool resigned = 20; google.protobuf.Timestamp resigned_at_date = 21; string phone_number = 22; + bool use_one_minute_intervals = 23; } // Response wrappers matching C# OperationDataResult diff --git a/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Services/GrpcServices/TimePlanningSettingsGrpcService.cs b/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Services/GrpcServices/TimePlanningSettingsGrpcService.cs index e0809558e..fa9d84560 100644 --- a/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Services/GrpcServices/TimePlanningSettingsGrpcService.cs +++ b/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Services/GrpcServices/TimePlanningSettingsGrpcService.cs @@ -266,6 +266,7 @@ public override async Task GetRegistrationSites( ResignedAtDate = Timestamp.FromDateTime( DateTime.SpecifyKind(site.ResignedAtDate, DateTimeKind.Utc)), PhoneNumber = site.PhoneNumber ?? "", + UseOneMinuteIntervals = site.UseOneMinuteIntervals, }; response.Model.Add(grpcSite); } @@ -318,6 +319,7 @@ public override async Task GetRegistrationSitesByC ResignedAtDate = Timestamp.FromDateTime( DateTime.SpecifyKind(site.ResignedAtDate, DateTimeKind.Utc)), PhoneNumber = site.PhoneNumber ?? "", + UseOneMinuteIntervals = site.UseOneMinuteIntervals, }; response.Model.Add(grpcSite); } diff --git a/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Services/TimePlanningSettingService/TimeSettingService.cs b/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Services/TimePlanningSettingService/TimeSettingService.cs index bbf557779..642a589e0 100644 --- a/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Services/TimePlanningSettingService/TimeSettingService.cs +++ b/eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Services/TimePlanningSettingService/TimeSettingService.cs @@ -311,7 +311,8 @@ planRegistrationForToday is FifthShiftActive = assignedSite.FifthShiftActive, Resigned = assignedSite.Resigned, ResignedAtDate = assignedSite.ResignedAtDate, - SnapshotEnabled = assignedSite.SnapshotEnabled + SnapshotEnabled = assignedSite.SnapshotEnabled, + UseOneMinuteIntervals = assignedSite.UseOneMinuteIntervals }; var workerEmail = (worker.Email ?? "").Trim().ToLower(); var user = baseDbContext == null || string.IsNullOrEmpty(workerEmail) ? null : await baseDbContext.Users @@ -617,7 +618,8 @@ planRegistrationForToday is FifthShiftActive = assignedSite.FifthShiftActive, Resigned = assignedSite.Resigned, ResignedAtDate = assignedSite.ResignedAtDate, - SnapshotEnabled = assignedSite.SnapshotEnabled + SnapshotEnabled = assignedSite.SnapshotEnabled, + UseOneMinuteIntervals = assignedSite.UseOneMinuteIntervals }; var workerEmail = (worker.Email ?? "").Trim().ToLower(); var user = baseDbContext == null || string.IsNullOrEmpty(workerEmail) ? null : await baseDbContext.Users @@ -892,6 +894,7 @@ planRegistrationForToday is FifthShiftActive = assignedSite.FifthShiftActive, Resigned = assignedSite.Resigned, ResignedAtDate = assignedSite.ResignedAtDate, + UseOneMinuteIntervals = assignedSite.UseOneMinuteIntervals, }; var workerEmail = (worker.Email ?? "").Trim().ToLower(); var user = baseDbContext == null || string.IsNullOrEmpty(workerEmail) ? null : await baseDbContext.Users