reportSurveyCompleted method

void reportSurveyCompleted(
  1. Map<String, dynamic> response, [
  2. Map<String, SurveyAnswer> answers = const {}
])

Fired once when the survey finishes (idempotent per showing). Beyond the Completed analytics event, answers (when supplied) are POSTed to the backend's recordSubmission endpoint via SubmissionReporter.

Implementation

void reportSurveyCompleted(
  Map<String, dynamic> response, [
  Map<String, SurveyAnswer> answers = const {},
]) {
  final state = _surveyOrchestrator.state;
  if (state == null || _completedSurveyToken == state.token) return;
  _completedSurveyToken = state.token;
  _recordCompleted(state.campaign.campaignKey);
  _events.toDigia(
    SurveyCompleted(
      itemTotal: _surveyItemTotal(state.config),
      answeredCount: answers.isNotEmpty ? answers.length : response.length,
      timeToCompleteMs:
          DateTime.now().millisecondsSinceEpoch - state.startedAtMs,
      response: response,
    ),
    state.payload,
  );

  if (answers.isEmpty) {
    _log.d(
      'Survey submission skipped because no questions were answered',
      campaign: state.campaign.campaignKey,
    );
    return;
  }

  // A live test's answers must not land in the project's real submission
  // data — they are one person pressing buttons, not a respondent. They go
  // to whoever started the test instead, and nowhere else.
  if (isLiveTestCepId(state.payload.cepCampaignId)) {
    _relayLiveTestSubmission(
        state.campaign, state.payload, answers, state.startedAtMs);
    return;
  }
  _log.d(
      'Survey submission started (campaignId=${state.campaign.id}, '
      'answers=${answers.length})',
      campaign: state.campaign.campaignKey);
  final services = _services;
  services?.submissionReporter.reportSurveyCompleted(
    state.campaign,
    answers,
    state.startedAtMs,
    services.identityManager.userId,
  );
}