fetchByInviteCode static method

Future<(StudyInvite?, Study?)> fetchByInviteCode(
  1. String code, {
  2. bool previewOnly = false,
})

Fetches a study by invite code using the RPC function.

The RPC is SECURITY DEFINER and returns the full study row plus the matched invite's preselected_intervention_ids as a single jsonb object, so anon deep-link callers can resolve both in one call without needing SELECT access to study_invite (RLS blocks non-editors). Returns the Study and StudyInvite, or nulls if not found.

Implementation

static Future<(StudyInvite?, Study?)> fetchByInviteCode(
  String code, {
  bool previewOnly = false,
}) async {
  final cleanCode = code.trim().toLowerCase();
  try {
    final studyResult = await env.client
        .rpc(
          'get_study_record_from_invite',
          params: {'invite_code': cleanCode},
        )
        .maybeSingle();

    if (studyResult == null || studyResult['id'] == null) {
      return (null, null);
    }

    final study = previewOnly
        ? Study.fromInvitePreviewJson(studyResult)
        : Study.fromJson(studyResult);

    List<String>? preselectedIds;
    final preselected = studyResult['preselected_intervention_ids'];
    if (preselected != null) {
      preselectedIds = List<String>.from(preselected as List);
    }

    final invite = StudyInvite(cleanCode, study.id)
      ..preselectedInterventionIds = preselectedIds;

    return (invite, study);
  } catch (error, stacktrace) {
    SupabaseQuery.catchSupabaseException(error, stacktrace);
    rethrow;
  }
}