cyberhybridhub/server/lib/question_service.dart
2026-05-31 11:17:12 -05:00

88 lines
2.9 KiB
Dart

import 'dart:async';
import 'dart:io';
import 'questions_db.dart';
import 'signalr/questions_hub_connections.dart';
/// Creates questions in Postgres and delivers them over SignalR.
class QuestionService {
QuestionService({
required QuestionsDb questionsDb,
required QuestionsHubConnections hubConnections,
}) : _questionsDb = questionsDb,
_hubConnections = hubConnections;
final QuestionsDb _questionsDb;
final QuestionsHubConnections _hubConnections;
/// Called at login: ensures a starter question exists when the user has none.
Future<Map<String, dynamic>> ensureStarterQuestionOnLogin(
String firebaseUid,
) async {
final Map<String, dynamic> question =
await _questionsDb.getOrCreateStarterQuestion(firebaseUid);
final int unansweredCount =
await _questionsDb.countUnansweredQuestions(firebaseUid);
final Map<String, dynamic> payload = _questionsDb.toClientPayload(
question,
unansweredCount: unansweredCount,
);
await _hubConnections.pushQuestion(firebaseUid, payload);
return payload;
}
/// Inserts a question and pushes it to connected SignalR clients.
Future<Map<String, dynamic>> createAndDeliverQuestion({
required String assignedUserId,
required String questionText,
required num correctAnswer,
String? sourceTag,
String? pipelineKey,
String? pipelineStep,
Map<String, dynamic>? metadata,
}) async {
final Map<String, dynamic> question = await _questionsDb.createQuestion(
assignedUserId: assignedUserId,
questionText: questionText,
correctAnswer: correctAnswer,
sourceTag: sourceTag,
pipelineKey: pipelineKey,
pipelineStep: pipelineStep,
metadata: metadata,
);
final int unansweredCount =
await _questionsDb.countUnansweredQuestions(assignedUserId);
final Map<String, dynamic> payload = _questionsDb.toClientPayload(
question,
unansweredCount: unansweredCount,
);
await _hubConnections.pushQuestion(assignedUserId, payload);
return payload;
}
/// On SignalR connect: deliver an existing unanswered question only (no create).
Future<void> deliverPendingQuestionOnConnect(
QuestionsHubConnection connection,
) async {
try {
final String uid = connection.firebaseUid;
final Map<String, dynamic>? question =
await _questionsDb.findUnansweredQuestion(uid);
if (question == null) {
return;
}
final int unansweredCount =
await _questionsDb.countUnansweredQuestions(uid);
final Map<String, dynamic> payload = _questionsDb.toClientPayload(
question,
unansweredCount: unansweredCount,
);
await _hubConnections.pushQuestionToConnection(connection, payload);
} catch (e, st) {
stderr.writeln(
'Failed to deliver pending question for ${connection.firebaseUid}: $e\n$st',
);
}
}
}