This document describes the session management system in Hyprnote, which handles the creation, storage, retrieval, and lifecycle management of note-taking sessions. A session represents a single note-taking event, potentially linked to a calendar event, and contains transcription data, notes, participants, and metadata.
For information about real-time transcription during an active session, see Real-time Transcription. For calendar event synchronization with sessions, see Calendar Integration. For the database system that persists sessions, see Database System.
A session is the core data entity in Hyprnote. Each session captures:
Sessions are persisted in a local SQLite database (libsql) with optional cloud synchronization via Turso. The system uses a Tauri plugin architecture where Rust backend operations are exposed to the React frontend through type-safe TypeScript bindings.
Sources: crates/db-user/src/sessions_types.rs1-114 crates/db-user/src/sessions_ops.rs1-506
The Session struct is defined in crates/db-user/src/sessions_types.rs5-23 with the following key fields:
| Field | Type | Purpose |
|---|---|---|
id | String (UUID) | Unique session identifier |
created_at | DateTime | Session creation timestamp |
visited_at | DateTime | Last access timestamp for sorting |
user_id | String | Owner of the session |
calendar_event_id | Option | Optional link to calendar event |
title | String | Session title (user-editable) |
raw_memo_html | String | User-authored note content |
enhanced_memo_html | Option | AI-enhanced version of notes |
words | Vec | Transcribed words with timing |
record_start / record_end | Option<DateTime> | Recording time bounds |
pre_meeting_memo_html | Option | Context prepared before meeting |
Sources: crates/db-user/src/sessions_types.rs5-72 plugins/db/js/bindings.gen.ts459
Sessions are created via upsert_session() which performs an INSERT or UPDATE operation. The implementation at crates/db-user/src/sessions_ops.rs266-335 uses an ON CONFLICT(id) DO UPDATE SQL pattern to enable both creation and updates with a single operation.
New sessions are typically created:
The visit_session() function at crates/db-user/src/sessions_ops.rs98-107 updates the visited_at timestamp whenever a user accesses a session. This enables the "Recently Visited" filter to show sessions in chronological access order.
The cleanup_sessions() method at crates/db-user/src/sessions_ops.rs16-31 removes empty sessions where:
title is emptyraw_memo_html is emptyenhanced_memo_html is NULL or emptypre_meeting_memo_html is NULL or emptyconversations is empty arraySources: crates/db-user/src/sessions_ops.rs16-335 plugins/db/src/commands/sessions.rs77-90
All session commands follow a consistent pattern, as seen in plugins/db/src/commands/sessions.rs77-90:
The pattern involves:
ManagedState mutex to access databaseok_or(Error::NoneDatabase)The tauri-specta library generates TypeScript bindings at plugins/db/js/bindings.gen.ts58-265 These provide:
Sources: plugins/db/src/commands/sessions.rs1-266 plugins/db/js/bindings.gen.ts58-265 plugins/db/src/lib.rs22-80
The ListSessionFilter type at crates/db-user/src/sessions_types.rs85-113 provides flexible session querying:
| Filter Type | Implementation | Use Case |
|---|---|---|
| Search | Full-text search across title, memos, and participant data | User search box |
| Recently Visited | ORDER BY visited_at DESC | Default view showing recent sessions |
| Date Range | Filter by created_at or event start_date | Calendar view, date pickers |
| Tag Filter | JOIN with tags_sessions table | Filtered views by topic/category |
The search filter at crates/db-user/src/sessions_ops.rs129-157 searches multiple fields:
The query uses LIKE '%query%' pattern matching and returns DISTINCT results since participants are joined.
The date range filter at crates/db-user/src/sessions_ops.rs172-196 has special logic:
calendar_event_id IS NULL, filter by session's created_atcalendar_event_id IS NOT NULL, filter by joined event's start_dateSources: crates/db-user/src/sessions_types.rs85-113 crates/db-user/src/sessions_ops.rs119-243
Sessions maintain a many-to-many relationship with Human entities through the session_participants join table. Participants can be added, removed (soft-deleted), and listed.
Adding Participants crates/db-user/src/sessions_ops.rs357-370:
INSERT OR REPLACE to handle duplicate addsdeleted = FALSE to restore previously removed participantsRemoving Participants crates/db-user/src/sessions_ops.rs372-385:
UPDATE deleted = TRUEListing Participants crates/db-user/src/sessions_ops.rs387-408:
humans table to get full participant detailsdeleted = FALSE OR deleted IS NULLHuman objects with name, email, job title, etc.Sources: crates/db-user/src/sessions_ops.rs357-408 plugins/db/src/commands/sessions.rs185-245
Sessions can be linked to calendar events, creating a bidirectional relationship that enables automatic session creation from calendar notifications and context enrichment from meeting details.
Setting Association crates/db-user/src/sessions_ops.rs337-355:
calendar_event_id columnNone to unlink an eventRetrieving Linked Event crates/db-user/src/sessions_ops.rs410-432:
events and sessions tablesEvent object with calendar detailsNone if no event is linkedcalendar_event_id pre-populatedstart_dateis_recurring flag for repeated meetingsSources: crates/db-user/src/sessions_ops.rs337-432 plugins/db/src/commands/sessions.rs164-183
The system maintains two hardcoded special session IDs for onboarding and post-signup flows.
ID: df1d8c52-6d9d-4471-aff1-5dbd35899cbe
Defined at crates/db-user/src/sessions_ops.rs8-10:
The onboarding session is created during user initialization via init::onboarding() at crates/db-user/src/init.rs9-24:
plugins/db/seed/onboarding.json{{ CURRENT_USER_ID }} with actual user IDID: 872cf207-6a28-4229-bd66-492d0dce43c0
Defined at crates/db-user/src/sessions_ops.rs12-14:
The thank you session:
hypr_buffer::opinionated_md_to_html() at crates/db-user/src/seed.rs62Both special sessions are:
Sources: crates/db-user/src/sessions_ops.rs8-14 crates/db-user/src/init.rs9-24 crates/db-user/src/seed.rs55-65
Sessions store transcription data as a JSON-serialized array of Word2 objects in the database.
From plugins/db/js/bindings.gen.ts464:
Storage at crates/db-user/src/sessions_ops.rs324:
Vec<Word2> to JSON string via serde_json::to_string()words TEXT columnupsert_session() callRetrieval via get_words() at crates/db-user/src/sessions_ops.rs41-60:
The get_words_onboarding() function at crates/db-user/src/sessions_ops.rs33-39 returns hardcoded sample transcription:
hypr_data::english_7::WORDS_JSONWord2.speaker can be:
{ type: "unassigned", value: { index: 0 } } - Detected speaker but not identified{ type: "assigned", value: { id: "human-uuid", label: "John Doe" } } - Linked to Human entitySources: crates/db-user/src/sessions_ops.rs33-60 plugins/db/js/bindings.gen.ts460-464 plugins/db/src/commands/sessions.rs20-72
The session management system exposes 17 commands to the frontend through the DB plugin.
From plugins/db/build.rs7-22:
| Command | Purpose | Parameters | Return Type |
|---|---|---|---|
onboarding_session_id | Get special session ID | None | String |
thank_you_session_id | Get special session ID | None | String |
upsert_session | Create/update session | Session object | Session |
list_sessions | Query sessions | Optional filter | Session[] |
get_session | Retrieve by filter | GetSessionFilter | Session | null |
visit_session | Update visited_at | session_id | void |
delete_session | Remove session | session_id | void |
set_session_event | Link calendar event | session_id, event_id | void |
session_add_participant | Add participant | session_id, human_id | void |
session_remove_participant | Remove participant | session_id, human_id | void |
session_list_participants | Get participants | session_id | Human[] |
session_list_deleted_participant_ids | Get removed IDs | session_id | String[] |
session_get_event | Get linked event | session_id | Event | null |
get_words | Get transcription | session_id | Word2[] |
get_words_onboarding | Get demo words | None | Word2[] |
The DatabasePluginExt trait at plugins/db/src/ext.rs19-27 provides higher-level session operations:
These methods are used internally by other Tauri commands and plugins to interact with sessions without directly invoking frontend-facing commands.
All session commands require explicit permission grants defined in plugins/db/permissions/default.toml4-18 The default permission set includes all session operations, but applications can restrict individual commands through Tauri's capability system.
Sources: plugins/db/build.rs7-22 plugins/db/permissions/default.toml4-18 plugins/db/src/ext.rs19-27
Session schema is managed through versioned migrations in crates/db-user/src/lib.rs145-173 Relevant migrations:
| Migration | File | Changes |
|---|---|---|
| 5 | sessions_migration.sql | Initial sessions table |
| 6 | session_participants_migration.sql | Join table for participants |
| 14 | sessions_migration_1.sql | Schema update |
| 15 | sessions_migration_2.sql | Schema update |
| 16 | sessions_migration_3.sql | Schema update |
| 17 | sessions_migration_4.sql | Schema update |
| 20 | session_participants_migration_1.sql | Participant schema update |
The migration system at crates/db-user/src/lib.rs175-180:
Sources: crates/db-user/src/lib.rs145-180
Refresh this wiki
This wiki was recently refreshed. Please wait 7 days to refresh again.