86 lines
2.8 KiB
Dart
86 lines
2.8 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,
|
|
}) async {
|
|
final Map<String, dynamic> question = await _questionsDb.createQuestion(
|
|
assignedUserId: assignedUserId,
|
|
questionText: questionText,
|
|
correctAnswer: correctAnswer,
|
|
sourceTag: sourceTag,
|
|
pipelineKey: pipelineKey,
|
|
pipelineStep: pipelineStep,
|
|
);
|
|
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',
|
|
);
|
|
}
|
|
}
|
|
}
|