O primeiro deploy pós-fix faz backup do compose ainda bare e o cleanup novo
remove os aliases bare em seguida: um rollback manual restaurando esse backup
legado precisaria recriar o alias (docker tag) após o pull. Documenta a
janela de transição na seção de rollback e na linha INF13 da tabela de
falhas.
O compose do stack referenciava a tag local bare teqo-1313:<sha>, que é uma
segunda ref que nada recria se perdida (achado INF8 24/08: só restava a ref
do registry e o 'compose up -d' falhou com No such image). Agora:
- swap escreve sempre localhost:5000/teqo-1313(-migrator):<sha> (sed
idempotente aceita ambas as formas); os docker tag bare somem (sem
consumidor);
- rollback do runbook simplifica (docker pull basta, sem dance de tag);
- limpeza pós-deploy (INF3/F2) preserva TODAS as tags da imagem em uso pelo
IMAGE ID do container, imune a drift de label do compose.
Runbook docs/ops/teqo-1313-deploy.md atualizado (fluxo, rollback, tabela de
falhas com o achado). Issue de referência (tracker infra-solla):
git.solla.dev/fsolla/infra-solla#24
* deploy: limpeza pós-deploy do build cache e tags locais antigas (INF3/F2)
O deploy compila no homeserver e acumulava build cache + tags locais
antigas no disco raiz (incidente 19/08: 45G de cache). Após o smoke:
docker builder prune -f + remoção das tags locais teqo-1313 exceto o
SHA em uso (best-effort, registry preserva o rollback).
* feat(S9): captura de novidades da campanha na home pública (form + CTA do hero)
Seção 'Receba as novidades da campanha' acima do rodapé: nome + WhatsApp
obrigatórios, e-mail/estado/cidade/comentário opcionais, toggle pré-selecionado
'Quero fazer parte do time' gravado como subscription.campaignLevel
(time|esporadico). CTA secundário do hero vira o atalho (#novidades, scroll
suave). Contact + Subscription em withPayloadTransaction com consentimento
novo fail-closed por chave estável 'campanha-novidades' — nada é gravado sem o
texto aprovado no admin. Migration 20260819_192605 (state de contact nullable
+ coluna campaign_level). Impl plan, changelog, int + e2e.
* plans(C141,C143,C142): permissões granulares por assessor + responsáveis de demanda + UI por perfil
* plans(C141,C143,C142): permissões granulares por assessor + responsáveis de demanda + UI por perfil
* feat(S8): seção 'Nossa história' na home — vídeo da trajetória embutido do YouTube (Closes#91)
* docs(S8): resolução do conflito com S9 (história → newsletter) + nota do guard e2e dev-only
* feat(S10): pixel do Meta na página pública de campanha (campo admin em SiteSettings + PageView na home + Lead no sucesso da captura)
Campo tracking.facebookPixelId no global SiteSettings (mesma validação/normalização do precedente Petition, regra centralizada em facebookPixel.ts); home (grupo (home)) injeta o base code + PageView quando o ID está configurado (fail-closed) e o CampaignNewsletterForm dispara exatamente um Lead no sucesso do S9. Migration 20260819_213947_add_site_settings_facebook_pixel_id. Closes#94
* refactor(S10): simplify pass — Lead wiring unit-tested e raças de estado compartilhado do e2e resolvidas
e2e: stub hermético de connect.facebook.net no guard compartilhado (specs paralelos renderizam a home com o pixel); advisory lock no Postgres serializando o login do usuário de teste (Payload perde sessão em login concorrente read-modify-write — classe documentada no webauthn); seedTestUser vira create-if-missing (sem janela de usuário ausente nem reset de senha); Lead do form protegido do catch de erro (tracking nunca falha uma captura commitada); descrição do campo compartilhada; unidade nova campaignNewsletterLead cobre exatamente um Lead no sucesso.
* feat(C141): perfis de permissão por assessor — Visão × Edição configuráveis, enforcement fail-closed (Closes#105)
* chore(C141): regenera changelog agregado após rebase com S10
* plans(C144): options write-scoped para formulários de escrita pós-C141
---------
Co-authored-by: Francisco Solla <admin@solla.dev>
O fail-closed silencioso da S3 deixava a assessoria cega: token errado não deixava
rastro além do picker vazio. Fim da caixa-preta:
- `instagramSyncStatus` (jsonb hidden) na global `social-feed-settings`, escrito pelo
render, pelo afterChange (sync awaited quando a credencial IG muda) e pela rota
`POST /api/social-feed/sync` (botão, auth admin + same-origin).
- `InstagramApiError` + `describeInstagramError`: o fetch parseia o body de erro da
Graph API e o mapeia para copy pt-BR com a correção (OAuthException/expired →
"token inválido/expirado ou emitido via Facebook Login — gere pelo Instagram Login";
"Invalid user id" → confira o ID; 5xx → indisponível; TypeError → rede; AbortError →
demorou demais). O ID só casa com "user" E "id" juntos (token rejections real falam
"the user must be logged in" — não podem virar a branch de ID).
- `InstagramSyncStatusPanel` (campo ui irmão do picker): 5 estados fiéis ao rascunho;
gate respeita o master `enabled`; `outcome` transiente limpo ao editar credencial;
aria-live nos boxes interativos. Home inalterada (fail-closed intacto).
- Bug real: `afterChange` roda dentro da transação do save (row lock até os hooks
retornarem); persistir o status via pool numa 2ª conexão deadlockava no lock da
própria linha (~80-230s/save). Fix: persists do sync-hook na MESMA transação via
`getPostgresTransactionDatabase` (C6); render/rota sem transação seguem no pool.
Diagrama: UPDATE transactionid Lock vs idle in transaction; fix verificado 45ms vs 232s.
- Stub IG ganha estado `invalid-token`; runbook docs/ops/instagram-feed-token-runbook.md;
migration add_instagram_sync_status (jsonb nullable).
- Débitos registrados: #124 (janela de lock) e #125 (polish P3).
- Gates: unit 2463 + int 791; lint/format/tsc/cycles; build; e2e admin 5/5 + frontend serial 19/19.
Job deploy em ci.yml (runs-on host na workstation) streama
scripts/deploy-homeserver.sh para o homeserver via SSH: build dos stages
runner+migrator com secrets do teqo-1313.env, push no registry local,
migrate pelo serviço de maintenance antes do rollout, up + smoke. Zero
secrets novos no Forgejo; HEAD guard + flock; rollback automático com
backup do compose; runbook docs/ops/teqo-1313-deploy.md; invariantes
unit do script (bash -n + estrutura).