Feature: Habit Tracker with Streak Calculation #1

Closed
Marius wants to merge 26 commits from feature/habit-tracker into master
7 changed files with 1069 additions and 0 deletions
Showing only changes of commit 760e0e031c - Show all commits

165
progress.txt Normal file
View File

@@ -0,0 +1,165 @@
=== HABIT TRACKER FEATURE PROGRESS ===
Date: 2026-02-10
Branch: feature/habit-tracker
Repo: /home/moltbot/clawd
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
COMPLETED STORIES:
[✓] Story 1.0: Define habits.json data schema
Commit: ee8727a
Date: 2026-02-10
Implementation:
- Created dashboard/habits.json with proper schema
- Root structure: lastUpdated (ISO timestamp) + habits (array)
- Habit schema: id (string), name (string), frequency (daily/weekly),
createdAt (ISO), completions (array of ISO dates)
- Initial file contains empty habits array with current timestamp
- All JSON validation passes
Tests:
- Created dashboard/test_habits_schema.py
- Tests for file existence, valid JSON, root structure
- Tests for lastUpdated ISO format validation
- Tests for habits array type
- Tests for complete habit schema (all required fields + types)
- Tests for initial empty state
- All tests pass ✓
Files modified:
- dashboard/habits.json (created)
- dashboard/test_habits_schema.py (created)
[✓] Story 2.0: Backend API - GET /api/habits
Commit: fc5ebf2
Date: 2026-02-10
Implementation:
- Added GET /api/habits endpoint to dashboard/api.py
- Endpoint returns habits array and lastUpdated timestamp
- Graceful error handling: returns empty array if file missing/corrupt
- Follows existing API patterns (similar to /api/git, /api/status)
- Returns 200 status for all valid requests
Tests:
- Created dashboard/test_habits_api.py
- Tests for endpoint existence (returns 200)
- Tests for valid JSON response
- Tests for response structure (habits array + lastUpdated)
- Tests for ISO timestamp validation
- Tests for empty file handling (returns [], not error)
- Tests for habits with data
- All 6 tests pass ✓
Files modified:
- dashboard/api.py (added handle_habits_get method + route)
- dashboard/test_habits_api.py (created)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CODEBASE PATTERNS:
1. JSON Data Files
- Location: dashboard/*.json
- Pattern: Similar structure to tasks.json, todos.json, issues.json
- All use ISO timestamps for dates
- Root objects contain metadata + data arrays
2. Testing Approach
- Python test files in dashboard/ directory
- Test naming: test_*.py
- Comprehensive validation: existence, JSON validity, schema, types
- Run tests from repo root with: python3 dashboard/test_*.py
3. Build Validation
- Command: python3 -m py_compile dashboard/api.py
- Validates Python syntax without executing
4. Utility Functions in api.py
- Standalone utility functions placed before TaskBoardHandler class
- Documented with docstrings (Args, Returns, Rules/behavior)
- ISO timestamp parsing pattern: datetime.fromisoformat(ts.replace('Z', '+00:00'))
- Convert to date only when time doesn't matter: dt.date()
- Use try/except for robust parsing with sensible defaults (return 0, [], etc.)
[✓] Story 3.0: Backend API - POST /api/habits (create habit)
Commit: 3a09e6c
Date: 2026-02-10
Implementation:
- Added POST /api/habits endpoint to dashboard/api.py
- Accepts {name, frequency} in request body
- Returns 400 for missing name or empty name (after trim)
- Returns 400 for invalid frequency (must be 'daily' or 'weekly')
- Generates unique id following format 'habit-{millisecond_timestamp}'
- Sets createdAt to current ISO timestamp
- Initializes completions array as empty
- Persists new habit to habits.json
- Updates lastUpdated timestamp in habits.json
- Returns 201 status with created habit object
- Graceful handling of missing/corrupt habits.json file
Tests:
- Created dashboard/test_habits_post.py
- Tests for successful habit creation (returns 201 + full habit object)
- Tests for habit persistence to habits.json
- Tests for correct id format (habit-{timestamp})
- Tests for missing name validation (400)
- Tests for empty name validation (400)
- Tests for invalid frequency validation (400)
- Tests for missing frequency validation (400)
- Tests for creating multiple habits (unique IDs)
- Tests for lastUpdated timestamp update
- All 9 tests pass ✓
Files modified:
- dashboard/api.py (added handle_habits_post method + route)
- dashboard/test_habits_post.py (created)
[✓] Story 4.0: Backend API - Streak calculation utility
Commit: 3927b7c
Date: 2026-02-10
Implementation:
- Created calculate_streak(completions, frequency) utility function
- Added to dashboard/api.py as standalone function (before TaskBoardHandler class)
- Accepts completions array (ISO timestamps) and frequency ('daily' or 'weekly')
- Returns integer streak count (days for daily, weeks for weekly)
- Daily habits: counts consecutive days without gaps
- Weekly habits: counts consecutive weeks (7-day periods)
- Returns 0 for no completions, invalid dates, or broken streaks
- Edge case: today's completion counts even if streak was 0 yesterday
- Edge case: multiple completions same day/week count as one period
- Robust date parsing with error handling for invalid ISO timestamps
Tests:
- Created dashboard/test_habits_streak.py
- Tests for no completions (returns 0)
- Tests for daily single completion (today and yesterday)
- Tests for daily consecutive days (5 days streak)
- Tests for daily broken streak (gap detection)
- Tests for daily old completion (>1 day ago returns 0)
- Tests for weekly single completion (this week)
- Tests for weekly consecutive weeks (4 weeks streak)
- Tests for weekly broken streak (missing week)
- Tests for weekly old completion (>7 days ago returns 0)
- Tests for multiple completions same day (deduplicated)
- Tests for today counting despite yesterday missing
- Tests for invalid date format handling
- Tests for weekly multiple in same week (deduplicated)
- All 14 tests pass ✓
- All previous tests (schema, GET, POST) still pass ✓
Files modified:
- dashboard/api.py (added calculate_streak function)
- dashboard/test_habits_streak.py (created)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
NEXT STEPS:
- Continue with remaining 14 stories
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━