# Meetily Database Schema for Meetings, Transcripts, and Summaries Explained

> Explore the Meetily database schema for storing meetings, transcripts, and summaries. Understand the five core tables used by the Zackriya-Solutions/meetily project.

- Repository: [Zackriya Solutions/meetily](https://github.com/Zackriya-Solutions/meetily)
- Tags: api-reference
- Published: 2026-08-01

---

**Meetily uses a SQLite database with five core tables—`meetings`, `transcripts`, `summary_processes`, `transcript_chunks`, and `settings`—to store meeting metadata, raw transcript segments, AI processing state, and LLM configuration.**

The schema is implemented in the Tauri-based Rust backend and managed through `sqlx`. It provides atomic storage for the entire meeting lifecycle, from initial transcription through chunked LLM processing to final summary generation.

## Schema Overview

The database schema for storing meetings, transcripts, and summaries in Meetily is defined in **[`frontend/src-tauri/migrations/20250916100000_initial_schema.sql`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/migrations/20250916100000_initial_schema.sql)**. All tables use **UUID-based TEXT primary keys** and declare foreign-key relationships that cascade deletions.

### Core Tables

| Table | Purpose | Key Relationship |
|-------|---------|----------------|
| **`meetings`** | Meeting container with title and timestamps | Root entity |
| **`transcripts`** | Individual transcript segments with optional AI highlights | `meeting_id` → `meetings.id` |
| **`summary_processes`** | Lifecycle tracking for summarization jobs | `meeting_id` → `meetings.id` |
| **`transcript_chunks`** | Chunked text fed to LLMs for processing | `meeting_id` → `meetings.id` |
| **`settings`** / **`transcript_settings`** | LLM provider and model configuration | Standalone |

## The `meetings` Table

This table represents a single meeting session.

```sql
-- From initial_schema.sql
CREATE TABLE meetings (
    id TEXT PRIMARY KEY,
    title TEXT NOT NULL,
    created_at TEXT NOT NULL,
    updated_at TEXT NOT NULL
);

```

The `id` is generated as a UUID. The `title` is typically derived from the meeting name or timestamp.

## The `transcripts` Table

Stores raw transcript segments produced by the Whisper speech-to-text engine.

```sql
CREATE TABLE transcripts (
    id TEXT PRIMARY KEY,
    meeting_id TEXT NOT NULL REFERENCES meetings(id) ON DELETE CASCADE,
    transcript TEXT NOT NULL,
    timestamp TEXT NOT NULL,
    summary TEXT,
    action_items TEXT,
    key_points TEXT
);

```

**Per-segment AI enrichment:** The optional columns `summary`, `action_items`, and `key_points` allow Meetily to store AI-generated highlights for individual transcript segments before full-meeting summarization.

### Saving Transcripts

In [`frontend/src-tauri/src/database/repositories/transcript.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/database/repositories/transcript.rs) (lines 10-78), the `TranscriptsRepository` handles persistence:

```rust
use crate::database::repositories::TranscriptsRepository;

// `transcripts` is a slice of `TranscriptSegment` from Whisper
let meeting_id = TranscriptsRepository::save_transcript(
    &db_pool,
    "Team Stand-up – 2024-08-01",
    &transcripts,
    Some("/path/to/meeting/folder".into()),
)
.await?;

```

Fetching transcripts for display uses a parameterized query:

```rust
let transcripts = sqlx::query_as::<_, Transcript>(
    "SELECT * FROM transcripts WHERE meeting_id = ?"
)
.bind(&meeting_id)
.fetch_all(&db_pool)
.await?;

```

## The `summary_processes` Table

Tracks the asynchronous lifecycle of meeting-wide summarization jobs.

```sql
CREATE TABLE summary_processes (
    meeting_id TEXT PRIMARY KEY REFERENCES meetings(id) ON DELETE CASCADE,
    status TEXT NOT NULL,  -- pending, processing, finished, error
    created_at TEXT NOT NULL,
    updated_at TEXT NOT NULL,
    error TEXT,
    result TEXT,
    start_time TEXT,
    end_time TEXT,
    chunk_count INTEGER,
    processing_time INTEGER,
    metadata TEXT
);

```

**State machine:** The `status` column drives the UI state, while `chunk_count`, `processing_time`, and `start_time`/`end_time` provide performance telemetry.

### Updating Process Status

The `ON CONFLICT` clause enables upsert semantics for idempotent status updates:

```rust
sqlx::query(
    "INSERT INTO summary_processes (meeting_id, status, created_at, updated_at)
     VALUES (?, ?, ?, ?)
     ON CONFLICT(meeting_id) DO UPDATE SET
        status = excluded.status,
        updated_at = excluded.updated_at"
)
.bind(&meeting_id)
.bind("processing")
.bind(chrono::Utc::now())
.bind(chrono::Utc::now())
.execute(&db_pool)
.await?;

```

## The `transcript_chunks` Table

Stores the chunked representation of full transcripts prepared for LLM ingestion.

```sql
CREATE TABLE transcript_chunks (
    meeting_id TEXT PRIMARY KEY REFERENCES meetings(id) ON DELETE CASCADE,
    meeting_name TEXT,
    transcript_text TEXT NOT NULL,
    model TEXT,
    model_name TEXT,
    chunk_size INTEGER,
    overlap INTEGER,
    created_at TEXT NOT NULL
);

```

The `chunk_size` and `overlap` columns record the tokenization strategy used, enabling reproducibility and A/B testing of different chunking approaches.

## Configuration Tables

### `settings`

Global application configuration for LLM providers and Whisper settings.

```sql
CREATE TABLE settings (
    id TEXT PRIMARY KEY,
    provider TEXT,
    model TEXT,
    whisperModel TEXT,
    -- API key fields omitted for security
    created_at TEXT,
    updated_at TEXT
);

```

### `transcript_settings`

Per-user or per-session transcription configuration with provider-specific overrides.

## Foreign Key Cascade Behavior

All child tables declare `ON DELETE CASCADE`:

- Deleting a `meetings` row automatically removes associated `transcripts`, `summary_processes`, and `transcript_chunks`
- This ensures referential integrity without application-level cleanup logic

## Key Implementation Files

| File | Responsibility |
|------|---------------|
| [`frontend/src-tauri/migrations/20250916100000_initial_schema.sql`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/migrations/20250916100000_initial_schema.sql) | DDL for all tables |
| [`frontend/src-tauri/src/database/repositories/transcript.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/database/repositories/transcript.rs) | Transcript CRUD and meeting creation |
| [`frontend/src-tauri/src/database/repositories/meeting.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/database/repositories/meeting.rs) | Meeting queries with transcript pagination |
| [`frontend/src-tauri/src/summary/processor.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/summary/processor.rs) | `summary_processes` and `transcript_chunks` management |

## Summary

- The database schema for storing meetings, transcripts, and summaries in Meetily centers on **SQLite with five interconnected tables**
- **`meetings`** is the root entity; all other tables cascade on deletion
- **`transcripts`** stores Whisper output with optional per-segment AI metadata
- **`summary_processes`** provides job-state tracking with performance metrics
- **`transcript_chunks`** preserves the chunked input to LLMs for debugging
- All persistence uses **`sqlx`** with compile-time checked queries in the Tauri Rust backend

## Frequently Asked Questions

### What database does Meetily use for meeting data?

Meetily uses **SQLite** accessed through the `sqlx` Rust crate. The database file is managed by the Tauri backend in `frontend/src-tauri/`.

### How does Meetily handle transcript chunking for LLM processing?

The `transcript_chunks` table stores the preprocessed, chunked transcript text along with parameters (`chunk_size`, `overlap`, `model_name`) used for the splitting strategy. This enables reproducibility and debugging of chunking decisions.

### Can transcripts be deleted independently of meetings?

No. The schema declares `ON DELETE CASCADE` on `meeting_id` foreign keys. Deleting a meeting automatically removes its transcripts, summary processes, and transcript chunks.

### Where is the AI summary status tracked?

The `summary_processes` table tracks the full lifecycle—`pending`, `processing`, `finished`, or `error`—with timing metrics and error messages. This table is updated by [`frontend/src-tauri/src/summary/processor.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/summary/processor.rs).