more api stuff

This commit is contained in:
2026-02-11 15:06:31 +01:00
parent 1f2fff109f
commit d6c66f54ad
2 changed files with 62 additions and 4 deletions

1
.gitignore vendored
View File

@@ -1 +1,2 @@
.env
MOBILE_APP_SPEC.md

65
app.py
View File

@@ -1060,6 +1060,43 @@ def api_task_detail(user_id, task_id):
# --- Logbook Detail / Edit API ---
@app.route('/api/logbook', methods=['GET'])
@token_required
def api_logbook_list(user_id):
# Fetch last 100 entries
entries = list(db.time_entries.find({'user_id': user_id}).sort('start_time', -1).limit(100))
result = []
# Cache activities to avoid N+1 queries
activities = {a['_id']: a for a in db.activities.find({'user_id': user_id})}
for entry in entries:
act = activities.get(entry.get('activity_id'))
# Calculate duration string
duration_str = "Running"
total_seconds = 0
if entry.get('end_time') and entry.get('start_time'):
diff = entry['end_time'] - entry['start_time']
total_seconds = diff.total_seconds()
hours = int(total_seconds // 3600)
mins = int((total_seconds % 3600) // 60)
duration_str = f"{hours:02}:{mins:02}"
result.append({
'id': str(entry['_id']),
'activity_name': act['name'] if act else 'Unknown',
'activity_color': act.get('color', '#ccc') if act else '#ccc',
'start_time': entry['start_time'].isoformat(),
'end_time': entry['end_time'].isoformat() if entry.get('end_time') else None,
'duration_str': duration_str,
'duration_seconds': total_seconds,
'note': entry.get('note', ''),
'subcategory': entry.get('subcategory', '')
})
return jsonify(result)
@app.route('/api/logbook/<entry_id>', methods=['GET', 'PUT', 'DELETE'])
@token_required
def api_log_entry(user_id, entry_id):
@@ -1170,11 +1207,31 @@ def api_goals(user_id):
})
return jsonify({'status': 'created'})
@app.route('/api/goals/<goal_id>', methods=['DELETE'])
@app.route('/api/goals/<goal_id>', methods=['PUT', 'DELETE'])
@token_required
def api_goal_delete(user_id, goal_id):
db.goals.delete_one({'_id': ObjectId(goal_id), 'user_id': user_id})
return jsonify({'status': 'deleted'})
def api_manage_goal(user_id, goal_id):
if request.method == 'DELETE':
db.goals.delete_one({'_id': ObjectId(goal_id), 'user_id': user_id})
return jsonify({'status': 'deleted'})
if request.method == 'PUT':
data = request.get_json()
update_fields = {}
if 'name' in data: update_fields['name'] = data['name']
if 'target_hours' in data: update_fields['target_hours'] = float(data['target_hours'])
if 'frequency' in data: update_fields['frequency'] = data['frequency']
if 'activity_id' in data: update_fields['activity_id'] = ObjectId(data['activity_id'])
if 'subcategory' in data: update_fields['subcategory'] = data['subcategory']
result = db.goals.update_one(
{'_id': ObjectId(goal_id), 'user_id': user_id},
{'$set': update_fields}
)
if result.matched_count == 0:
return jsonify({'message': 'Goal not found'}), 404
return jsonify({'status': 'updated'})
debug = os.getenv('DEBUG') == 'False'
host = os.getenv('HOST')