journeys walkthroughs 05 habits - fahadahmed/jamaal-app GitHub Wiki
Journey 5 โ Habits: create, log, pause
Status: done โ gaps G-37 โฆ G-44 raised, decided and applied (see the gap log). The text below is the walkthrough as first written, with the proposals it raised. Register flow F08, screens HB-01 โฆ HB-09 and the Habits section of TD-01. Behaviour is in Habit and Rules engine โ module 2; this page tests it against the schema and engine.
In one line: the user creates a habit of one of four kinds, logs it day by day from Today, reads how it is going from a grid that never "breaks", and can pause it when life gets in the way.
Preconditions: Journeys 1โ4 done. Examples: the onboarding habit Qur'an reading (timed, 15 min), plus Water (counted, 8), Morning run (timed, three times a week), Reading before bed (binary, daily) and No sugary drinks (avoid).
HB-01 The Habits overview
- Sees: the Habits | Anchors segmented control (Habits selected). Groups as cards โ name, "4/5 today", a completion ring, a 14-day aggregate grid โ collapsed by default and expandable into their habits; ungrouped habits; paused habits muted with "Paused โ resumes 19 Oct"; Add at the top; an empty state ("No habits yet โ they'll appear as patterns do.").
- Reads: non-archived
Habits andHabitGroups, their windows, today's and the last 14 days'HabitEntrys,pausesData. - Does: expands a group (local UI state), opens a habit, adds one.
- Assumes:
- the ring and the aggregate grid need no storage โ โ (derived: complete windows รท due windows today; paused habits excluded);
- archived habits can be found again โ โ G-41 (archiving hides a habit, and nothing brings it back).
HB-03 Add or edit a habit
- Sees: first a type picker with plain descriptions โ Did I do it? (binary) ยท Did I do it N times? (counted) ยท Did I do it for N minutes? (timed) ยท Did I avoid it? (avoid). Then a form for that kind: title; the kind's target (a count, minutes, or an allowance of slips); the schedule (daily ยท weekdays ยท custom โ
HB-04); times of day; a reminder per time; a group; an optional note. Presets pre-fill it (the catalogue). - Writes: a
Habit(kind,presetKey,frequency,scheduledDays,targetPerWeek,notes), itsHabitTimeWindows (label,startMinute,endMinute,target,effortMinutes,reminderMinute), and the optionalgrouplink. - Assumes:
- several times a day are possible โ โ G-37 (the schema supports multiple windows, but no screen lets the user add a second one: a medication taken morning and evening can't be made);
- the kind can be changed later โ โ G-42 (history is interpreted by kind โ
amountis a count, minutes or slips โ so changing the kind would silently reinterpret every past day); - editing a target later is safe โ โ (each entry snapshots its
target).
HB-04 Custom recurrence
- Sees: seven day chips or a "N times a week" stepper ("Which days suit you?" / "Target a week").
- Writes:
scheduledDays(fixed days,targetPerWeek = 0) ortargetPerWeek(1โ7, any days). - Assumes: "N times a week" is well defined โ โ G-38 (which days does Today show such a habit on, and can a day be missed when the week is still open?).
HB-05 Groups
- Sees: a name, the habits in it, and the collapsed preview.
- Writes:
HabitGroup(title,sortOrder),Habit.group. - Assumes: a group is purely a visual bundle โ โ (no score or history of its own; archiving never deletes its habits).
TD-01 Logging from Today
- Sees: a habit section ("Habits ยท 4 of 7"): groups as pills, then habits. A binary habit has a check; a counted one a stepper ("3 / 8"); a timed one shows minutes so far with Begin; an avoid one shows Log a slip and Held today. Paused habits are hidden.
- Writes: a
HabitEntryfor the window and the day (created on first log, with itstargetsnapshot): binaryamount0 or 1; counted the count; timed the minutes recomputed from sessions; avoid the slips, withcompletedAtset when the user confirms Held today. Completing the target setscompletedAt. - Assumes:
- the day is the logical date โ โ;
- un-checking is harmless โ โ (the entry goes back to
amount = 0); - the section has a stable order โ โ G-44 (nothing says how habits are ordered);
- a reminder doesn't fire for something already done โ โ G-43 (repeating local notifications can't skip a day).
HB-02 Habit detail
- Sees: the density grid (filled by how much was done; a miss in its own colour; unscheduled, paused and pre-creation days empty), a plain-language read ("Missed 9 of the last 21. Five a week may be more than this season allows โ try three?"), and per-kind figures. Actions: Edit ยท Pause ยท Archive. A habit with several times a day has one grid per time.
- Reads:
HabitEntrys over the window,createdAt,pausesData; the engine's.densityRead. - Does: taps a past cell to correct it.
- Assumes:
- the grid states are fully derived โ โ (module 2: a due past day with no entry or
amount0 is missed; partial shades at 1โ49% and 50โ99%; complete at 100%); - a forgotten day can be put right โ โ G-39 (nothing says whether past days are editable, or how far back);
- the read never scolds โ โ (plain numbers, no praise or blame).
- the grid states are fully derived โ โ (module 2: a due past day with no entry or
HB-06 Pause with a reason
- Sees: dates (from today; an end, or until I resume) and a reason โ travel, illness, cycle, other.
- Writes: an entry in
Habit.pausesData. Paused days become unscheduled: no cell fills, nothing counts against the habit, no reminders, hidden from Today and Night Planning. Resume edits the end date. - Assumes: โ (defined in habit.md; past days keep their entries).
HB-07 Edit and archive
- Does: edits fields (not the kind โ G-42), or archives:
isArchived = true; history is never deleted. - Assumes: archived items stay recoverable โ โ G-41.
HB-08 Avoid habits
- Sees: Log a slip (undoable), Held today, and the allowance; a day stays unresolved until it ends.
- Writes:
HabitEntry.amount(slips);completedAton Held today. - Rules:
missedif slips exceed the allowance;completeonly if within it and the user engaged that day; otherwiseempty. There is no "days since the last slip" counter. - Assumes: "engaged that day" can be computed โ โ G-40 (the docs say "any recorded activity" but don't list which records count, and opening the app leaves no record).
- Note: Settled 8 Oct 2026: Option A (Say it: two actions on the row), as drawn in the v4
HB-08frame. Option B (inferring the hold from the day) is dropped. Built: the three moments on the Today row, and the detail's grid and read.
HB-09 Minutes by hand
- Does: a timed habit's "Add minutes".
- Writes: a finished
WorkSessionwithoutcome = manual(no timing of its own); the day's entry is recomputed. โ (decided in Journey 3).
What the user sees over time
Week one: a few cells filled, the read saying nothing yet. After three weeks of mostly doing it: a dense grid, a read that simply states the numbers. After a holiday: a paused stretch of empty cells, not a run of misses, and no drop in the read. A weekly-target habit (Morning run, three times a week) shows on Today each day until the week's three are done, then quietly stays done; its read says "2 of 3 this week".
Data that exists afterwards (end-state check)
| Model | Change |
|---|---|
Habit |
+ 1 per habit (kind fixed at creation) |
HabitTimeWindow |
โฅ 1 per habit (one all-day by default; more with G-37) |
HabitEntry |
one per window per day logged, with its target snapshot and amount |
HabitGroup |
+ 1 per group |
WorkSession |
timed habits: sessions, and manual ones for minutes added by hand |
Habit.pausesData |
pauses |
Every row is storable now; no new fields are proposed. The gaps are UI, rules and definitions.
Rules and changes this journey implies
If the proposals are accepted:
- Times of day (G-37): the form has a Times of day section: one all-day window by default, Add another time (up to four) adds a labelled window with an optional start, end and reminder. Each window has its own target, entries and grid.
- Weekly-target habits (G-38): Today shows the habit every day of the week until the week's target is met, then as done. Its days are never
missed(nothing breaks, no red): filled days and empty days only, and the read speaks in weeks. A day counts toward the week when its own day target is met. The week follows the calendar's first weekday. - Past days (G-39): the last 14 days in the grid are tappable to correct (binary toggle, counted stepper, timed minutes, avoid slips / Held); older days are read-only. A correction is an explicit engagement for an avoid habit.
- Engagement (G-40): a logical day is engaged if any of these exist for it: a
TaskItemcompleted that day; aHabitEntrywithamount > 0for any habit, or an avoid entry withcompletedAtset (Held today); anAnchorwhoseresolvedAtfalls on that day; aWorkSessionwith thatday; aNightPlanningSessionfor that date that was closed or skipped. Opening the app alone doesn't count. - Archived items (G-41): each list โ habits, Anchor rules, categories (and groups) โ ends with a collapsed Archived section with Restore.
- Kind is fixed (G-42): a habit's
kindcan't change after creation; to change it, archive the habit and create a new one. Every other field is editable (a changedtargetaffects the future only). - Reminders skip what's done (G-43): habit reminders are planned by the notification planner as near-term individual notifications, and cancelled when the habit is logged, paused, archived or its time is edited.
- Order on Today (G-44): groups first (as pills), then ungrouped habits by window start (all-day last), then title.