| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- """
- Reports API endpoints.
- Provides endpoints for:
- - GET /api/reports - Get paginated list of reports
- - GET /api/reports/detail - Get report details
- - GET /api/reports/download - Download report file
- - POST /api/reports/delete - Delete a report
- """
- import os
- from flask import jsonify, request, send_file, current_app
- from app.api import api_bp
- from app.services import login_required, get_current_user_from_context, get_accessible_reports
- from app.services.report_service import ReportService
- from app.models import Report, Task
- @api_bp.route('/reports', methods=['GET'])
- @login_required
- def get_reports():
- """
- Get paginated list of reports.
-
- Query Parameters:
- page: Page number (default: 1)
- page_size: Items per page (default: 20, max: 100)
- task_id: Optional filter by task ID
-
- Returns:
- JSON with 'data' array and 'pagination' object
- """
- current_user = get_current_user_from_context()
-
- page = request.args.get('page', 1, type=int)
- # Support both pageSize (frontend) and page_size (backend convention)
- page_size = request.args.get('pageSize', type=int) or request.args.get('page_size', type=int) or 20
- page_size = min(page_size, 100)
- task_id = request.args.get('task_id', type=int)
-
- # For regular users, only show their own reports
- user_id = None
- if current_user.role == 'user':
- user_id = current_user.id
-
- result = ReportService.get_reports(
- page=page,
- page_size=page_size,
- task_id=task_id,
- user_id=user_id
- )
-
- return jsonify(result), 200
- @api_bp.route('/reports/detail', methods=['GET'])
- @login_required
- def get_report_detail():
- """
- Get report details.
-
- Query Parameters:
- id: Report ID (required)
-
- Returns:
- JSON with report details
- """
- current_user = get_current_user_from_context()
- report_id = request.args.get('id', type=int)
-
- if not report_id:
- return jsonify({'error': {'code': 'MISSING_PARAMETER', 'message': 'Report ID is required'}}), 400
-
- report = ReportService.get_report_by_id(report_id)
- if not report:
- return jsonify({'error': {'code': 'NOT_FOUND', 'message': 'Report not found'}}), 404
-
- # Check access for regular users
- if current_user.role == 'user':
- task = Task.query.get(report.task_id)
- if not task or task.created_by != current_user.id:
- return jsonify({'error': {'code': 'FORBIDDEN', 'message': 'Access denied'}}), 403
-
- return jsonify(report.to_dict()), 200
- @api_bp.route('/reports/download', methods=['GET'])
- @login_required
- def download_report():
- """
- Download a report file.
-
- Query Parameters:
- id: Report ID (required)
-
- Returns:
- The report file as attachment
- """
- current_user = get_current_user_from_context()
- report_id = request.args.get('id', type=int)
-
- if not report_id:
- return jsonify({'error': {'code': 'MISSING_PARAMETER', 'message': 'Report ID is required'}}), 400
-
- report = ReportService.get_report_by_id(report_id)
- if not report:
- return jsonify({'error': {'code': 'NOT_FOUND', 'message': 'Report not found'}}), 404
-
- # Check access for regular users
- if current_user.role == 'user':
- task = Task.query.get(report.task_id)
- if not task or task.created_by != current_user.id:
- return jsonify({'error': {'code': 'FORBIDDEN', 'message': 'Access denied'}}), 403
-
- # Get file path
- file_path = ReportService.get_report_file_path(report_id)
- if not file_path:
- return jsonify({'error': {'code': 'FILE_NOT_FOUND', 'message': 'Report file not found'}}), 404
-
- return send_file(
- file_path,
- as_attachment=True,
- download_name=report.file_name,
- mimetype='application/vnd.openxmlformats-officedocument.wordprocessingml.document'
- )
- @api_bp.route('/reports/delete', methods=['POST'])
- @login_required
- def delete_report():
- """
- Delete a report.
-
- Request Body:
- id: Report ID (required)
-
- Returns:
- JSON with success message
- """
- current_user = get_current_user_from_context()
- data = request.get_json() or {}
- report_id = data.get('id')
-
- if not report_id:
- return jsonify({'error': {'code': 'MISSING_PARAMETER', 'message': 'Report ID is required'}}), 400
-
- report = ReportService.get_report_by_id(report_id)
- if not report:
- return jsonify({'error': {'code': 'NOT_FOUND', 'message': 'Report not found'}}), 404
-
- # Only admins can delete reports, or users can delete their own
- if current_user.role == 'user':
- task = Task.query.get(report.task_id)
- if not task or task.created_by != current_user.id:
- return jsonify({'error': {'code': 'FORBIDDEN', 'message': 'Access denied'}}), 403
-
- success = ReportService.delete_report(report_id)
- if success:
- return jsonify({'message': 'Report deleted successfully'}), 200
- else:
- return jsonify({'error': {'code': 'DELETE_FAILED', 'message': 'Failed to delete report'}}), 500
|