Skip to content

Feature: Habits v2 Step 2 - frequency + decouple deadline from schedule #75

Description

@manucompiles

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions