more api stuff
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
.env
|
.env
|
||||||
|
MOBILE_APP_SPEC.md
|
||||||
|
|||||||
65
app.py
65
app.py
@@ -1060,6 +1060,43 @@ def api_task_detail(user_id, task_id):
|
|||||||
|
|
||||||
# --- Logbook Detail / Edit API ---
|
# --- 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'])
|
@app.route('/api/logbook/<entry_id>', methods=['GET', 'PUT', 'DELETE'])
|
||||||
@token_required
|
@token_required
|
||||||
def api_log_entry(user_id, entry_id):
|
def api_log_entry(user_id, entry_id):
|
||||||
@@ -1170,11 +1207,31 @@ def api_goals(user_id):
|
|||||||
})
|
})
|
||||||
return jsonify({'status': 'created'})
|
return jsonify({'status': 'created'})
|
||||||
|
|
||||||
@app.route('/api/goals/<goal_id>', methods=['DELETE'])
|
@app.route('/api/goals/<goal_id>', methods=['PUT', 'DELETE'])
|
||||||
@token_required
|
@token_required
|
||||||
def api_goal_delete(user_id, goal_id):
|
def api_manage_goal(user_id, goal_id):
|
||||||
db.goals.delete_one({'_id': ObjectId(goal_id), 'user_id': user_id})
|
if request.method == 'DELETE':
|
||||||
return jsonify({'status': 'deleted'})
|
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'
|
debug = os.getenv('DEBUG') == 'False'
|
||||||
host = os.getenv('HOST')
|
host = os.getenv('HOST')
|
||||||
|
|||||||
Reference in New Issue
Block a user