SupabaseDatasource class Data Sources

Constructors

SupabaseDatasource(SupabaseClient _client)

Properties

hashCode → int
The hash code for this object.
no setterinherited
runtimeType → Type
A representation of the runtime type of the object.
no setterinherited

Methods

acceptTerms(String version) → Future<void>
Records that the user accepted the given terms version right now.
assignTopicToLevel(String topicId, String? levelId) → Future<void>
Assign a topic to a curriculum level (or null to unassign).
completeAdminOnboarding() → Future<void>
completeOnboarding() → Future<void>
completeValidation({required String sessionId, required String result, String? topicId, String? validationTarget}) → Future<void>
Complete a validation session by setting the result and optionally advancing mastery if the validation was confirmed.
createBookmark({required BookmarkKind kind, required String targetId, String? note}) → Future<BookmarkModel>
Creates a bookmark on the given target. Returns the persisted row. Throws if the user is not authenticated, or if the target is already bookmarked (Postgres unique-violation surfaces as a PostgrestException).
createCard(ReviewCardModel card) → Future<void>
createDomain({required String name, required String slug, String? description, String? iconName}) → Future<DomainModel>
createGoal(Map<String, dynamic> data) → Future<void>
createLevel({required String domainId, required int levelNumber, required String name, String? description}) → Future<CurriculumLevelModel>
Create a new curriculum level within a domain.
createNote(UserNoteModel note) → Future<UserNoteModel>
createSession(Map<String, dynamic> data) → Future<LearningSessionModel>
deleteBookmark(String id) → Future<void>
Deletes a bookmark by its primary key.
deleteBookmarkByTarget({required BookmarkKind kind, required String targetId}) → Future<bool>
Removes the bookmark for the given target if one exists. Returns true if a row was deleted, false if no bookmark existed. Convenience for toggle UIs that don't want to fetch first.
deleteDeviceToken(String fcmToken) → Future<void>
deleteDomain(String domainId) → Future<void>
deleteLevel(String levelId) → Future<void>
Delete a curriculum level by ID.
deleteNote(String noteId) → Future<void>
deleteOwnAccount() → Future<void>
Permanently delete the current user's account and all associated data. Calls a SECURITY DEFINER RPC that handles FK cleanup and auth.users deletion.
enrolInStarter(String domainId) → Future<void>
Adds a curated starter to the learner's library. Nothing is copied — the enrolment is a reference, so progress is recorded against the shared content and fixes to the curriculum reach every learner.
exportUserData() → Future<Map<String, dynamic>>
Export all personal data for the current user (GDPR Article 20). Calls the export-user-data Edge Function which returns a JSON object containing all user-owned data across all tables. Throws FunctionException on server errors (non-2xx status).
findUserIdByEmail(String email) → Future<String?>
Look up a user ID by email (for sharing). Uses an RPC function that accesses auth.users via SECURITY DEFINER.
getAcceptedTermsVersion() → Future<String?>
Returns the terms version the current user has accepted, or null if none.
getActiveSession({required String topicId, required String sessionType}) → Future<LearningSessionModel?>
Returns the most recent active (not ended) session for the given topic and session type, or null if none exists.
getAllProgress() → Future<List<UserTopicProgressModel>>
Fetch all progress rows for the current user (across all domains).
getAllProgressForDomain(String domainId) → Future<List<UserTopicProgressModel>>
Fetch all progress rows for topics in a given domain.
getAllSessionsForTopic({required String topicId, required String sessionType}) → Future<List<LearningSessionModel>>
Returns ALL sessions (active + ended) for the given topic and session type, ordered chronologically. Used to merge conversation history.
getBookmarks({BookmarkKind? filter}) → Future<List<BookmarkModel>>
Returns all bookmarks for the current user, newest first. When filter is non-null, restricts to that bookmark kind.
getChunksForTopic(String topicId) → Future<List<ContentChunkModel>>
getChunksWithEmbeddings(String topicId) → Future<List<(ContentChunkModel, List<double>)>>
Fetch chunks for a topic including their embedding vectors (for local sync).
getDomainAuditLog(String domainId, {int limit = 100}) → Future<List<Map<String, dynamic>>>
Returns audit log entries for a domain the caller can read (owner, org admin, actor/target user, or platform admin — enforced by RLS). Ordered newest-first. Used for the access-history view and for tests.
getDomainIdsWithContent() → Future<Set<String>>
Return the set of domain IDs that have at least one topic with a content chunk. Used to gate goal-eligible domains so users can't bind a learning goal to an empty domain.
getDomains() → Future<List<DomainModel>>
Every domain RLS grants the caller: their own, shares, org content, and anything public.
getDomainsByIds(Set<String> ids) → Future<List<DomainModel>>
getDueCardCount() → Future<int>
Lightweight count of due review cards (avoids fetching full objects).
getDueCards({int limit = 20}) → Future<List<ReviewCardModel>>
getGoals() → Future<List<LearningGoalModel>>
getLastEndedSession({required String topicId, required String sessionType}) → Future<LearningSessionModel?>
Returns the most recent ended session for the given topic and session type, or null if none exists. Used to display past conversations.
getLevelsForDomain(String domainId) → Future<List<CurriculumLevelModel>>
Fetch all levels for a domain, ordered by level_number.
getMasteryOverrides({String? topicId}) → Future<List<MasteryOverrideModel>>
Fetch mastery overrides for the current user, optionally filtered by topic.
getMessages(String sessionId) → Future<List<Map<String, dynamic>>>
getMessagesForSessions(List<String> sessionIds) → Future<List<Map<String, dynamic>>>
Returns all messages across multiple sessions, ordered by created_at.
getMyDomains() → Future<List<DomainModel>>
getNeighborChunks(String topicId, List<int> chunkIndices, {int window = 1}) → Future<List<ContentChunkModel>>
Fetch chunks neighboring the given chunkIndices within a topic.
getNextReviewDate() → Future<DateTime?>
getNoteById(String noteId) → Future<UserNoteModel?>
getNotesCount() → Future<int>
getNotificationPreferences() → Future<Map<String, dynamic>>
getPersona() → Future<String?>
Returns the user's selected persona ('solo' or 'team_lead'), or null if not yet chosen (triggers persona selection screen on next login).
getPreferredVariants() → Future<Map<String, String>>
Returns { familyName: variantString } from profiles.settings.preferred_variants.
getPrivacySettings() → Future<Map<String, dynamic>>
getProfile() → Future<ProfileModel?>
Fetch the full profile row including onboarding state columns. Returns null if the user is not authenticated or the row doesn't exist.
getProgress(String topicId) → Future<UserTopicProgressModel?>
getReadingQuestions(String topicId) → Future<List<ReadingQuestionModel>>
getRecentSessions({int limit = 10}) → Future<List<LearningSessionModel>>
getReviewHistory(String cardId, {int limit = 50}) → Future<List<ReviewLogModel>>
getReviewSummariesForDomain(String domainId) → Future<Map<String, ({bool due, int? intervalDays})>>
Per-topic review summary for a domain. For each topic with at least one review card, returns the longest interval_days and whether any of its cards are due (next_review_at <= now). Topics with no cards are absent from the returned map.
getSeenTooltips() → Future<Set<String>>
Read the set of tooltip keys the user has already dismissed. Returns an empty set if the column is unset or empty.
getSessionCountsByDay({required DateTime since}) → Future<Map<DateTime, int>>
Returns a date-only → session-count map for sessions that started on or after since. Used to drive the progress-dashboard heatmap. Days with no activity are omitted; callers can default missing keys to 0.
getSessionDates({int limit = 90}) → Future<List<DateTime>>
Distinct session dates for streak calculation, descending.
getSharedWithMe() → Future<List<DomainModel>>
getSharesForDomain(String domainId) → Future<List<Map<String, dynamic>>>
getStarterDomains() → Future<List<DomainModel>>
The curated catalog. Readable by anyone — starters are public — so this works before the learner owns any content of their own.
getStarterEnrollmentIds() → Future<Set<String>>
Ids of the starter curricula the current user has opted into.
getTopicById(String topicId) → Future<TopicModel?>
Fetch a single topic by ID.
getTopicIdsWithContent(String domainId) → Future<Set<String>>
Return the set of topic IDs (within domainId) that have at least one content chunk. Used to hide content-less leaves from the topic tree.
getTopicsByIds(Set<String> ids) → Future<List<TopicModel>>
Batch-fetch topics by ID in a single round-trip. Mirrors getDomainsByIds. Returns an empty list when ids is empty so callers don't need a guard.
getTopicsForBook(String bookId) → Future<List<TopicModel>>
Fetch all topics belonging to a specific book.
getTopicsForLevel(String levelId) → Future<List<TopicModel>>
Fetch topics assigned to a specific curriculum level.
getTopicTree(String domainId) → Future<List<TopicModel>>
Fetch all topics for a domain and build a tree using parent_topic_id.
getTotalCardCount() → Future<int>
getUserNotes({String? topicId, String? search, int limit = 50}) → Future<List<UserNoteModel>>
getUserTargetRetention() → Future<double>
grantMasteryOverride({required String topicId, required String previousMastery, required String grantedMastery, String? reason}) → Future<MasteryOverrideModel>
Grant a mastery override (self-assessment). Inserts the override record and updates user_topic_progress in one go.
insertChunks(List<Map<String, dynamic>> rows) → Future<int>
Insert content-chunk rows in batches of 50.
insertTopics(List<Map<String, dynamic>> rows) → Future<List<Map<String, dynamic>>>
Insert topic rows in a single batch. Each map must include keys matching the topics table columns (id, domain_id, parent_topic_id, title, depth, sort_order). Returns the inserted rows.
isBookmarked({required BookmarkKind kind, required String targetId}) → Future<bool>
Whether the current user has bookmarked the given target.
leaveStarter(String domainId) → Future<void>
Removes a starter from the library. Progress rows are left untouched, so re-enrolling later resumes where the learner left off.
logReview(ReviewLogModel log) → Future<void>
markTooltipSeen(String key) → Future<void>
Mark a tooltip as seen by upserting its key into seen_tooltips JSONB.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
resetAdminOnboarding() → Future<void>
Clear admin onboarding so it can be replayed (e.g. for a different org).
resetOnboarding() → Future<void>
Reset learner onboarding so the user can replay from the beginning.
resolveBookmarkTarget({required BookmarkKind kind, String? topicId, String? chunkId, String? sessionId}) → Future<({String? domainSlug, String? topicId, String? topicTitle})>
Resolves a bookmark target to its owning topic (id + title) and that topic's domain slug, so the UI can build a real lesson/tutor route and a readable title. Chunk and session bookmarks resolve their owning topic first. Any field is null when it can't be resolved (e.g. orphaned target).
saveMessage(String sessionId, String role, String content, {String? id}) → Future<void>
Persist a conversation_messages row. When id is supplied (offline- outbox path), uses upsert(onConflict: 'id', ignoreDuplicates: true) so a replay of an already-applied write is a no-op rather than a duplicate-key error. Without id, the migration's DEFAULT gen_random_uuid() fires server-side as before.
saveReadingQuestions(List<ReadingQuestionModel> questions) → Future<void>
searchChunks(String query, {String? topicId, String? domainId, int limit = 8}) → Future<List<ContentChunkModel>>
searchChunksSemantic(List<double> queryEmbedding, {String? topicId, String? domainId, double threshold = 0.3, int limit = 8}) → Future<List<ContentChunkModel>>
Semantic search via pgvector cosine similarity (requires embeddings).
setAdminOnboardingOrgId(String? orgId) → Future<void>
setAdminOnboardingStep(String step) → Future<void>
setOnboardingStep(String step) → Future<void>
Learner onboarding step (welcome, why_socratic, first_session, review_intro, mastery_explained, completed).
setPersona(String persona) → Future<void>
setTopicMastery({required String topicId, required String target, required String source, String? sessionId}) → Future<void>
Advance a topic's mastery through the server-side authorization RPC (set_topic_mastery, migration 071). Direct writes to the mastery column are blocked by a DB trigger, so mastery must never be written via updateProgress. The RPC re-derives the allowed transition from source — one of 'awareness', 'session', 'validation', or 'override' — and throws (PostgrestException) if the transition is not permitted. sessionId is required for the 'session' and 'validation' sources.
shareDomain(String domainId, String targetUserId, {String permission = 'read'}) → Future<void>
submitReadingResponse({required String questionId, required String responseText, bool? isCorrect}) → Future<void>
toString() → String
A string representation of this object.
inherited
unshareDomain(String domainId, String targetUserId) → Future<void>
Soft-deletes a curriculum share by setting revoked_at and revoked_by. The row is preserved (not hard-deleted) so the audit trigger records a domain.unshared event. Only the active (non-revoked) share is updated.
updateCard(String cardId, Map<String, dynamic> updates) → Future<void>
updateDomainVisibility(String domainId, String visibility) → Future<void>
updateGoal(String goalId, Map<String, dynamic> updates) → Future<void>
updateLevel(String levelId, {String? name, String? description}) → Future<void>
Update a curriculum level's name and/or description.
updateNote(String noteId, Map<String, dynamic> updates) → Future<void>
updateNotificationPreferences(Map<String, dynamic> prefs) → Future<void>
updatePassword(String newPassword) → Future<void>
Update the authenticated user's password. Throws AuthException on failure.
updatePreferredVariants(Map<String, String> variants) → Future<void>
updatePrivacySettings(Map<String, dynamic> prefs) → Future<void>
updateProfile({String? displayName, String? avatarUrl}) → Future<void>
Update top-level profile fields (display name, avatar). Pass only the fields that should change; nulls are ignored.
updateProgress(String topicId, Map<String, dynamic> updates) → Future<void>
updateSession(String sessionId, Map<String, dynamic> updates) → Future<void>
upsertDeviceToken(String fcmToken, String platform) → Future<void>
upsertNote(Map<String, dynamic> data) → Future<void>
Idempotent insert for replay paths that have only the raw payload map (e.g. SyncWorker). Requires data["id"].
upsertReviewLog(Map<String, dynamic> data) → Future<void>
Idempotent insert for replay paths that have only the raw payload map (e.g. SyncWorker) rather than a ReviewLogModel. Requires data["id"] to exist.
upsertSession(Map<String, dynamic> data) → Future<void>
Idempotent session insert for the offline-outbox flow. data must include id (a client-generated UUID) so a replay of an already- applied write is a no-op rather than a duplicate-key error. Does not return the row — the caller already knows the id and any server-defaulted fields (e.g. started_at) it needs were provided at enqueue time.
verifyCurrentPassword(String email, String currentPassword) → Future<void>
Re-authenticate the user with their current password. Throws AuthException if the password is wrong.

Operators

operator ==(Object other) → bool
The equality operator.
inherited