feat: 5.0 - Backend API - POST /api/habits/{id}/check
This commit is contained in:
@@ -151,6 +151,8 @@ class TaskBoardHandler(SimpleHTTPRequestHandler):
|
||||
self.handle_pdf_post()
|
||||
elif self.path == '/api/habits':
|
||||
self.handle_habits_post()
|
||||
elif self.path.startswith('/api/habits/') and self.path.endswith('/check'):
|
||||
self.handle_habits_check()
|
||||
elif self.path == '/api/workspace/run':
|
||||
self.handle_workspace_run()
|
||||
elif self.path == '/api/workspace/stop':
|
||||
@@ -881,6 +883,93 @@ class TaskBoardHandler(SimpleHTTPRequestHandler):
|
||||
except Exception as e:
|
||||
self.send_json({'error': str(e)}, 500)
|
||||
|
||||
def handle_habits_check(self):
|
||||
"""Mark a habit as completed for today."""
|
||||
try:
|
||||
# Extract habit ID from path: /api/habits/{id}/check
|
||||
path_parts = self.path.split('/')
|
||||
if len(path_parts) < 4:
|
||||
self.send_json({'error': 'Invalid path'}, 400)
|
||||
return
|
||||
|
||||
habit_id = path_parts[3] # /api/habits/{id}/check -> index 3 is id
|
||||
|
||||
# Get today's date in ISO format (YYYY-MM-DD)
|
||||
today = datetime.now().date().isoformat()
|
||||
|
||||
# Read habits file
|
||||
habits_file = KANBAN_DIR / 'habits.json'
|
||||
if not habits_file.exists():
|
||||
self.send_json({'error': 'Habit not found'}, 404)
|
||||
return
|
||||
|
||||
try:
|
||||
habits_data = json.loads(habits_file.read_text(encoding='utf-8'))
|
||||
except (json.JSONDecodeError, IOError):
|
||||
self.send_json({'error': 'Habit not found'}, 404)
|
||||
return
|
||||
|
||||
# Find the habit by ID
|
||||
habit = None
|
||||
habit_index = None
|
||||
for i, h in enumerate(habits_data.get('habits', [])):
|
||||
if h.get('id') == habit_id:
|
||||
habit = h
|
||||
habit_index = i
|
||||
break
|
||||
|
||||
if habit is None:
|
||||
self.send_json({'error': 'Habit not found'}, 404)
|
||||
return
|
||||
|
||||
# Check if already checked today
|
||||
completions = habit.get('completions', [])
|
||||
|
||||
# Extract dates from completions (they might be ISO timestamps, we need just the date part)
|
||||
completion_dates = []
|
||||
for comp in completions:
|
||||
try:
|
||||
# Parse ISO timestamp and extract date
|
||||
dt = datetime.fromisoformat(comp.replace('Z', '+00:00'))
|
||||
completion_dates.append(dt.date().isoformat())
|
||||
except (ValueError, AttributeError):
|
||||
# If parsing fails, assume it's already a date string
|
||||
completion_dates.append(comp)
|
||||
|
||||
if today in completion_dates:
|
||||
self.send_json({'error': 'Habit already checked today'}, 400)
|
||||
return
|
||||
|
||||
# Add today's date to completions
|
||||
completions.append(today)
|
||||
|
||||
# Sort completions chronologically (oldest first)
|
||||
completions.sort()
|
||||
|
||||
# Update habit
|
||||
habit['completions'] = completions
|
||||
|
||||
# Calculate streak
|
||||
frequency = habit.get('frequency', 'daily')
|
||||
streak = calculate_streak(completions, frequency)
|
||||
|
||||
# Add streak to response (but don't persist it in JSON)
|
||||
habit_with_streak = habit.copy()
|
||||
habit_with_streak['streak'] = streak
|
||||
|
||||
# Update habits data
|
||||
habits_data['habits'][habit_index] = habit
|
||||
habits_data['lastUpdated'] = datetime.now().isoformat()
|
||||
|
||||
# Write back to file
|
||||
habits_file.write_text(json.dumps(habits_data, indent=2), encoding='utf-8')
|
||||
|
||||
# Return 200 OK with updated habit including streak
|
||||
self.send_json(habit_with_streak, 200)
|
||||
|
||||
except Exception as e:
|
||||
self.send_json({'error': str(e)}, 500)
|
||||
|
||||
def handle_files_get(self):
|
||||
"""List files or get file content."""
|
||||
from urllib.parse import urlparse, parse_qs
|
||||
|
||||
Reference in New Issue
Block a user