work-tracing/app/api/events.py
ilia-gurielidze-autstand 9e6d0a6911 first commit
2025-05-05 12:12:46 +04:00

85 lines
3.2 KiB
Python

"""
API endpoints for reporting user activity events.
This module provides endpoints for clients to report state changes (working/stopped).
"""
from datetime import datetime
from flask import Blueprint, request, jsonify, current_app
from sqlalchemy.exc import SQLAlchemyError
from app import db
from app.models import WorkEvent
# Create a blueprint for event-related API endpoints
events_bp = Blueprint('events', __name__, url_prefix='/api')
@events_bp.route('/report', methods=['POST'])
def report_event():
"""
Endpoint for clients to report activity state changes.
Expected JSON payload:
{
"user": "username",
"state": "working|stopped",
"ts": "2023-07-08T12:30:45Z" (optional, ISO 8601)
}
"""
data = request.get_json()
current_app.logger.info(f"Received report request: {data}") # Log request
if not data or 'user' not in data or 'state' not in data:
current_app.logger.warning("Invalid report request payload.")
return jsonify({
'success': False,
'message': 'Missing required fields: user, state'
}), 400
# Validate state value
if data['state'] not in ['working', 'stopped']:
return jsonify({
'success': False,
'message': 'Invalid state value. Must be "working" or "stopped"'
}), 400
# Parse timestamp if provided, otherwise use current time
timestamp = None
if 'ts' in data and data['ts']:
try:
timestamp = datetime.fromisoformat(data['ts'].replace('Z', '+00:00'))
except ValueError:
return jsonify({
'success': False,
'message': 'Invalid timestamp format. Use ISO 8601 (YYYY-MM-DDTHH:MM:SSZ)'
}), 400
# Create and store the event
user = data['user']
state = data['state']
ts_str = data.get('ts') # Optional timestamp
event_ts = datetime.utcnow()
if ts_str:
try:
# Attempt to parse ISO 8601 format
event_ts = datetime.fromisoformat(ts_str.replace('Z', '+00:00'))
except ValueError:
current_app.logger.warning(f"Invalid timestamp format received: {ts_str}. Using current UTC time.")
# Optionally return an error here if strict timestamp validation is needed
# return jsonify({"success": False, "message": "Invalid timestamp format"}), 400
new_event = WorkEvent(user=user, state=state, ts=event_ts)
try:
current_app.logger.info(f"Attempting to add event to database: User={user}, State={state}, TS={event_ts}")
db.session.add(new_event)
db.session.commit()
current_app.logger.info(f"Successfully recorded event: User={user}, State={state}")
return jsonify({"success": True}), 201
except SQLAlchemyError as e:
db.session.rollback()
current_app.logger.error(f"Database error while recording event: {e}")
return jsonify({"success": False, "message": "Database error"}), 500
except Exception as e:
current_app.logger.error(f"Unexpected error processing report request: {e}")
return jsonify({"success": False, "message": "Internal server error"}), 500