282 lines
12 KiB
Plaintext
282 lines
12 KiB
Plaintext
=== 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)
|
|
|
|
[✓] Story 5.0: Backend API - POST /api/habits/{id}/check
|
|
Commit: ca4ee77
|
|
Date: 2026-02-10
|
|
|
|
Implementation:
|
|
- Added POST /api/habits/{id}/check endpoint to dashboard/api.py
|
|
- Extracts habit ID from URL path (/api/habits/{id}/check)
|
|
- Adds today's date (YYYY-MM-DD) to completions array
|
|
- Returns 400 if habit already checked today
|
|
- Returns 404 if habit ID not found
|
|
- Sorts completions chronologically (oldest first) after adding
|
|
- Uses ISO date format YYYY-MM-DD (not full timestamps)
|
|
- Calculates and returns streak using calculate_streak utility
|
|
- Returns 200 with updated habit object including streak
|
|
- Streak is calculated but not persisted (only in response)
|
|
- Updates lastUpdated timestamp in habits.json
|
|
- Graceful error handling for missing/corrupt files
|
|
|
|
Tests:
|
|
- Created dashboard/test_habits_check.py
|
|
- Tests for successful habit check (returns 200 + updated habit)
|
|
- Tests for already checked validation (400 error)
|
|
- Tests for habit not found (404 error)
|
|
- Tests for persistence to habits.json
|
|
- Tests for chronological sorting of completions
|
|
- Tests for streak calculation in response
|
|
- Tests for weekly habit checking
|
|
- Tests for ISO date format (YYYY-MM-DD, no time)
|
|
- All 8 tests pass ✓
|
|
- All previous tests (schema, GET, POST, streak) still pass ✓
|
|
|
|
Files modified:
|
|
- dashboard/api.py (added handle_habits_check method + route in do_POST)
|
|
- dashboard/test_habits_check.py (created)
|
|
- dashboard/habits.json (reset to empty for testing)
|
|
|
|
[✓] Story 6.0: Backend API - GET /api/habits with streaks
|
|
Commit: c84135d
|
|
Date: 2026-02-10
|
|
|
|
Implementation:
|
|
- Enhanced GET /api/habits endpoint to include calculated streaks
|
|
- Each habit in response now includes 'streak' field (integer)
|
|
- Each habit in response now includes 'checkedToday' field (boolean)
|
|
- Streak is calculated using the calculate_streak utility function
|
|
- checkedToday checks if today's date (YYYY-MM-DD) is in completions array
|
|
- All original habit fields are preserved in response
|
|
- Get today's date once and reuse for all habits (efficient)
|
|
- Enhanced habits array built by looping through each habit and adding fields
|
|
- Updated docstring to reflect new functionality
|
|
|
|
Tests:
|
|
- Created dashboard/test_habits_get_enhanced.py
|
|
- Tests for streak field inclusion in response
|
|
- Tests for checkedToday boolean field inclusion
|
|
- Tests for correct streak calculation (daily and weekly habits)
|
|
- Tests for broken streaks (should return 0)
|
|
- Tests for empty habits array handling
|
|
- Tests for preservation of original habit fields
|
|
- All 5 tests pass ✓
|
|
- All previous tests (schema, GET, POST, streak, check) still pass ✓
|
|
|
|
Files modified:
|
|
- dashboard/api.py (enhanced handle_habits_get method)
|
|
- dashboard/test_habits_get_enhanced.py (created)
|
|
|
|
[✓] Story 7.0: Frontend - Create habits.html page structure
|
|
Commit: dd0bf24
|
|
Date: 2026-02-10
|
|
|
|
Implementation:
|
|
- Created dashboard/habits.html with basic layout matching dashboard style
|
|
- Uses common.css and swipe-nav.js for consistent styling and navigation
|
|
- Added navigation bar with 5 items (Dashboard, Workspace, KB, Files, Habits)
|
|
- Habits nav item has 'active' class to indicate current page
|
|
- Page header with title "Habit Tracker" and subtitle
|
|
- Empty state section with lucide 'target' icon
|
|
- Empty state message: "Nicio obișnuință încă. Creează prima!"
|
|
- Add habit button with lucide 'plus' icon and text "Adaugă obișnuință"
|
|
- Theme toggle functionality (dark/light mode) matching dashboard
|
|
- Placeholder JavaScript functions for future API integration
|
|
- HTML5 compliant structure with lang="ro" attribute
|
|
|
|
Tests:
|
|
- Created dashboard/test_habits_html.py
|
|
- Tests for file existence
|
|
- Tests for valid HTML5 structure (DOCTYPE, required tags, lang attribute)
|
|
- Tests for common.css and swipe-nav.js inclusion
|
|
- Tests for navigation bar with correct items and active state
|
|
- Tests for page title "Habit Tracker" in both <title> and <h1>
|
|
- Tests for empty state message with exact text
|
|
- Tests for add habit button with lucide plus icon
|
|
- All 7 tests pass ✓
|
|
- All previous tests (schema, API endpoints) still pass ✓
|
|
|
|
Files modified:
|
|
- dashboard/habits.html (created)
|
|
- dashboard/test_habits_html.py (created)
|
|
- dashboard/habits.json (reset to empty for testing)
|
|
|
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
|
CODEBASE PATTERNS UPDATE:
|
|
|
|
5. Frontend HTML Pages
|
|
- Location: dashboard/*.html
|
|
- Common structure: DOCTYPE html, lang="ro", UTF-8 charset
|
|
- Shared resources: common.css, swipe-nav.js, lucide icons CDN
|
|
- Navigation pattern: header.header > logo + nav.nav > nav-item links
|
|
- Active nav item has 'active' class
|
|
- Theme toggle button in nav with onclick="toggleTheme()"
|
|
- Main content in <main class="main"> with max-width container
|
|
- Page header pattern: .page-header > .page-title + .page-subtitle
|
|
- Empty states: .empty-state with centered icon, message, and action button
|
|
- Icons: use lucide via data-lucide attribute, initialize with lucide.createIcons()
|
|
|
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
|
|
NEXT STEPS:
|
|
- Continue with remaining 11 stories
|
|
|
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|