cyberhybridhub/server/lib/handlers/incoming_question_handler.dart

83 lines
2.5 KiB
Dart

import 'dart:convert';
import 'dart:io';
import 'package:shelf/shelf.dart';
import '../cors_headers.dart';
import '../firebase_auth.dart';
import '../questions_db.dart';
import 'questions_hub_handler.dart';
/// REST helper to push a question to the signed-in user over SignalR.
Handler incomingQuestionHandler({
required FirebaseAuthVerifier auth,
required QuestionsDb questionsDb,
}) {
return (Request request) async {
if (request.method == 'OPTIONS') {
return Response.ok('', headers: apiCorsHeaders());
}
final String? firebaseUid = await auth.verifyBearerToken(
request.headers['Authorization'] ?? request.headers['authorization'],
);
if (firebaseUid == null) {
return _jsonResponse(401, <String, dynamic>{'error': 'Unauthorized'});
}
if (request.requestedUri.path != '/v1/me/incoming-question') {
return _jsonResponse(404, <String, dynamic>{'error': 'Not found'});
}
if (request.method != 'POST') {
return _jsonResponse(405, <String, dynamic>{'error': 'Method not allowed'});
}
try {
final String body = await request.readAsString();
final Map<String, dynamic> json = body.isEmpty
? <String, dynamic>{}
: jsonDecode(body) as Map<String, dynamic>;
final String text = (json['text'] as String?)?.trim().isNotEmpty == true
? (json['text'] as String).trim()
: 'You have a new question.';
final num correctAnswer = (json['correctAnswer'] as num?) ?? 0;
final Map<String, dynamic> question = await questionsDb.createQuestion(
assignedUserId: firebaseUid,
questionText: text,
correctAnswer: correctAnswer,
);
final int unansweredCount =
await questionsDb.countUnansweredQuestions(firebaseUid);
final Map<String, dynamic> payload = questionsDb.toClientPayload(
question,
unansweredCount: unansweredCount,
);
final int delivered = await questionsHubConnections.pushQuestion(
firebaseUid,
payload,
);
return _jsonResponse(200, <String, dynamic>{
'question': question,
'deliveredToConnections': delivered,
});
} catch (e, st) {
stderr.writeln('Incoming question handler error: $e\n$st');
return _jsonResponse(500, <String, dynamic>{'error': 'Internal error'});
}
};
}
Response _jsonResponse(int status, Map<String, dynamic> body) {
return Response(
status,
body: jsonEncode(body),
headers: <String, String>{
...apiCorsHeaders(),
'Content-Type': 'application/json',
},
);
}