docs: update README with auth, campaigns, and CI/CD changes
All checks were successful
Build and Push / build (push) Successful in 1m17s

This commit is contained in:
KansaiGaijin
2026-07-30 16:09:54 +12:00
parent cef9178d8d
commit f7eeae8469

View File

@@ -21,22 +21,30 @@ cd nat20-notes
docker compose up -d --build
```
Then open `http://<your-server>:8020` (yes, that port reads "a d20") and follow the setup wizard:
Open `http://<your-server>:8020` (d20 nod) and **log in** with the default
admin credentials (`admin` / `admin`, overridable via `NAT20_ADMIN_USERNAME`
and `NAT20_ADMIN_PASSWORD`). The first user is created automatically on
first startup — no separate registration step.
Then follow the setup wizard:
1. Choose a Whisper model size based on your GPU's available VRAM (guidance shown in-app)
2. Choose local Ollama or a hosted API for summarization, and paste your HF token
3. Optionally paste campaign/world context (NPC names, places) so summaries recognize them correctly
2. Give your campaign a name
3. Choose local Ollama or a hosted API for summarization, and paste your HF token
4. Optionally paste campaign/world context (NPC names, places) so summaries recognise them correctly
A reference compose file using named volumes only (no host paths) is at
[`docker-compose.example.yml`](./docker-compose.example.yml).
## Using it
1. **Upload** a recording (audio or video — video is auto-converted, audio-only files skip that step and are much faster). Files over **90 MB** are auto-chunked with 3-way concurrent uploads.
2. **Transcribe** — runs in the background. On completion you're **automatically taken** to the speaker-naming screen.
3. **Name your speakers** — a waveform-style "session reel" shows each detected speaker's segments; click any point to jump the audio there and hear who's talking, then type in their name. Use the checkboxes to **merge** speakers (e.g. when diarization over-splits one person into `SPEAKER_00`, `SPEAKER_05`, etc.).
4. **Generate notes** — click "Done naming" and confirm; notes generation starts automatically and you're taken to the job progress screen. When finished, navigate to the notes viewer.
5. **Review & tweak** — regenerate notes, rename speakers, or delete jobs/sessions from the session detail page.
1. **Log in** with your username and password. Admins can create additional users at `/users`.
2. **Select a campaign** from the sidebar (or use the default). Each campaign has its own settings, sessions, and player recaps.
3. **Upload** a recording (audio or video — video is auto-converted, audio-only files skip that step and are much faster). Files over **90 MB** are auto-chunked with 3-way concurrent uploads.
4. **Transcribe** — runs in the background. On completion you're **automatically taken** to the speaker-naming screen.
5. **Name your speakers** — a waveform-style "session reel" shows each detected speaker's segments; click any point to jump the audio there and hear who's talking, then type in their name. Use the checkboxes to **merge** speakers (e.g. when diarization over-splits one person into `SPEAKER_00`, `SPEAKER_05`, etc.).
6. **Generate notes** — click "Done naming" and confirm; notes generation starts automatically and you're taken to the job progress screen. When finished, navigate to the notes viewer.
7. **Review & tweak** — regenerate notes, rename speakers, or delete jobs/sessions from the session detail page.
## Data layout
@@ -47,7 +55,7 @@ The app stores everything under `/data` (inside the container):
| `campaigns/{id}/audio/` | Uploaded recordings and extracted audio, organised per campaign |
| `campaigns/{id}/transcriptions/` | Per-session transcript JSON files |
| `campaigns/{id}/notes/` | Generated notes (GM log + player recap) |
| `app.db` | SQLite database (sessions, speakers, campaigns, settings, jobs) |
| `app.db` | SQLite database (users, campaigns, campaign_shares, sessions, speakers, campaign/global settings, jobs) |
## Configuration
@@ -85,12 +93,37 @@ and Settings page can set them at runtime.
| `NAT20_PLAYER_RECAP_STYLE` | Player recap format | `story` `diary` `bullets` `custom` | `story` | |
| `NAT20_PLAYER_RECAP_CUSTOM_PROMPT` | Custom prompt (only when style is `custom`) | text | (none) | |
#### Auth
| Variable | What it does | Values | Default | Notes |
|---|---|---|---|---|
| `NAT20_ADMIN_USERNAME` | Admin username | string | `admin` | Created on first startup if no users exist |
| `NAT20_ADMIN_PASSWORD` | Admin password | string | `admin` | |
| `NAT20_JWT_SECRET` | JWT signing key | string | (random) | Set to a fixed value so tokens survive restarts |
#### Setup wizard
| Variable | What it does | Values | Default | Notes |
|---|---|---|---|---|
| `NAT20_ONBOARDING_COMPLETED` | Skip the setup wizard | `true` or `false` | `false` | Set to `"true"` after you finish the wizard once |
### Campaigns
Campaigns organise sessions, settings, and context into separate silos.
On first run a **default** campaign is created automatically; you can
name it during the setup wizard and rename it later in Settings.
Key features:
- **Per-campaign settings** — each campaign has its own Whisper model,
LLM config, world context, and player recap style. Switch campaigns
in the sidebar to change which settings apply to new sessions.
- **Sharing** — the admin can share a campaign with other registered users
from the campaign's detail page. Shared users can upload sessions and
generate notes within that campaign.
- **User management** — admins can create additional users via the Users
page (`/users`). Every user authenticates with the same login form.
### Campaign context
You can paste context directly in the Settings page, or point to a file
@@ -108,7 +141,16 @@ system overhead from other GPU-using services).
## Architecture
- `backend/` — FastAPI, SQLite (no external DB needed), WhisperX as a library (no nested Docker), in-process `ThreadPoolExecutor` background jobs (no Redis/Celery)
- `frontend/` — React 18 + Vite + Tailwind, served via nginx (listens on port **8020**) which proxies `/api` to the backend
- `backend/` — FastAPI, SQLite (no external DB needed), WhisperX as a library (no nested Docker), in-process `ThreadPoolExecutor` background jobs (no Redis/Celery). JWT auth with HMAC-SHA256 tokens, scrypt password hashing.
- `frontend/` — React 18 + Vite + Tailwind, served via nginx (listens on port **8020**) which proxies `/api` to the backend. Auth state managed via React context; global fetch interceptor adds `Authorization: Bearer` to all API calls.
### CI/CD
The backend is split into two Docker images for fast rebuilds:
| Image | Build time | Contents |
|---|---|---|
| `whisperx-base` (`.deps`) | 5-10 min, only when `requirements.txt` changes | PyTorch 2.3.1 + cu121, WhisperX, ctranslate2, ffmpeg |
| `backend` (thin) | ~10 seconds | App code only (`FROM whisperx-base`) |
Both run as standard Docker Compose services — no special orchestration needed beyond GPU passthrough for the backend.