Skip to content

fix(timeplanning): self-heal corrupt pauseNId on save (temporary guard)#1609

Merged
renemadsen merged 7 commits into
stablefrom
feat/pauseid-selfheal-guard
Jun 16, 2026
Merged

fix(timeplanning): self-heal corrupt pauseNId on save (temporary guard)#1609
renemadsen merged 7 commits into
stablefrom
feat/pauseid-selfheal-guard

Conversation

@renemadsen

Copy link
Copy Markdown
Member

Why

Some deployed mobile app versions still send the absolute stop-time tick as pauseNId (5-minute sites) instead of the duration, which the server decodes as a huge break and negative netto. The startup batch repair (already on stable) heals history but only at restart; this adds an on-save guard so new saves self-heal regardless of app version, until all customers upgrade.

What

  • Shared PauseIdCorrection.CorrectedPauseId helper = single source of the detect+correct rule; CorruptedPauseIdRepair refactored to use it (behavior-identical).
  • SelfHealCorruptPauseIds guard in TimePlanningWorkingHoursService.UpdateWorkingHour (personal + kiosk write sites), 5-minute sites only, runs after pauseNId+timestamps are set and before the inline netto math, so the corrected id flows into a correct netto. Each correction logs to console + Sentry.
  • Default-on kill switch PauseIdSelfHealEnabled on the plugin settings (no migration); set false + remove the guard once all apps are upgraded.
  • Tests: PauseIdCorrectionTests (unit) + PauseIdSelfHealGuardTests (Testcontainers: corrupt-healed, correct/off-by-one/1-min/flag-off unchanged, kiosk).

Spec: docs/superpowers/specs/2026-06-16-pauseid-selfheal-guard-design.md (flutter-time repo).

🤖 Generated with Claude Code

renemadsen and others added 6 commits June 16, 2026 16:55
…unit tests

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rection

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… on)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ave (5-min sites)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…g, 1-min)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- FixSlot: compute actualMinutes once up front instead of duplicating the
  (stop - start).TotalMinutes expression and the (double?)null branch across
  the corrected/uncorrected paths. Behavior byte-identical: the helper only
  returns a non-null correction when timestamps are valid and ordered, so the
  single up-front value matches both prior branches.
- SelfHealCorruptPauseIds: fully-qualify the AssignedSite? parameter to the
  EF entity type for explicitness, since two same-named AssignedSite types are
  imported unqualified in this file.

No change to the detection threshold, corrected-value math, 5-min/flag gating,
call-site placement, or any test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 16, 2026 14:55

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

Adds a temporary, default-on server-side “self-heal” guard to correct corrupt incoming pauseNId values on 5‑minute sites (caused by older mobile apps sending an absolute stop-tick instead of duration), ensuring netto calculations remain sane at save-time. The PR centralizes the detect+correct logic into a shared helper used by both the startup batch repair and the on-save guard, and adds unit + integration coverage.

Changes:

  • Introduce PauseIdCorrection.CorrectedPauseId(...) as a shared single-source-of-truth helper for detecting/correcting the corrupt pause id.
  • Add SelfHealCorruptPauseIds(...) guard in TimePlanningWorkingHoursService.UpdateWorkingHour paths (personal + kiosk), gated to 5‑minute sites and a default-on kill switch (PauseIdSelfHealEnabled).
  • Add tests for the helper and for end-to-end kiosk-path healing behavior (Testcontainers MariaDB).

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/TimePlanningWorkingHoursService/TimePlanningWorkingHoursService.cs Adds an on-save correction guard and wires it into both personal and kiosk update flows before inline netto math.
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Infrastructure/Models/Settings/TimePlanningBaseSettings.cs Adds PauseIdSelfHealEnabled nullable kill switch (null/true = enabled).
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Infrastructure/Helpers/PauseIdCorrection.cs New shared detect+correct helper (minutes-per-tick + tolerance constants and correction rule).
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn/Infrastructure/Helpers/CorruptedPauseIdRepair.cs Refactors batch repair to use PauseIdCorrection constants + correction logic.
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/PauseIdSelfHealGuardTests.cs New integration tests covering guard behavior across scenarios and kill switch behavior.
eFormAPI/Plugins/TimePlanning.Pn/TimePlanning.Pn.Test/PauseIdCorrectionTests.cs New unit tests covering the correction helper’s decision logic.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@renemadsen renemadsen merged commit 2a960d9 into stable Jun 16, 2026
73 of 75 checks passed
@renemadsen renemadsen deleted the feat/pauseid-selfheal-guard branch June 16, 2026 15:31
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