teqo-backup/docs/plans/c170-corte-sem-limite.md

11 KiB
Raw Permalink Blame History

Acervo: cortar sem teto — do mínimo de 5 s até o fim da fala

Status: rascunho Atualizado em: 2026-09-15 Issue: #1046 Priority: P2 Impeccable: B — encaixe no player/detalhe do acervo Rascunho UI: docs/plans/c170-corte-sem-limite-ui-draft.html Appetite: ~0,5–1 dia eng; um outcome verificável — qualquer trecho de 5 s até o fim da fala corta, publica e baixa exatamente o intervalo escolhido Responsável: —

Intenção

O corte do acervo trava em 3 min (180 s). A assessoria precisa cortar trechos longos — um discurso inteiro, uma fala de vários minutos — e esbarra num teto que não é do material, é da ferramenta: acima de 3 min a barra de seleção não anda e o servidor recusa o corte, então o trecho longo sai por fora (baixar a sessão, editar em outra ferramenta). Esta fatia remove o teto de produto: o limite passa a ser a própria fala — do mínimo de 5 s até o fim — e o corte publicado/baixado corresponde exatamente ao trecho escolhido. Sem superfície nova, sem editor: é a mesma seleção do C166 e o mesmo corte do C167, sem teto.

Persona e fluxo

  • Persona / contexto: assessoria de comunicação (communicator; coordenação e candidatura também), na mesa ou em campo, montando peça com o discurso inteiro ou uma fala de vários minutos.
  • Job principal: selecionar e cortar o trecho exato que a peça precisa, inclusive um trecho longo, sem teto artificial de duração.
  • Fluxo desejado: abre a fala → "Selecionar trecho" → marca o início nas frases (ímã) e leva o fim até onde precisar — até o fim da fala; a barra não trava mais em 3 min e a duração aparece enquanto seleciona → "Compartilhar" (C166) ou "Cortar vídeo" (C167) → o corte publicado/baixado começa e termina nos marcos escolhidos, mesmo com 12 min ou a fala inteira.
  • Anti-goals de produto: não é editor de vídeo nem timeline com zoom; não muda o mínimo de 5 s; não mexe no mecanismo de corte nem no resolver (item irmão de pipeline, C169) nem na publicação/kill switch (C167/C168); não cria presets de duração nem seleção multi-trecho; não muda o gate do acervo nem o crédito CC BY.

Esboço de fluxo (B/C/D)

[detalhe da fala] → "Selecionar trecho" → [início nas frases] + [fim até onde precisar: ≥5s, até o fim da fala]
→ duração visível (ex.: 12min) → [Compartilhar (C166) | Cortar vídeo (C167)]
→ corte publicado/baixado = [início,fim] exatos (sem teto de 3 min)

Rascunho UI (B/C/D)

  • Rascunho UI (gate): docs/plans/c170-corte-sem-limite-ui-draft.html — cenas: detalhe com seleção longa (12 min) e o rótulo novo do limite; diálogo "Cortar vídeo" com a copy nova; variantes (até o fim da fala; fala inteira); mobile com seleção longa e diálogo.

Objetivo e aceite

  • Selecionar [início,fim] de 5 s até a duração total da fala: o fim alcança o último segundo da fala e o início, o primeiro; a barra não trava mais em 180 s.
  • O corte publicado/baixado corresponde exatamente ao trecho escolhido — começa e termina nos marcos escolhidos, inclusive trechos longos (12 min, fala inteira).
  • Robustez: um corte longo acima dos ~3 min atuais conclui — o arquivo toca e baixa; se o pipeline falhar por limite operacional (download do VOD, tempo do ffmpeg), falha honesta como hoje e nada é publicado (causa no item de pipeline, não vira teto de produto).
  • A copy diz a verdade: limite visível = "Mínimo 5s · sem limite — até o fim da fala"; a duração aparece durante a seleção.
  • Mínimo de 5 s mantido (decisão de produto: evita corte de 1 s sem uso). (assumido — validar no gate)
  • Guardrails: excerptTMs/seleção exata [início,fim] intocados; crédito "Fonte: Câmara dos Deputados · CC BY 4.0"; gate do acervo intocado (communicator/coordinator/candidate; advisor/leader negados fail-closed); kill switch/publicação do C167/C168 intocados; sem editor de vídeo; sem trocar início/fim depois de cortado.

