Commit graph

412 commits

Author SHA1 Message Date
Francisco Solla
63bd370b6c feat(C222): apagar uma peça na Central de Conteúdos (Closes #1330)
Hard delete por peça (sem lixeira/lote/telemetria) em qualquer estado, com confirmação que nomeia o link público só quando publicado; access próprio da vertical + admin (advisor/leader fail-closed), cascata da mídia pós-commit e bust da tag contentPieces no afterDelete; máquina do diálogo extraída no 3º call site (C183/C199/C222).
2026-09-24 23:49:28 -03:00
Francisco Solla
c9ab467f23 feat(C217): cortes e links compartilhaveis na fonte "Falas na internet" (Closes #1293) 2026-09-24 20:17:54 -03:00
Francisco Solla
b119d203aa feat(S37): liderancas que aparecem nas pecas na Central de Conteudos (Closes #1303)
Some checks are pending
Deploy / preflight (push) Waiting to run
Deploy / verify (push) Blocked by required conditions
Deploy / deploy staging (teqo-staging) (push) Blocked by required conditions
Deploy / requeue when main advanced (push) Blocked by required conditions
Deploy / deploy production (teqo-1313) (push) Blocked by required conditions
2026-09-24 17:40:57 -03:00
Francisco Solla
d0063d39f3 refactor(C216): aplica achados do simplify (Related #1292) 2026-09-24 17:01:42 -03:00
Francisco Solla
425361d278 feat(C216): terceira fonte do acervo — falas na internet (Closes #1292) 2026-09-24 17:01:42 -03:00
Francisco Solla
13b5a3c1d1 feat(S38): alterna peças e cards no board e certifica o design (Closes #1304) 2026-09-24 16:57:03 -03:00
Francisco Solla
e7055ae33d refactor(S38): reusa o label do dono, fidelidade ao artefato e simplifica o filtro (Related #1304) 2026-09-24 16:57:03 -03:00
Francisco Solla
bf2c7a25c4 feat(S38): cards personalizáveis como itens do catálogo (Closes #1304) 2026-09-24 16:57:03 -03:00
Francisco Solla
02ca466469 feat(S40): arte genérica do Time do estadual e janela vazia sem silhueta (Closes #1316) 2026-09-24 16:23:44 -03:00
Francisco Solla
11de48f726 feat(S39): seção da Central de Conteúdos na home (Closes #1305) 2026-09-24 14:53:36 -03:00
Francisco Solla
38e6742673 feat(C219): paridade de busca e filtros nas gravações do acervo (Closes #1295)
Some checks are pending
Deploy / preflight (push) Waiting to run
Deploy / verify (push) Blocked by required conditions
Deploy / deploy staging (teqo-staging) (push) Blocked by required conditions
Deploy / requeue when main advanced (push) Blocked by required conditions
Deploy / deploy production (teqo-1313) (push) Blocked by required conditions
Classificação automática com proveniência (job + CLI recordings:classify), facetas ano/tema/alcance/município/duração na URL canônica, busca por tema no corpus próprio, ordenação e a barra de filtros portada do design aprovado sobre os shells compartilhados. Deep-links existentes byte-idênticos; Câmara intocada.
2026-09-24 04:00:06 -03:00
Francisco Solla
8f3118312a fix(C220): link do proprio Instagram baixa e cataloga a peca (Closes #1302) 2026-09-24 03:51:17 -03:00
Francisco Solla
8318fb5fce feat(C215): ingestão de falas da internet no acervo — origem web, espelho privado e catálogo (Closes #1291) 2026-09-24 03:26:10 -03:00
Francisco Solla
2c8b38f2be feat(S34): colinha usa a arte exata com a linha do estadual preenchida (Closes #1298) 2026-09-24 02:20:44 -03:00
Francisco Solla
9069d23d88 feat(S33): ajuste da foto do card do time sem limite (Closes #1297) 2026-09-24 01:38:06 -03:00
Francisco Solla
e8a190005a feat(S32): contadores anônimos de download dos cards na home staff (Closes #1273) 2026-09-23 18:12:42 -03:00
Francisco Solla
8d81883509 feat(S28): busca por tema na Central de Conteúdos pública 2026-09-23 15:35:21 -03:00
Francisco Solla
f47c2645ac feat(C213): contadores anônimos de circulação por peça na Central de Conteúdos (Closes #1258)
Collection contentEvent (hidden, sem hooks, sem PII) + beacon público
POST /api/content-events fail-soft, download contado no servidor na rota
de mídia, agregação em uma query group-by e a coluna "Circulação" na lista
interna + painel na ficha (port classe-a-classe do artefato estendido,
crítica final do designer certificada).
2026-09-23 15:29:43 -03:00
Francisco Solla
48a01de58b fix(S29-FOLLOWUP): .ics do link de anúncio e feed — folding RFC 5545 (75 octets) no owner ical.ts (Closes #1281) 2026-09-23 14:16:25 -03:00
Francisco Solla
2a0dca6243 fix(S29): achados da review — snapshot pós-rebase, manifest e2e e a11y do anúncio
- snapshot drizzle da migration regenerado pós-rebase (inclui as tabelas do
  S27; sem ele o próximo migrate:create recriaria content_piece)
- manifest e2e: CampaignFooter/jingleReads/campaignTime acordam o
  frontendShareLink; dynamicParams inerte removido da rota .ics
- anúncio: dl válido (Local sem dd), aria-live só no status/chip, sem
  hasImage/cast; hook direct deixa o erro de URL falar antes (+ teste int)
- débitos triados no impl plan (folding .ics -> #1281; deferidos com gatilho)

Related #1268
2026-09-23 12:37:00 -03:00
Francisco Solla
b0bac78090 feat(S31): colinha de voto — 6º modelo com o estadual escolhido (Closes #1272) 2026-09-23 12:33:04 -03:00
Francisco Solla
b8051bb7e0 feat(S29): link com destino trocável e página de anúncio da atividade
- shareLink ganha modo (direct|announcement), pool de destinos com "Destino no
  ar" por linha e dados do evento; destination escalar sai via migration com
  backfill lossless (legado vira direct com destino no ar)
- página de anúncio pública portada classe-a-classe, header campaign-site
  extraído (CampaignPageHeader) e ativação/troca sem reload por poll da rota
  /api/share-link/<slug>/live (fail-closed, no-store)
- agenda Google (action=TEMPLATE) + .ics por rota sob o slug; compartilhar o
  link curto (kind event); S19 intacto e 404 uniforme preservado

Related #1268
2026-09-23 11:48:12 -03:00
Francisco Solla
dda55adc27 feat(S27): Central de Conteúdos pública — Peça voto pra Solla 1313
/conteudos + /conteudos/<slug>: catálogo filtrável (Tipo · Cidade · Região ·
Tema · Instituição + termo na URL canônica), play sob demanda (Vídeo/Áudio só
carregam no toque; Foto com preview leve), Baixar e Compartilhar do próprio
card com a mensagem de voto por tipo (wa.me sem destinatário, editável; "A
mídia" usa a folha nativa e cai em download onde o aparelho não suportar) e o
card personalizado como peça sintética do catálogo → /cards.

- leitura pública nova (contentPieceReads) cacheada na tag contentPieces com o
  gate where status=publicado + contentPieceIsPublic; a rota GET
  /conteudos/<slug>/midia reusa buildPrivateMediaResponse (range, disposition,
  private no-store, 404 uniforme) com download jorge-solla-1313-<slug>.<ext> e
  a allowlist inline do dono estendida (webp/gif/avif + áudios das peças)
- contrato público puro do catálogo (filtros/VM/download) + mensagens de voto
  (contentPieceShare); OG com fallback do global; conteudos entra nos slugs
  reservados; kill switch por peça vale na hora (lista, página, rodapé/selo);
  descoberta condicional no CampaignFooter e no header local
- UI portada classe-a-classe do design aprovado (cenas 01–08, com as cenas
  06–08 estendidas no trigger a); sem migration, sem Consent e sem access novo;
  contentMedia segue privada (sem segunda cópia de mídia)
- testes: 2 unit specs novos, 18 casos int (leitura pública + rota de mídia) e
  e2e frontendConteudos (5 casos); manifest e curado atualizados
- follow-up de engenharia: #1276 (docs/plans/escala-dry-pos-s27.md)

Closes #1255
2026-09-23 11:13:57 -03:00
Francisco Solla
e72bfe8f8f fix(S30): TeamCardSubject é tipo interno do renderer 2026-09-23 10:06:17 -03:00
Francisco Solla
6480768926 feat(S30): card Time do estadual — 5º modelo com as 53 dobradinhas (Closes #1271) 2026-09-23 10:06:17 -03:00
Francisco Solla
cb61cf1152 feat(C211): Central de Conteúdos interna — envio em lote, link, catalogação e publicação
Envio em lote (1 request raw-body por arquivo, fan-out ≤2, até 50 arquivos) e
adicionar por link (Instagram/YouTube; extração só pela Graph API da conta
própria, senão peça-link) em /campanha/comunicacao/conteudos. Cada peça tem
estado próprio (Processando/Pronto/Falhou + Reprocessar), transcrição/texto e
catalogação automática revisável; publicar/despublicar preserva arquivo, slug
e publishedAt.

- collections contentPiece + contentMedia (upload privado no S3) e migration
  20260923_032714_add_content_piece (slug único gerado no 1º publish,
  sourceUrl única, searchText com índice trigram)
- pipeline reusa C199 (job after() + reaper + retry condicional, transcrição
  DeepInfra, ffmpeg/chunk), o classificador de facetas do acervo e o
  institutionCatalog; curatedFields impede o job de sobrescrever curadoria
- gate único canReadCommunicationCatalog (advisor/leader negados); delete
  só pelo admin; sem Consent novo
- UI portada do design aprovado (lista desktop + cards mobile, diálogo de
  lote com progresso por arquivo, diálogo de link, ficha editável, kill
  switch); nav/chrome/column-picker/manifest atualizados
- instagramFeed expõe mediaUrl; revalidateTag ganha wrapper seguro fora de
  request (fixtures/scripts)
- testes: 2 unit specs, 1 int spec (16 casos) e 7 e2e na vertical
- follow-up de engenharia: #1267 (docs/plans/escala-dry-pos-c211.md)

Closes #1254
2026-09-23 02:25:15 -03:00
Francisco Solla
bb550cebff feat(S25): player próprio da Rádio 1313 na home — exclusividade, share e fail-soft (Closes #1239) 2026-09-21 13:39:42 -03:00
Francisco Solla
8a5e271f6d feat(S26): título completo e crédito do artista no card do jingle (Closes #1240) 2026-09-21 12:50:17 -03:00
Francisco Solla
48e08bf7f5 fix(cards): recorte no celular (WASM/WebGL) e volta do enquadramento S15
O recorte do card 'Time de você' falhava em navegadores endurecidos (IronFox/Tor
desligam WebAssembly e WebGL por padrão) com a copy errada de 'tente outra foto';
o motor MediaPipe exige ambos (o grafo pede kGpuService mesmo com delegate CPU).
Agora o adapter sonda WASM/WebGL antes do download e devolve 'unsupported' com
mensagem acionável; a entrada de inferência é capada em 1600 e a foto passa pelo
loadCardPhoto (foto de 61MP que falhava agora conclui).

O enquadramento automático volta ao S15 (bbox cobre a janela): o S18 mirava a
caixa do rosto em 103px e deixava o busto inteiro pequeno na janela. Saem o
detector de rosto (asset removido), frameCardPhotoOnFace, a referência 103px, o
piso 0.2 e a âncora S20 (inerte sob o cover). S16/S17 intactos.
2026-09-20 17:33:29 -03:00
Francisco Solla
c7eeb5dbd8 feat(S21): jingles de Jorge Solla no site público — ouvir e baixar (Closes #1222)
Some checks are pending
Deploy / preflight (push) Waiting to run
Deploy / verify (push) Blocked by required conditions
Deploy / deploy staging (teqo-staging) (push) Blocked by required conditions
Deploy / requeue when main advanced (push) Blocked by required conditions
Deploy / deploy production (teqo-1313) (push) Blocked by required conditions
2026-09-20 01:48:20 -03:00
Francisco Solla
e652f0ae45 feat(S20): ajuste lateral da foto do card time sem limite artificial (Closes #1216) 2026-09-19 16:32:33 -03:00
Francisco Solla
468f33e5b2 feat(S19): links de compartilhamento com miniatura OG (Closes #1207) 2026-09-19 14:02:17 -03:00
Francisco Solla
cde96b26d0 feat(S18): cabeça do visitante proporcional à dos candidatos no card Time de você
- FaceDetector (blaze_face_full_range, Apache-2.0, lazy/on-device) mede o maior rosto no canvas do recorte; math pura frameCardPhotoOnFace escala a face à referência TEAM_CARD_FACE_REFERENCE_SIZE=103 (mediana das 5 caixas da arte-mestre).
- Piso do time CARD_TEAM_PHOTO_MIN_ZOOM=0.2 com clamp contain/cover por eixo (minZoom opcional preserva os 3 modelos S13/S14); fallback silencioso ao enquadramento S15 sem rosto/falha.
- Stub e2e estendido ('noface'); unit novo da math e da seleção do rosto; craft com retrato real 86-98px vs 103 (±20%); crítica Tier 1 certificada.

Closes #1197
2026-09-19 13:42:22 -03:00
Francisco Solla
dbd9ecdfd4 feat(S16): banner azul dinâmico no card "Time de você" — nomes longos cabendo (Closes #1195) 2026-09-19 13:05:52 -03:00
Francisco Solla
0d6518c3d1 feat(C200): separar falas por pessoa nas gravações enviadas (Closes #1167) 2026-09-19 12:32:46 -03:00
Francisco Solla
d7d4258cd7 feat(S17): controle "Harmonizar cores" no ready do card Time de você
Ajuste local de brilho/contraste/saturação (clamps fixos ≤12%, alpha byte-a-byte) para aproximar a selfie do tom da arte-mestre; variante gerada 1× no ready do useCardCutout e escolhida pelo toggle no mesmo canvas da prévia e do PNG. Sem migration/Consent/rede/persistência; os 3 modelos e o recorte intocados. Crítica do designer certificada no tier primário (artefato revalidado sem DEGRADED).
2026-09-19 10:55:18 -03:00
Francisco Solla
d0f606a55d feat(C199): gravações enviadas no acervo de comunicação (Closes #1166) 2026-09-18 23:42:30 -03:00
Francisco Solla
a8a5ed324f
C195 — Ingestão do pacote do reel na biblioteca privada (#1182)
C195 — Ingestão do pacote do reel na biblioteca privada
2026-09-18 22:30:57 -03:00
Francisco Solla
560f2e494a feat(S15): card "Time de você" — quarto modelo auto-serviço no funil público (Closes #1161) 2026-09-18 22:17:52 -03:00
Francisco Solla
7079c63949 Merge remote-tracking branch 'origin/main' into C195-ingestao-do-pacote-do-reel-na-biblioteca-privada
# Conflicts:
#	src/lib/reel.ts
2026-09-18 22:01:32 -03:00
Francisco Solla
7e164b637d fix(C194): port fiel ao artefato após crítica do designer (#1153)
- player mobile 226px (CTA do detalhe acima da dobra), 330px a partir de lg
- painel de downloads no mobile: CTA primário primeiro, 'Outros arquivos' depois
- cards mobile só com título/funcionalidade; data e 'Abrir reel' a partir de lg
- despublicado: aviso + publicação antes da mídia bloqueada; 'Sobre o reel' depois
- feature sem '(#cards)' na UI e data de publicação só com o dia
- 'Abrir reel' aria-hidden (o card inteiro é o link)

Design tier: openai/gpt-5.6-sol — crítica final certificada (v3, 10 capturas).
2026-09-18 21:54:37 -03:00
Francisco Solla
448f3845a2 feat(C194): biblioteca de reels na vertical Comunicação (#1153)
Lista publicados-only com capas 9:16, detalhe com player 9:16 e painel de
downloads (vídeo sem áudio primário; com áudio, mp3 e .srt quando existem;
transcrição em texto) e kill switch reversível: despublicar tira da lista e
bloqueia a mídia (C193 decision B), republicar reativa e re-carimba publishedAt.

Fiação: gate communicationCatalog (rename do speechCatalog), 3º sub-item da
vertical no nav, rule da lista no chrome, paths e loader próprios; sem
migration, sem Consent, sem tocar Media.read ou a rota de mídia do C193.

Design tier: DEGRADED — crítica final do designer indisponível no tier
primário (limite de uso); requer sign-off humano antes de push/PR.
2026-09-18 21:54:37 -03:00
Francisco Solla
5afa16c33b feat(C195): ingestão do pacote do reel na biblioteca privada (Closes #1154) 2026-09-18 21:47:48 -03:00
Francisco Solla
bdaf3c7cbb feat(C193): reel privado no CMS — modelo, upload privado e kill switch (Closes #1152) 2026-09-18 17:48:34 -03:00
Francisco Solla
45eef25b1a feat(C192): busca semântica no acervo de falas (Closes #1147)
Modo "Por tema" no acervo de falas: expansão determinística do tema via
DeepSeek (generateObject, timeout, fallback null) alimenta o motor lexical
existente (searchText/keywords OR), mantendo facetas AND, paginação por fala,
o OR de cortes do C174 e o access control intacto. Resultado de tema mostra
selo e "Por que apareceu" com trecho real (frase contínua), sem score;
degradação honesta para termo exato com aviso e vazio honesto com saídas.

- URL: mode=tema (default omitido; canonicaliza sem q), seletor otimista
- ai/expandSpeechSearchTheme + lib/speechThemeTerms (sanitiza saída do modelo)
- view model com themeMatchTerm + espelho speechMatchesSearchTerm
- UI do card de tema (selos, proveniência, ações) e aviso degradado
- sem migration/Consent/exposição pública; gate de leitura inalterado
- testes unit/int/e2e; design hi-fi estendido e certificado pelo designer
2026-09-18 17:48:28 -03:00
Francisco Solla
e5e1ae7ee8 feat(C190): dossiê Solla por tema/área + boletim modelo (skill + builder)
Terceira variante da família de dossiês: recorte pela área canônica do
acervo (SPEECH_TOPICS), com o pipeline C186/C187 generalizado para a forma
subject via THEME_UNIT (generalização aditiva; C186/C187 byte-idênticos).

- resolveSpeechTopic no dono speechFacets (fail-closed, sem slug inventado)
- themeSnapshot + extract-theme-snapshot (THEME_REPORT_CONFIRM=1, read-only)
- build-dossie-solla-tema (pack medido, PDF A4 + .md + boletim 1 página)
- skill/comando/2 subagentes (researcher por era + redator) + specs
- cenas theme-only no descritor (acervo universo/amostra, abrangência,
  lacunas, hierarquia de fontes, pills do boletim) certificadas pelo designer

Closes #1143
2026-09-18 17:02:56 -03:00
Francisco Solla
cb5854d17e feat(C187): dossiê Solla por instituição + boletim modelo (skill + builder) (Closes #1135)
Generaliza aditivamente o pipeline C186 (default município; specs verdes) via o
descritor scripts/lib/dossieUnit.mjs (municipality|institution), extrai o emit
A4/fit-guard para scripts/lib/buildPdf.mjs e a receita read-only para
scripts/lib/readOnlyExtract.mjs.

- Catálogo fail-closed src/lib/institutionCatalog.ts + institutionNameAliases.ts
  (seed UFBA/Correios/Enfermagem; escape one-off --slug/--name; dedup).
- Skill/command/subagente /dossie-solla-instituicao; eras A/B/C reusadas.
- Abrangência instituição × setor × rede nunca somada; era sem fonte vira página
  de lacuna explícita; lista capada declara "e mais N" (regra C188 no dono).
- Boletim modelo 1×A4 com fase junto ao valor, sem fontes, sem CTA; herda apenas
  fatos com fonte do dossiê (incl. falas do acervo read-only).
- Sem schema/migration/DB write; artefatos gitignored.
2026-09-17 19:25:13 -03:00
Francisco Solla
f8b0d5ecac feat(C173): pré-visualizar no player o trecho selecionado (Closes #1083) 2026-09-16 22:22:29 -03:00
Francisco Solla
b1beb07f2a fix(C182): acervo mostra o frame do meio de cada fala, não a capa da sessão (Closes #1104) 2026-09-16 21:42:36 -03:00
Francisco Solla
9de601b7aa feat(C183): apaga um corte da biblioteca e recupera cortes falhados (Closes #1105) 2026-09-16 20:34:12 -03:00