docs: update README with auth, campaigns, and CI/CD changes
All checks were successful
Build and Push / build (push) Successful in 1m17s
All checks were successful
Build and Push / build (push) Successful in 1m17s
This commit is contained in:
64
README.md
64
README.md
@@ -21,22 +21,30 @@ cd nat20-notes
|
|||||||
docker compose up -d --build
|
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)
|
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
|
2. Give your campaign a name
|
||||||
3. Optionally paste campaign/world context (NPC names, places) so summaries recognize them correctly
|
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
|
A reference compose file using named volumes only (no host paths) is at
|
||||||
[`docker-compose.example.yml`](./docker-compose.example.yml).
|
[`docker-compose.example.yml`](./docker-compose.example.yml).
|
||||||
|
|
||||||
## Using it
|
## 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.
|
1. **Log in** with your username and password. Admins can create additional users at `/users`.
|
||||||
2. **Transcribe** — runs in the background. On completion you're **automatically taken** to the speaker-naming screen.
|
2. **Select a campaign** from the sidebar (or use the default). Each campaign has its own settings, sessions, and player recaps.
|
||||||
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.).
|
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. **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.
|
4. **Transcribe** — runs in the background. On completion you're **automatically taken** to the speaker-naming screen.
|
||||||
5. **Review & tweak** — regenerate notes, rename speakers, or delete jobs/sessions from the session detail page.
|
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
|
## 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}/audio/` | Uploaded recordings and extracted audio, organised per campaign |
|
||||||
| `campaigns/{id}/transcriptions/` | Per-session transcript JSON files |
|
| `campaigns/{id}/transcriptions/` | Per-session transcript JSON files |
|
||||||
| `campaigns/{id}/notes/` | Generated notes (GM log + player recap) |
|
| `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
|
## 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_STYLE` | Player recap format | `story` `diary` `bullets` `custom` | `story` | |
|
||||||
| `NAT20_PLAYER_RECAP_CUSTOM_PROMPT` | Custom prompt (only when style is `custom`) | text | (none) | |
|
| `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
|
#### Setup wizard
|
||||||
|
|
||||||
| Variable | What it does | Values | Default | Notes |
|
| 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 |
|
| `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
|
### Campaign context
|
||||||
|
|
||||||
You can paste context directly in the Settings page, or point to a file
|
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
|
## Architecture
|
||||||
|
|
||||||
- `backend/` — FastAPI, SQLite (no external DB needed), WhisperX as a library (no nested Docker), in-process `ThreadPoolExecutor` background jobs (no Redis/Celery)
|
- `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
|
- `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.
|
Both run as standard Docker Compose services — no special orchestration needed beyond GPU passthrough for the backend.
|
||||||
|
|||||||
Reference in New Issue
Block a user