Dados (intenção)

  • Vou apresentar dados? Não — a superfície é a barra de seleção e o diálogo de corte; duração/mm:ss é feedback de ação, não dado do acervo.
  • Decisões desbloqueadas: a assessoria decide cortar um trecho longo (discurso inteiro, fala de vários minutos) sem sair da ferramenta; a coordenação decide o que fica no ar (C168).
  • Forma: adiada ao plano de implementação — restrição: sem KPI/telemetria de corte nesta fatia.

Dados da decisão (literais)

  • Teto atual removido: MAX_EXCERPT_SECONDS = 180 (src/lib/speechExcerptSelection.ts:21), aplicado em normalizeExcerptRange (:54) e moveRangeEdge (:125,134).
  • Mínimo mantido: MIN_EXCERPT_SECONDS = 5 (src/lib/speechExcerptSelection.ts:44-53).
  • Limite efetivo: durationSeconds da fala — [início,fim] pode ir de 5 s até a duração total (fala inteira permitida).
  • Copy nova (exata):
    • Barra de seleção (SpeechExcerptControls.tsx:31): Mínimo 5s · máximo 3min → Mínimo 5s · sem limite — até o fim da fala; aria-valuemin/max (:114,119) passam a refletir 0–duração.
    • Diálogo de corte (SpeechCutDialog.tsx:242-244): dentro da faixa de 5–180 s → mínimo 5 s · até o fim da fala (linha vira <duração> · mínimo 5 s · até o fim da fala).
    • Mensagem de erro (src/lib/schemas/speechCut.ts:17): Selecione um trecho de 5 a 180 segundos. → Selecione um trecho de 5 segundos até o fim da fala.
    • Prompt da IA (src/utilities/speech/speechCutMetadata.ts:42): Receberá tipo, data, resumo oficial e a transcrição automática (ASR) de um trecho de 5 a 180 segundos. → Receberá tipo, data, resumo oficial e a transcrição automática (ASR) de um trecho da fala com 5 segundos ou mais.
  • Servidor: src/app/(campaign)/campanha/actions/speech.ts:133 (resolveExcerptRange, também usado na sugestão de IA em :338) — o guard de máximo passa a ser só a duração da fala; src/lib/schemas/speechCut.ts:16-17 — zod já limita 0–86.400 (excerptBoundarySeconds), o teto real é a action.
  • Testes que pinam 180 a atualizar: tests/unit/speechExcerptSelection.unit.spec.ts:41-42,113,130; tests/unit/speechDetailPlayer.unit.spec.tsx:290,306,321,444; tests/int/speechCut.int.spec.ts:300 (regex /5 a 180/).
  • Limites operacionais que um corte longo encosta (aceite de robustez, sem engenharia aqui): SOURCE_DOWNLOAD_TIMEOUT_MS=180_000, MAX_SOURCE_BYTES=2GiB, FFMPEG_MAX_TIMEOUT_MS=300_000, reaper SPEECH_CUT_STALE_MS=15min (src/utilities/speech/speechCutJob.ts:37-44); qualquer corte >~37,5 s já roda no teto de 5 min do ffmpeg.

Direção no codebase (hipótese)

  • Áreas prováveis: src/lib/speechExcerptSelection.ts (geometria/limites), src/components/campaign/speech/ (SpeechExcerptControls, SpeechCutDialog), src/app/(campaign)/campanha/actions/speech.ts + src/lib/schemas/speechCut.ts (validação/servidor), src/utilities/speech/speechCutMetadata.ts (prompt da IA).
  • Precedente a olhar: C166 (c166-compartilhar-trecho-link.md) e C167 (c167-cortar-trecho-publicar.md) — a barra e a validação nasceram com o teto; os testes acima são o mapa da mudança.
  • Risco de acoplamento: o teto está espalhado (geometria, aria, action, schema, prompt, testes) — remover só a UI deixaria o servidor recusando o corte longo; campaignSpeechAcervo (e2e) e as units de speechDetailPlayer/speechExcerptSelection cobrem o caminho.

