Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ Rules:
- Released versions are immutable — never re-tag, never amend, never delete an entry
- Merge conflicts must preserve both sides; if both branches used the same version string, renumber the lower-priority one upward

---
## [0.47.2-beta.1] - 2026-06-10

### Fixed
- Logging a slider tracker without dragging it now saves using the slider's displayed default value, instead of silently doing nothing.

---
## [0.47.1-beta.1] - 2026-06-06

Expand Down
3 changes: 3 additions & 0 deletions LESSONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ A flag like `allowMultiple` controls whether saving a log upserts an existing ro
**Remap all foreign keys on data import**
When importing data that generates new primary IDs (e.g. JSON/CSV restore), every foreign key referencing those IDs must also be remapped. Importing parent records with new IDs but leaving child records pointing at old IDs silently breaks relational integrity.

**A `null` "not yet interacted" state must not be read as "no value to save"**
When a UI shows a default value (e.g. a slider rendered at `numericMin` via `value ?: min`) but the backing state field stays `null` until the user actively changes it, a save handler that does `val v = state.value ?: return` silently no-ops for anyone who accepts the displayed default without touching the control. The UI looks identical (same value shown) whether or not the user interacted, so there's no visual cue that "Save" did nothing. Fix at the save site by falling back to the same default the UI displays (`state.value ?: category.min`), not by requiring interaction.

**Store the per-event delta on the event record, not only in the running aggregate**
When an action adds to a running total (points, balance, count), store the per-event amount on the event itself. Every deletion and undo path can then read and subtract that stored delta, keeping the aggregate in sync. An aggregate that's only ever incremented drifts away from the true value over time — the only reliable fix is a symmetric decrement path that reads from the event record.

Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ android {
applicationId = "com.mapgie.goflo"
minSdk = 26
targetSdk = 34
versionCode = 101
versionName = "0.47.1-beta.1"
versionCode = 102
versionName = "0.47.2-beta.1"
}

signingConfigs {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,9 @@ class LogCategoryViewModel(
// Determine the values to persist
val valuesToSave: Set<String> = when (cat?.categoryType) {
"numeric_slider" -> {
val v = state.numericValue ?: return // nothing to save yet
// Null means the user hasn't dragged the slider; fall back to its
// displayed default (numericMin) rather than blocking the save.
val v = state.numericValue ?: cat.numericMin
setOf(formatNumericValue(v, cat.allowDecimals))
}
"numeric_free" -> {
Expand Down
Loading