5.1 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Commands
Build and run (Podman) — must run as root:
cp .env.example .env # first time only
sudo podman compose up -d --build
UI available at http://127.0.0.1:8094/ and https://voicelog.aquantico.lan (via Traefik).
Restart after code changes:
sudo podman rm -f diarization-ui
sudo podman compose up -d --build
Run locally without Podman:
pip install -r requirements.txt
API_BASE=http://... OLLAMA_BASE_URL=http://... DB_PATH=./ui.db uvicorn app:app --host 0.0.0.0 --port 8094 --reload
Publish container to registry:
podman build -t registry.aquantico.lan/claw/diarization-ui:latest .
podman push registry.aquantico.lan/claw/diarization-ui:latest
Logs:
sudo podman logs -f diarization-ui
There are no tests and no linter configured.
Important: This system uses
podman/sudo podman compose, notdocker. Always usesudofor podman compose commands — the container runs as root.
Documentation
Detailed docs live in doc/:
doc/architecture.md— data model, background jobs, DB schemadoc/api.md— all HTTP endpointsdoc/interfaces.md— Transcription-API and Ollama request/response detailsdoc/configuration.md— env vars and runtime settingsdoc/deployment.md— build, deploy, backup, Traefik setup
Keep doc/ up to date whenever routes, DB schema, settings keys, or external interfaces change.
Architecture
The entire application lives in a single file: app.py (~2000 lines). There are no templates, no separate frontend build, and no additional modules.
Request handling
All routes are FastAPI endpoints. HTML is returned as server-rendered Python f-strings using Bootstrap 5.3 (CDN) for layout. Inline <script> blocks handle client-side interactivity. The layout() function wraps every page with the sidebar navigation, topbar, shared CSS, and the global modal/JS helpers (window.showModal, window.uiPrompt, window.uiConfirm, window.uiSelect).
Data model (SQLite)
The DB is a single SQLite file at DB_PATH (default /data/ui.db). Five tables:
- projects — named groupings for documents
- prompts — reusable LLM prompt templates; each prompt can optionally override LLM parameters (
llm_use_default,llm_model,llm_think,llm_num_ctx,llm_num_predict,llm_repeat_penalty,llm_repeat_last_n) - documents — stored content;
kindis eithertranscript(raw transcription output) oranalysis(LLM result). An analysis document links back to its source viasource_document_idandprompt_id. - jobs — background task queue;
kindisuploadoranalysis;statuscycles throughqueued → running → done|error|cancelled. - settings — key/value store for runtime configuration (persists Ollama settings set via
/settingspage)
Schema migrations are handled inline in init_db() with ALTER TABLE … ADD COLUMN wrapped in try/except.
Background job processing
Jobs are processed by a ThreadPoolExecutor(max_workers=2). enqueue_job() inserts a row and submits the worker function. Workers check for cancelled status at each checkpoint before making external calls.
- upload job (
_process_upload_job): POSTs the audio/video file to{API_BASE}/transcribe-diarize, storesformatted_textfrom the response as atranscriptdocument. - analysis job (
_process_analysis_job): POSTs to Ollama's/api/generatewith the transcript content and selected prompt, stores the response as ananalysisdocument. LLM parameters are read from the prompt's own settings ifllm_use_default=0, otherwise from thesettingstable, falling back to env vars.
The jobs page auto-polls /jobs/data every 3 s when active jobs exist, 10 s otherwise.
LLM settings priority
Prompt-specific (llm_use_default=0) → prompts.llm_* columns
Global (llm_use_default=1, default) → settings table
Fallback → env vars (OLLAMA_MODEL, OLLAMA_THINK, …)
Runtime settings (settings table)
Configurable via /settings page: ollama_model, ollama_think, ollama_num_ctx (auto or fixed size), ollama_num_predict, ollama_repeat_penalty, ollama_repeat_last_n.
External dependencies
API_BASE— thetranscribe-diarizeservice; accepts audio and video files, returns JSON withformatted_textOLLAMA_BASE_URL— Ollama instance for LLM analysis; also queried atGET /api/tagsfor the model list (lazy-loaded on/settingsand/promptspages)
PWA
The app serves /manifest.webmanifest, /icon.svg, and /sw.js directly from route handlers to support installable PWA on mobile.
Deployment notes
- The active data volume is
diarization-ui_diarization_ui_data(mounted at/data). Never delete this volume. - There is also an older, unused volume
voicelog_diarization_ui_data(legacy name) — leave it alone. - Traefik network is
traefik(external). The app is exposed atvoicelog.aquantico.lanvia thewebsecureentrypoint with TLS. - Git remote:
https://gitea.aquantico.lan/claw/diarization-ui.git