Dependências

  • Nenhuma dura. Observação: C169 (defeito do resolver) toca o pipeline de corte — validar um corte longo real depende do pipeline funcionar; risco registrado, sem bloquear.

Fora de escopo

  • Mudar o mínimo de 5 s; editor/timeline/zoom/precisão de frame; segundo player/preview do corte.
  • Mecanismo de corte e resolver VOD (C169); publicação, kill switch e biblioteca (C167/C168).
  • Corte em partes/streaming/fila assíncrona; presets de duração; seleção multi-trecho; legenda no corte.
  • Ampliar papéis com acesso ao acervo; Consent/collection novas.

Rabbit holes de produto

  • "Sem teto = cortar 2 h de sessão de uma vez." Se alguém "só completar": ffmpeg em partes, fila, storage fragmentado. Corte neste item: o teto é a duração da fala; robustez mínima para um corte longo real concluir; infra de mídia não muda.
  • "Já que destravou, tira o mínimo também." Se alguém "só completar": cortes de 1 s, dezenas por fala, biblioteca poluída. Corte neste item: mínimo de 5 s permanece.
  • "Aproveitar e refazer a barra com zoom." Se alguém "só completar": timeline, precisão de frame, preview. Corte neste item: barra atual + ímã de frase, segundos inteiros.
  • "Preview do corte longo antes de publicar." Se alguém "só completar": render extra, segundo player. Corte neste item: o progresso honesto do C167 já basta.
  • "Aumentar timeouts para garantir o corte longo." Se alguém "só completar": mexer no pipeline às cegas. Corte neste item: se o pipeline não aguentar, é defeito do pipeline (C169) — não teto de produto.

Questões em aberto (produto)

  • O mínimo continua 5 s? Opções: A) manter | B) reduzir junto com o teto. Recomendação: A — 5 s evita corte de 1 s sem uso e não é o que a assessoria pediu. (assumido — validar no gate)
  • Texto do limite? Opções: A) Mínimo 5s · sem limite — até o fim da fala | B) só até o fim da fala. Recomendação: A — "sem limite" mata a memória do teto de 3 min e "até o fim da fala" diz qual é o teto real. (assumido)
  • Selecionar a fala inteira é permitido? Opções: A) sim, [00:00, duração] | B) exigir deixar algo de fora. Recomendação: A — o teto é a duração; a peça decide o recorte.
  • Corte longo que falha por limite operacional? Opções: A) tratar como defeito do pipeline (C169), com aceite de robustez aqui | B) reintroduzir teto técnico. Recomendação: A — teto de produto não se justifica por timeout; a falha honesta já existe (C167).

Referências

  • GitHub Issue: — (após pnpm agent:register)
  • Rascunho UI (gate): docs/plans/c170-corte-sem-limite-ui-draft.html
  • Planos irmãos: c166-compartilhar-trecho-link.md, c167-cortar-trecho-publicar.md
  • Arquivos-chave (pista, não contrato): src/lib/speechExcerptSelection.ts, src/components/campaign/speech/SpeechExcerptControls.tsx, src/components/campaign/speech/SpeechCutDialog.tsx, src/app/(campaign)/campanha/actions/speech.ts, src/lib/schemas/speechCut.ts, src/utilities/speech/speechCutMetadata.ts, src/utilities/speech/speechCutJob.ts
  • AGENTS.md — vertical Comunicação, gate do acervo e crédito CC BY.

Self-score (shaping)

5/5 — (1) fatia = um outcome verificável (selecionar de 5 s até o fim da fala e cortar exato) sem nova superfície; (2) appetite de ~0,5–1 dia para remover o teto nas pontas + robustez do corte longo, com os limites operacionais declarados; (3) persona, job e aceite em linguagem de produto, com a copy literal separada; (4) direção no codebase é hipótese (áreas, testes que pinam 180 e o risco C169); (5) zero decisão dura de engenharia — mecanismo, schema e infra ficam na implementação.