Files
diarization-ui/CLAUDE.md

100 lines
5.1 KiB
Markdown
Raw Normal View History

# 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:**
```bash
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:**
```bash
sudo podman rm -f diarization-ui
sudo podman compose up -d --build
```
**Run locally without Podman:**
```bash
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:**
```bash
podman build -t registry.aquantico.lan/claw/diarization-ui:latest .
podman push registry.aquantico.lan/claw/diarization-ui:latest
```
**Logs:**
```bash
sudo podman logs -f diarization-ui
```
There are no tests and no linter configured.
> **Important:** This system uses `podman` / `sudo podman compose`, not `docker`. Always use `sudo` for podman compose commands — the container runs as root.
## Documentation
Detailed docs live in `doc/`:
- `doc/architecture.md` — data model, background jobs, DB schema
- `doc/api.md` — all HTTP endpoints
- `doc/interfaces.md` — Transcription-API and Ollama request/response details
- `doc/configuration.md` — env vars and runtime settings
- `doc/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; `kind` is either `transcript` (raw transcription output) or `analysis` (LLM result). An analysis document links back to its source via `source_document_id` and `prompt_id`.
- **jobs** — background task queue; `kind` is `upload` or `analysis`; `status` cycles through `queued → running → done|error|cancelled`.
- **settings** — key/value store for runtime configuration (persists Ollama settings set via `/settings` page)
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`, stores `formatted_text` from the response as a `transcript` document.
- **analysis job** (`_process_analysis_job`): POSTs to Ollama's `/api/generate` with the transcript content and selected prompt, stores the response as an `analysis` document. LLM parameters are read from the prompt's own settings if `llm_use_default=0`, otherwise from the `settings` table, 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`** — the `transcribe-diarize` service; accepts audio and video files, returns JSON with `formatted_text`
- **`OLLAMA_BASE_URL`** — Ollama instance for LLM analysis; also queried at `GET /api/tags` for the model list (lazy-loaded on `/settings` and `/prompts` pages)
### 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 at `voicelog.aquantico.lan` via the `websecure` entrypoint with TLS.
- Git remote: `https://gitea.aquantico.lan/claw/diarization-ui.git`