docs(issues): log KC-40–48 (streak tally, stats, history, banner, calendar rework)
Some checks failed
CI / build-and-test (push) Has been cancelled

Records this session's work in the issue tracker: workout streak → lifetime
tally (KC-40), recurring-aware stats (KC-41), Activity History (KC-42), neutral
Today checkbox (KC-43), swipeable streak banner (KC-44), continuous year view
(KC-45), month TickTick bars+collapse reverted (KC-46), week timeline + drag +
grid toggle (KC-47), week/3-day dead-space fix (KC-48).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
kutesir
2026-07-07 01:17:18 +03:00
parent 3134c064e9
commit 543a1c3ee0

View File

@@ -1245,3 +1245,165 @@ Files: `ExerciseModels.swift`.
Cross-device *live* refresh while the app is open isn't wired (`WorkoutViewModel`
doesn't observe `kisaniCloudDataRefreshed`) — out of scope; the restore-on-launch
path is what preserves state across updates.
---
## KC-40 — Workout streak resets on a missed day (should be a lifetime tally)
**Status:** Implemented (not build-verified — sim runtime unavailable)
**Reported by:** User
**Area:** Workout
### Description
The profile showed a streak of `1` even after 5 workouts that week — a single
skipped/rest day reset it. User wants the count to only ever grow: every
workout achieved counts, a 4/5 week and a 5/5 week both count fully, misses
never subtract.
### Change
`streakDays` is now a lifetime tally of distinct workout days
(`Set(workoutDates).count`, `totalAchievedWorkoutDays`). Removed the
consecutive/weekly-goal chain. Settings copy updated (goal no longer "maintains"
a breakable streak). Unit tests in `StreakLogicTests` (4/5+5/5=9, blank-week,
duplicates, skipped-day, empty) — algorithm also verified via standalone harness.
Files: `ExerciseModels.swift`, `SettingsView.swift`, `KisaniCalTests/StreakLogicTests.swift`.
---
## KC-41 — 7-day bars empty & "this week" = 0 despite a nonzero done rate
**Status:** Implemented (not build-verified)
**Reported by:** User
**Area:** Tasks / Profile stats
### Description
The profile's "COMPLETED LAST 7 DAYS" bars stayed flat and "this week" showed 0
even with completed tasks, because only one-off `completedAt` tasks were counted
— recurring occurrences were ignored.
### Change
Added `TaskViewModel.completionCount(on:)` / `completions(on:)` that count
recurring occurrences (`completedOccurrences`) plus one-offs. Profile bars,
"this week", and a new "day streak" cell now use them.
Files: `TaskItem.swift`, `SettingsView.swift`.
---
## KC-42 — No way to browse historical task/workout activity
**Status:** Implemented (not build-verified)
**Reported by:** User ("we need to be able to dig through the data")
**Area:** Tasks / Workout / History
### Change
New `ActivityHistoryView`: a 90-day, day-by-day archive of completed tasks (with
times, recurring markers), workout logs (sets + volume), and missed / made-up
days. Opened via a "History" button on the profile Tasks card.
Files: `ActivityHistoryView.swift` (new), `SettingsView.swift`.
---
## KC-43 — Today-list checkbox color duplicates the row accent
**Status:** Implemented (not build-verified)
**Reported by:** User
**Area:** Tasks / Today
### Change
`TaskRowView` checkbox stroke changed from `task.quadrant.color` to neutral
`text3` — the row already carries its color on the left accent bar and the
category chip. Calendar day-list checkbox left colored (no accent bar there).
Files: `TodayView.swift`.
---
## KC-44 — Workout streak banner should show week, then year, then comparison
**Status:** Implemented (not build-verified)
**Reported by:** User
**Area:** Workout
### Change
`StreakBannerView` is now a swipeable 3-page TabView: (1) this week + 7 day
ticks, (2) this year + 12 month ticks + all-time total, (3) this-week-vs-last-week
delta. Added VM breakdowns: `workoutsThisWeek/LastWeek/ThisYear`,
`currentWeekDays`, `currentYearMonths`.
Files: `WorkoutView.swift`, `ExerciseModels.swift`.
---
## KC-45 — Calendar year view should scroll continuously (TickTick-style)
**Status:** Implemented (not build-verified)
**Reported by:** User
**Area:** Calendar
### Change
Replaced the single paged year (`◀ 2026 ▶`, dead space below December) with an
infinite `LazyVStack` of years, anchored on the current year (accent-colored).
The top header now follows the scrolled-to year via a `YearTopKey` preference
(iOS 16-safe). Removed `navigateYear` + the year nav header.
Files: `CalendarView.swift`.
---
## KC-46 — Calendar month view: TickTick bars + collapse (REVERTED)
**Status:** Reverted (user preferred the original)
**Reported by:** User
**Area:** Calendar
### Notes
Implemented TickTick-style day bars, collapse-to-week on selection (tap/drag),
and a full-column selection highlight (commits `2ec3278`, `bd43eec`). User
preferred the original month view, so both were reverted (commits `0a87769`,
`e8d74d4`). Month view is back to dots + full grid + agenda below.
Files: `CalendarView.swift`.
---
## KC-47 — Calendar week view should be a TickTick-style timeline
**Status:** Implemented (not build-verified)
**Reported by:** User (screen recording)
**Area:** Calendar
### Change
Replaced the mini-month + agenda-list split with a 7-day timeline (hours down
the left, one column per weekday, events as positioned blocks) reusing
`cvTimeGrid`/`cvDayColumnHeader`. Added:
- **Drag-to-reschedule**: task blocks drag vertically to change time, snapped to
15 min (`CVTimeBlock`, `rescheduleTask`; events + recurring tasks stay fixed).
- **Layout toggle**: timeline ⇄ grid of day-cards (`weekGrid`, `weekGridLayout`).
- Week-swipe navigation (`navigateWeek`).
Known gaps: drag moves time only (not across days); calendar events not draggable.
Files: `CalendarView.swift`.
---
## KC-48 — Week / 3-day views float to the bottom (dead space on top)
**Status:** Fixed (not build-verified)
**Reported by:** User
**Area:** Calendar / Layout
### Root cause
The timeline views are a thin day-header + a greedy `ScrollView` (≈0 ideal
height), so the top-level `VStack` shrank and the `ZStack(alignment:
.bottomTrailing)` floated it to the bottom, leaving a large empty gap above the
header. Month view has a tall fixed grid, so it never surfaced.
### Fix
Pinned the top-level content `VStack` with
`.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .top)`.
Files: `CalendarView.swift`.