wip: snapshot das alterações não commitadas (2026-10-20)

Origem: D:/Documents/Github/transcript
Arquivos omitidos (segredos, bancos de dados, logs, >50 MB): 2
This commit is contained in:
evandrodevbr committed 2026-10-20 00:50:17 -03:00
1 parent 92c214254e
commit 06aaeeaf79
123 files changed
+20537 -982

No files matched your search

@@ -0,0 +1,44 @@
# Áudio persistente, fallback local e streaming — Design
## Objetivo
Guardar os 10 áudios mais recentes enviados à transcrição, permitir salvar qualquer um deles em um local escolhido pelo usuário, usar Whisper local em PT-BR quando a API falhar e inserir texto progressivamente quando a API responder em streaming.
## Escopo e decisões
### Histórico de áudio
- Cada gravação finalizada permanece no diretório de dados do aplicativo como WAV.
- O histórico é limitado a 10 arquivos, ordenados por data de modificação decrescente. Ao finalizar uma gravação, arquivos mais antigos são removidos.
- Cada item expõe somente `id` (nome de arquivo validado), nome, tamanho e data. Caminhos absolutos nunca são enviados ao frontend.
- O frontend mostra um `<details>` compacto de “Áudios recentes”, com “Baixar último áudio” e ações de salvar por item.
- O salvamento usa o diálogo nativo de arquivo e copia o WAV para a localização escolhida. Cancelar o diálogo não é erro.
### Fallback API → Whisper
- O modo de servidor tenta a API configurada primeiro.
- Qualquer falha antes de texto parcial aciona Whisper embarcado com idioma fixo `pt`.
- Se uma resposta streaming já tiver emitido texto parcial, não há fallback automático: repetir o texto poderia duplicar o que já foi inserido no campo ativo. O erro é mostrado para revisão.
- O modo local continua usando Whisper primeiro e API como fallback, preservando o comportamento existente.
### Streaming de resposta
- O cliente envia `Accept: text/event-stream, application/x-ndjson, application/json`.
- A API é detectada como streaming exclusivamente pelo `Content-Type` da resposta: `text/event-stream` ou `application/x-ndjson`.
- Eventos SSE/NDJSON aceitam `delta`, `text`, `transcript`, `result`, `output`, `data` e `choices[0].delta.content`; payloads cumulativos são convertidos em somente o sufixo novo.
- Na janela principal, cada fragmento atualiza o editor de transcrição.
- No atalho global, o primeiro fragmento esconde a barra não focável e tenta colar imediatamente no campo externo ativo; a transcrição final não é colada uma segunda vez.
- Respostas JSON normais mantêm o fluxo atual: texto completo somente após concluir.
## Segurança e limites
- IDs de áudio são nomes simples de WAV; separadores de diretório, extensões diferentes e caminhos fora do diretório de gravações são rejeitados.
- O backend nunca recebe um destino de arquivo escolhido pelo frontend; o diálogo nativo escolhe o destino e o backend executa a cópia local.
- Áudio é dado potencialmente sensível. A retenção fixa em 10 arquivos é deliberada e visível na UI; não há telemetria nem upload adicional.
## Testes
- Histórico: limita a 10, remove o mais antigo, rejeita IDs inseguros.
- Fallback: API-only usa Whisper PT-BR quando não houve parcial; streaming parcial não dispara fallback.
- Streaming: detecta Content-Type, extrai deltas/cumulativos e evita duplicação.
- Frontend: renderiza histórico e pede download do item selecionado.