The Problem

Enterprises that record meetings need transcription and summarisation without sending audio or notes to third‑party clouds. Existing SaaS tools either expose raw data or require expensive licences, leaving a gap for a self‑hosted, privacy‑first solution that runs on macOS or Windows and can be integrated into internal pipelines.

What This Does

meetily bundles four self‑contained projects:

  • frontend – a Tauri desktop client (React + Tailwind) that captures audio, streams it to a local Whisper‑Parakeet engine, and displays live transcripts. Core Rust code lives in frontend/src-tauri/src/audio_* and UI logic in frontend/src/components/*.
  • backend – a FastAPI service (backend/app/main.py) exposing REST endpoints for transcript storage, speaker diarisation and Ollama summarisation. The service reads/writes a SQLite DB (backend/app/db.py) and serves static assets (backend/whisper-custom/server/public/index.html).
  • scripts – helper shells for Docker image builds, model downloads and DB initialisation.
  • llama-helper – a tiny Rust crate that wraps LLM inference for the summariser.

All processing stays on the host; no external API keys are required unless the user configures an LLM endpoint.

How It Is Wired

Execution starts in the desktop client at frontend/src-tauri/src/main.rsmain(). main launches the Tauri runtime and registers the audio/pipeline module. The pipeline entry start (frontend/src-tauri/src/audio/pipeline.rs:958) spawns a thread pool and calls start_streamscreateprocess_audio_datasend_audio_chunk. The last step performs a network POST to the local backend (client.post(stream_url)) and uploads the audio chunk.

On the backend, the FastAPI entry backend/app/main.py creates the app and includes the router defined in backend/app/transcript_processor.py. The router’s /transcribe endpoint receives the chunk, writes it to the DB (db.py), and forwards it to the Whisper server (backend/whisper-custom/server). Model discovery (discover_models) validates model files on disk (fs::File::open). Summarisation uses the LLM client in frontend/src-tauri/src/summary/llm_client.rs, which calls generate_summary – a thin wrapper around the local Ollama or any LLM binary.

The most fan‑in functions are spawn (44 callers) and pool (29 callers), indicating the thread‑pool infrastructure is the primary blast radius. The track_event function (20 callers) is the only place that writes analytics, so changes there affect telemetry across UI, audio handling and summarisation.

No circular imports were detected, but several modules have deep nesting (up to 8 levels) and duplicated shell snippets across the backend/*.sh scripts, which makes small changes ripple through many files.

How To Use It

# Clone the repo
git clone https://github.com/moses-y/meetily.git
cd meetily

# Build the backend container (Dockerfile pins python:3.11‑slim)
docker build -f backend/Dockerfile.app -t meetily-backend .

# Start the backend (environment file example)
cp backend/temp.env .env          # edit .env for DB path if needed
docker run -p 8000:8000 --env-file .env meetily-backend

# Install frontend dependencies
cd frontend
pnpm install                     # package.json defines pnpm usage
pnpm tauri dev                   # launches the Tauri desktop client

The backend expects the Whisper model files in backend/whisper-custom/models/ – the repository provides helper scripts (backend/download-ggml-model.sh) to fetch them. No additional API keys are required unless an external LLM endpoint is configured in frontend/src-tauri/src/summary/summary_engine/model_manager.rs.

Real‑World Use

A product team runs the Dockerised backend on a secure internal server. Each developer launches the Tauri client on their laptop, records a Zoom call, and receives a transcript and Ollama‑generated summary within minutes. All artefacts (audio, transcript, summary) are stored locally, satisfying GDPR‑style data‑sovereignty policies.

Code Health & Issues

  • HIGH – GitHub Actions reference tags instead of commit SHAs (.github/workflows/*). Pin to exact SHAs.
  • HIGH – No Cargo.lock; lock the Rust dependency graph.
  • HIGH – Backend FastAPI allows allow_origins=["*"] with credentials (backend/app/main.py). Replace wildcard with an explicit allow list.
  • MEDIUM – Dependabot not configured; add .github/dependabot.yml.
  • MEDIUM – Dockerfile uses mutable base tag (python:3.11-slim). Pin by digest.
  • MEDIUM – No dependency‑vulnerability scan in CI; add dependency-review-action or osv-scanner.
  • MEDIUM – Large GIF assets (docs/meetily-export.gif, meetily_demo.gif) exceed 5 MiB; move to Git LFS or external storage.
  • MEDIUM – Checkout step keeps token; set persist-credentials: false.
  • MEDIUM – Container runs as root; add a non‑root USER.
  • MEDIUM – Test coverage is minimal (1 test file vs 323 source files). Expand tests, starting with high‑fan‑in modules like frontend/src/components/ui/button.

No critical findings were reported.

The Bottom Line

meetily delivers a functional, fully local meeting‑note workflow with a clear separation between UI (Tauri/React) and backend (FastAPI + Rust inference). The codebase is usable but suffers from high cognitive load, duplicated scripts, and several security‑hardening gaps that should be addressed before production deployment. It is best suited for teams that can tolerate a modestly complex build process and are prepared to tighten the identified high‑severity issues.