Refactor user config validation and add transcript display

Introduces a dedicated function `validate_and_index_users` to
encapsulate the logic for validating user configurations, checking for
duplicate slugs and API keys. This function returns a `Result` to handle
errors gracefully, and its usage in `load_users` is updated to panic
with a more informative error message.

Additionally, this commit modifies the web routing to fetch and display
audio transcripts. When scanning recordings, it now attempts to read a
corresponding `.transcript.txt` file. If found, the transcript content
is included in the `RecordingView` and rendered in the `cases.html`
template. If the transcript file is not found, a "Transcription pending"
message is displayed.

The `transcribe` function in `whisper.rs` is updated to explicitly set
the language to German (`language=de`), which can improve transcription
accuracy by skipping language detection. The `encode=false` query
parameter has been removed, as the service is designed to handle encoded
audio.

Finally, tests have been added for the new `validate_and_index_users`
function to ensure duplicate slugs and API keys are correctly rejected.
Integration tests in `web_test.rs` have been updated to verify the
rendering of transcripts and the pending status.
This commit is contained in:
2026-04-13 17:08:21 +02:00
parent 13375b8297
commit 1e3cc9574c
6 changed files with 93 additions and 13 deletions
+5 -3
View File
@@ -27,8 +27,10 @@ impl std::error::Error for WhisperError {}
/// POST the audio file to whisper-asr-webservice and return the transcript text.
///
/// Uses `output=txt` for a plain-text response and `encode=false` to skip
/// whisper's internal ffmpeg pass — we remux ourselves upstream.
/// `output=txt` plain-text response. `language=de` pins German so the model
/// skips language detection. We send AAC-in-mp4 and let the service decode it
/// internally (the default `encode=true`) — passing `encode=false` would tell
/// the service "this is already raw PCM", which ours isn't.
pub async fn transcribe(
client: &reqwest::Client,
whisper_url: &str,
@@ -48,7 +50,7 @@ pub async fn transcribe(
.map_err(WhisperError::Http)?;
let form = Form::new().part("audio_file", part);
let url = format!("{}/asr?output=txt&encode=false", whisper_url.trim_end_matches('/'));
let url = format!("{}/asr?output=txt&language=de", whisper_url.trim_end_matches('/'));
debug!(%url, "posting to whisper");
let response = client