journal entries that carry a number, not just a tag - #218
Conversation
A tag can only say whether something happened. Most of what people wanted to log has a size: mood, sleep quality, how much water, how much caffeine and when. One coffee and five coffees are not the same day, and the tag vocabulary cannot tell them apart. Nine built-in fields, plus your own — name it, say whether it is a 1-5 rating, an amount, or minutes, and it behaves like a built-in everywhere after that. Caffeine and alcohol also ask when the last one was, because a 200 mg morning coffee and a 200 mg evening one are the same dose and a completely different night. The thing every control here is shaped around: absent and zero are different answers. "No caffeine today" is a measurement, "I didn't fill this in" is not, and reading the second as the first invents a data point at the bottom of the dose range. So a field starts unset, one tap on minus reaches a real zero, a value can always be cleared back to unset, and clearing one deletes it rather than leaving a stale reading nobody made. Ratings run 1-5 rather than 1-10. A ten-point self-report is not ten distinguishable states, and the extra resolution is noise. Forgetting a custom field forgets its label, not its history. Those readings were still real. The journal screen also stops keeping its own private copy of the tag list, which is how it would have drifted from the compose screen the first time either changed.
|
Warning Review limit reached
Next review available in: 48 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (10)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
PR Reviewer Guide 🔍(Review updated until commit 1e3c3af)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to 1e3c3af
Previous suggestionsSuggestions up to commit 8a9805d
|
|
One of the three was real. Custom field definitions were missing from the day export. They are not day-scoped, so the per-day copy loop skipped them, and an exported day ended up holding values under keys like The The unclamped write for a field with no definition is deliberate and, as far as I can tell, unreachable from the UI: removing a custom field drops it from the editor's value map in the same |
|
Persistent review updated to latest commit 1e3c3af |
|
@coderabbitai review |
|
User description
The most-requested journal changes — mood, water, caffeine with a dose and a time, a sleep-quality rating, custom entries — all need the same thing the journal did not have: a number. A tag can only say whether something happened, and one coffee versus five is usually the actual question.
Nine built-in fields ship: mood, sleep quality, energy, stress, soreness, water, caffeine, alcohol, screens before bed. Beyond those you can define your own — name it, say whether it is a 1–5 rating, an amount, or minutes, and it behaves exactly like a built-in everywhere downstream. Caffeine and alcohol also ask when the last one was, because a 200 mg morning coffee and a 200 mg evening one are the same dose and a completely different night, and that is the half that predicts anything.
Absent and zero are different answers, and every control here is shaped around it. "No caffeine today" is a measurement; "I didn't fill this in" is not. Reading the second as the first invents a data point at the very bottom of the dose range, which is exactly where a correlation is most sensitive. So: a field starts unset, one tap on minus reaches a real zero rather than making you step down to it, any value can be cleared back to unset, and clearing one deletes the row instead of leaving a stale reading nobody made. Saving a day replaces that day outright rather than merging into it, for the same reason.
Ratings are 1–5, not 1–10 — a ten-point self-report is not ten distinguishable states, and the extra resolution is noise a rank correlation then has to see through.
Deleting a custom field forgets its label, not its history. Those readings were still real, and they render unlabelled until the field is defined again.
Schema goes to 28. Two new tables, purely additive — an upgrade touches no existing journal row, and a day that only ever had tags keeps them and simply has no numeric rows. There is a migration test from v27 pinning that.
Correlating these fields is deliberately not in this PR. That needs a rank statistic that does not exist in the analytics package yet (OpenStrap/analytics#41), and holding storage and UI hostage to that merge would just make both harder to review. Values are recorded and shown here; the insight wiring follows once the pin moves.
One drive-by: the journal screen kept its own private copy of the preset tag list, which is how it would have drifted from the compose screen the first time either changed.
PR Type
Enhancement, tests
Description
Adds numeric journal fields (mood, sleep quality, energy, stress, soreness, water, caffeine, alcohol, screens) with absent-vs-zero semantics
Schema bumped to v28: two new tables (
journal_metric,journal_field_def), purely additive; existing tag/note rows untouchedUsers can define custom fields (name, kind, unit, ceiling, step, optional time); deleting a definition preserves its history
Journal screen gains a
NUMBERSsection with rating dots and steppers; tag list de-duplicated fromkJournalPresetTagsDiagram Walkthrough
File Walkthrough
7 files
New file: numeric field vocabulary, specs, and value typesSchema v28: journal_metric and journal_field_def tables + CRUDAbstract interface for numeric journal field operationsImplement numeric journal field read/write with value clampingNew widget: rating dots and stepper rows for numeric fieldsNew sheet: define a user-invented numeric journal fieldAdd NUMBERS section; deduplicate tag list; load/save metrics3 files
New tests: field vocabulary, key uniqueness, formatting, valueequalityNew tests: round-trip, zero storage, destructive replace, custom defsPin v27→v28 migration: tags/notes preserved, new tables usableimmediately