What we're building
Habits v2 Step 2 (deferred from #73). Two intertwined improvements to how habits are scheduled, shipped together because frequency builds on the decouple-deadline foundation.
Part 1 - Decouple deadline from a habit's schedule
A habit can carry a schedule without a hard due date. Relaxed the 'recurrence requires a deadline' rule for habits only; non-habit recurring tasks keep the deadline-anchor requirement.
Part 2 - Habit frequency ('x times a week')
A habit's schedule is ONE of two modes: specific days (existing recurrence) OR x-times-a-week (new weekly target, calendar week Mon-Sun). Frequency streak: green (>= target) / yellow (1..target-1) / grey (0); streak = consecutive green-or-yellow weeks, grey breaks.
Scope
In scope: deadline relaxation for habits; new nullable WeeklyTarget column (migration); frequency-aware streak (pure helper); extended HabitResponse; two-mode picker; HabitCard frequency UI; MCP weeklyTarget.
Out of scope (backlog): combined count+days mode; 'x times a month'; per-habit minimum floor; calendar heatmap.
Plan
docs/plans/_archive/P75-habits-v2-step2.md
Outcome
What was built:
- Backend: nullable WeeklyTarget column + migration AddHabitWeeklyTarget; TasksController POST/PATCH validation (habits-only, 1-7, mode exclusivity, deadline-free habit recurrence, isHabit processed first); new pure Services/HabitFrequency.cs (Monday weeks, this-week count, week-streak with grace, met/partial/none); HabitResponse extended (unit-aware CurrentStreak + WeeklyTarget/ThisWeekCount/RecentWeeks).
- MCP: weeklyTarget (1-7) on create_task/update_task + api-client.
- Frontend: Due chip hidden for habits; RecurrencePicker isHabit un-gate; TaskSheet two-mode schedule picker (recurrence XOR weeklyTarget); HabitCard frequency view (n/x this week, week streak, green/yellow/grey week strip) with shared CheckInButton.
Verified:
- Tests green: backend 270 (+20), frontend 138 (+2), MCP 101 (+4). Live API smoke: created a deadline-free 3x/week habit, checked in, /api/habits returned weeklyTarget/thisWeekCount/week-streak/recentWeeks correctly.
- Code review (3 sub-agents): 0 blocks, 0 warns; 2 suggestions applied (extracted CheckInButton, clarified frequency branch comment).
Issues raised during this work: none (2 review suggestions were applied inline).
What we're building
Habits v2 Step 2 (deferred from #73). Two intertwined improvements to how habits are scheduled, shipped together because frequency builds on the decouple-deadline foundation.
Part 1 - Decouple deadline from a habit's schedule
A habit can carry a schedule without a hard due date. Relaxed the 'recurrence requires a deadline' rule for habits only; non-habit recurring tasks keep the deadline-anchor requirement.
Part 2 - Habit frequency ('x times a week')
A habit's schedule is ONE of two modes: specific days (existing recurrence) OR x-times-a-week (new weekly target, calendar week Mon-Sun). Frequency streak: green (>= target) / yellow (1..target-1) / grey (0); streak = consecutive green-or-yellow weeks, grey breaks.
Scope
In scope: deadline relaxation for habits; new nullable WeeklyTarget column (migration); frequency-aware streak (pure helper); extended HabitResponse; two-mode picker; HabitCard frequency UI; MCP weeklyTarget.
Out of scope (backlog): combined count+days mode; 'x times a month'; per-habit minimum floor; calendar heatmap.
Plan
docs/plans/_archive/P75-habits-v2-step2.md
Outcome
What was built:
Verified:
Issues raised during this work: none (2 review suggestions were applied inline).