grantMasteryOverride method

Future<MasteryOverrideModel> grantMasteryOverride({
  1. required String topicId,
  2. required String previousMastery,
  3. required String grantedMastery,
  4. String? reason,
})

Grant a mastery override (self-assessment). Inserts the override record and updates user_topic_progress in one go.

Implementation

Future<MasteryOverrideModel> grantMasteryOverride({
  required String topicId,
  required String previousMastery,
  required String grantedMastery,
  String? reason,
}) async {
  final userId = _client.auth.currentUser?.id;
  if (userId == null) {
    throw StateError('Cannot grant override: user is not authenticated');
  }

  final response = await _client
      .from('mastery_overrides')
      .insert({
        'user_id': userId,
        'topic_id': topicId,
        'previous_mastery': previousMastery,
        'granted_mastery': grantedMastery,
        'granted_by': userId,
        'reason': reason,
      })
      .select()
      .single();

  // Advance mastery via the authorized RPC (the mastery column is
  // trigger-protected against direct client writes; migration 071).
  await setTopicMastery(
    topicId: topicId,
    target: grantedMastery,
    source: 'override',
  );

  // Fire-and-forget: check if any certifications should be auto-issued
  _tryIssueCertificates(topicId);

  return MasteryOverrideModel.fromJson(response);
}