Commit Graph

16 Commits

Author SHA1 Message Date
26a68e1823 fix: restaurar deploy-staging via workflow_run (Gitea ≥1.25)
All checks were successful
CI / static (push) Successful in 2m38s
CI / unit (push) Successful in 3m40s
CI / feature (push) Successful in 2m55s
CI / container (push) Successful in 1m11s
CI / browser (push) Successful in 4m22s
Remove job/reusable workflow do CI. Staging volta a ser workflow
separado após CI; 1.24 não implementava o trigger.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-12 16:01:56 -03:00
ac08b5f064 fix: staging deploy via needs no CI, não workflow_run
Some checks failed
CI / static (push) Successful in 2m35s
CI / unit (push) Successful in 3m36s
CI / feature (push) Successful in 2m31s
CI / container (push) Successful in 1m0s
CI / browser (push) Successful in 4m11s
CI / deploy-staging (push) Failing after 6m19s
workflow_run nunca disparou no Gitea 1.24 com CI multi-job.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-12 15:33:29 -03:00
dd82ca2dca fix: paralelizar CI no act_runner (rede por job, sem :8000 no host)
Some checks failed
CI / static (push) Successful in 2m48s
CI / unit (push) Successful in 3m54s
CI / feature (push) Successful in 2m53s
CI / container (push) Failing after 55s
CI / browser (push) Successful in 4m18s
capacity>1 exige rede isolada por job e containers aninhados via DNS,
sem publish de host ports que colidem entre jobs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-12 15:12:07 -03:00
87a019109d fix: CI Postgres via hostname, sem bind :5432 no host
Some checks failed
CI / container (push) Waiting to run
CI / static (push) Successful in 1m24s
CI / unit (push) Failing after 1m31s
CI / feature (push) Failing after 1m14s
CI / browser (push) Failing after 2m10s
act_runner em VPS compartilhada falhava com port already
allocated; jobs usam service postgres na rede do job.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-12 15:02:24 -03:00
1468a23145 fix: remover actions/cache no Gitea Actions
Some checks failed
CI / static (push) Successful in 1m25s
CI / unit (push) Failing after 1s
CI / feature (push) Failing after 1s
CI / browser (push) Failing after 0s
CI / container (push) Failing after 2m38s
Job containers nao alcancam o cache do act_runner
(ETIMEDOUT ~5m). Tira cache steps e Buildx type=gha.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-12 14:57:12 -03:00
f730e766f5 fix: secrets de registry sem prefixo GITEA_
Some checks failed
CI / unit (push) Waiting to run
CI / static (push) Successful in 6m23s
CI / feature (push) Failing after 0s
CI / browser (push) Failing after 0s
CI / container (push) Has been cancelled
Gitea rejeita nomes de secret reservados GITEA_*; workflows
e runbook passam a REGISTRY_PAT / REGISTRY_USER.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-12 14:44:04 -03:00
1e215ac3d2 docs: alinhar remotes e registry para Gitea
Some checks failed
CI / unit (push) Has been cancelled
CI / feature (push) Has been cancelled
CI / browser (push) Has been cancelled
CI / container (push) Has been cancelled
CI / static (push) Has been cancelled
Origin e deploy passam a documentar git.hellomanoel.com;
GitHub/GHCR ficam como legado/backup.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-12 14:35:20 -03:00
716196dbe0 fix: owner path manoel-freitas/amare no registry Gitea
Conta renomeada admin→manoel-freitas; paths de imagem e docs
alinham com repo real no git.hellomanoel.com.
2026-08-12 14:21:24 -03:00
84f6d7c31a ci: migrate GitHub Actions para Gitea Actions
- Move .github/workflows/ para .gitea/workflows/ (desativa CI no GitHub)
- gitea.* contexts no lugar de github.*; GITHUB_TOKEN -> GITEA_PAT/GITEA_REGISTRY_USER
  (GITEA_TOKEN nao publica pacotes OCI, gitea#23642)
- Registry: ghcr.io -> git.hellomanoel.com (container registry da instancia)
- docs/deployment/dokploy.md: prereqs Gitea (Actions, runner, secrets, Dokploy registry)
2026-08-12 13:54:27 -03:00
2e43fdeb04 chore: usar America/Sao_Paulo como timezone da aplicação (#42)
A cidade de atuação é São Paulo, garantida por teste em quatro lugares e
exigida por openspec/specs/site-settings/spec.md. O identificador de
timezone, porém, era America/Fortaleza. O identificador passa a
acompanhar o negócio.

A mudança não altera comportamento. America/Sao_Paulo e
America/Fortaleza são UTC-3 o ano inteiro desde que o horário de verão
brasileiro foi extinto — verificado para janeiro, março e dezembro de
2026, idênticos ao segundo. Nada renderizado muda, o relógio congelado
dos testes visuais usa offset absoluto (-03:00) e os baselines seguem
válidos.

O motivo de mexer é outro: a divergência entre o timezone e a cidade
custou tempo real. Uma sessão anterior a interpretou como drift e
"corrigiu" a SPEC no sentido errado, mudando o documento normativo para
Fortaleza em vez de olhar o que o negócio é. Com os dois valores dizendo
São Paulo, não há mais o que interpretar.

Escopo: config/app.php, .env.example, os dois pontos do ci.yml,
SPEC.md (§0, §13.5, §15.4), README.md, docs/deployment/dokploy.md,
CLAUDE.md, openspec/config.yaml, openspec/specs/visual-regression/spec.md
e o withTimezone do VisualRegressionTest.

Intocados de propósito: as asserções que garantem que Fortaleza não
aparece como cidade de operação, em PublicPagesTest, SiteSettingsTest,
ContentSeederProductionGatingTest e openspec/specs/site-settings. Essas
tratam de cidade, não de fuso, e continuam corretas.

Co-Authored-By: Claude noreply@anthropic.com
AI-Assisted: yes
AI-Tool: claude-code

Co-authored-by: manoel.neto <manoel.neto@creditas.com>
2026-08-10 11:37:03 -03:00
49fbc0fdfa fix(seed): impedir ContentSeeder de sobrescrever conteúdo em produção (MAN-103) (#36)
* fix(seed): impedir ContentSeeder de sobrescrever conteúdo em produção

O migrate do Dokploy roda `db:seed --class=ContentSeeder --force` em todo
deploy, tanto em staging quanto em produção (mesmo compose, só o .env
muda). Como ContentSeeder usa updateOrCreate/delete incondicionais, cada
deploy em produção revertia edições feitas pela dona no Filament
(SiteSetting, Services, PortfolioCases), republicava os 3 casos e
serviços fictícios, apagava fotos reais da galeria e reenviava as
fixtures de imagem para o bucket R2 de produção — além de publicar os
depoimentos reais via TestimonialsSeeder, sem autorização explícita.

Adiciona uma guarda de ambiente no início de ContentSeeder::run(),
seguindo o mesmo padrão já usado em AppServiceProvider::
freezeClockWhenConfigured(): em APP_ENV=production o método retorna
sem efeito colateral (exit 0), preservando o passo migrate&&seed&&...
do docker-compose.deploy.yml. TestimonialsSeeder não é tocado — ele
continua sendo o único caminho de publicação de depoimentos em
produção, documentado como passo manual em docs/deployment/dokploy.md.
Staging (APP_ENV=staging) continua recebendo conteúdo de demonstração
normalmente, preservando a revisão visual.

Atualiza docs/deployment/dokploy.md, que afirmava (incorretamente,
desde o commit 10a1f0d) que os workflows de deploy eram "migrate-only"
e que ContentSeeder nunca rodava em staging/produção.

Adiciona teste de regressão cobrindo: banco vazio em produção (nenhum
registro criado, nenhuma fixture enviada ao disco), banco com conteúdo
editado pela dona em produção (seeding duas vezes não altera nada) e
comportamento inalterado fora de produção (semeia o conteúdo de demo
normalmente).

Co-Authored-By: Claude noreply@anthropic.com
AI-Assisted: yes
AI-Tool: claude-code

* fix(seed): trocar guarda de produção do ContentSeeder para allow-list

O guard anterior (`App::environment('production')`) é uma comparação
exata e sensível a maiúsculas contra o valor literal de APP_ENV, que é
digitado manualmente no editor de texto livre do Dokploy sem validação,
enum ou valor padrão garantido por este repositório. Se esse valor
algum dia ficar vazio, vier com case diferente ('Production',
'PRODUCTION'), espaço em branco ou for simplesmente digitado errado, o
guard falha aberto: o ContentSeeder roda seu caminho destrutivo em
produção sem nenhuma outra checagem no caminho de deploy que pegasse o
erro — exatamente o cenário que esta guarda deveria evitar.

Inverte a lógica para uma allow-list dos ambientes conhecidos e
seguros ('local', 'staging', 'testing'), então qualquer valor não
reconhecido de APP_ENV — incluindo 'production', vazio, mal digitado
ou com case diferente — falha fechado (no-op) em vez de falhar aberto
(sobrescrever dados reais). 'testing' entra na lista porque é o valor
de APP_ENV usado pelo job `feature` do CI (ver .github/workflows/ci.yml),
que roda testes que chamam ContentSeeder diretamente — sem esse valor
a suíte quebraria em CI mesmo passando localmente (APP_ENV=local via
.env).

Adiciona cobertura de regressão via data provider cobrindo tanto os
três ambientes permitidos quanto uma lista de valores não permitidos
('production', string vazia, 'Production', 'PRODUCTION', espaço à
direita, valor arbitrário desconhecido), para que a guarda seja testada
como allow-list e não apenas contra o literal 'production'.

Co-Authored-By: Claude noreply@anthropic.com
AI-Assisted: yes
AI-Tool: claude-code

* docs(deploy): corrigir descrição da guarda do ContentSeeder no runbook

O texto descrevia a guarda antiga (deny-list de 'production') e ainda
afirmava, de forma incorreta, que a publicação dos cinco depoimentos
reais era "um passo manual e deliberado em todo ambiente (incluindo
staging)". Isso nunca foi verdade: o ContentSeeder chama o
TestimonialsSeeder internamente e só pula essa chamada quando a guarda
não casa com o ambiente atual — em staging a guarda casa, então os
depoimentos são publicados/republicados automaticamente a cada deploy,
sem nenhum passo manual envolvido (o próprio teste
test_content_seeder_still_seeds_demo_content_outside_production já
provava isso).

Atualiza as duas passagens para descrever a allow-list
('local'/'staging'/'testing') introduzida no commit anterior e para
deixar explícito que staging publica depoimentos automaticamente,
reservando o comando manual apenas para produção. Também documenta o
trade-off do fail-closed: um APP_ENV de staging digitado errado agora
faz o conteúdo de demonstração parar de ser resemeado silenciosamente.

Co-Authored-By: Claude noreply@anthropic.com
AI-Assisted: yes
AI-Tool: claude-code

---------

Co-authored-by: manoel.neto <manoel.neto@creditas.com>
2026-08-10 09:12:18 -03:00
27711ad0c2 feat: add production testimonials seeder (#11)
Canonical upsert for five authorized couples so staging/prod
can load depoimentos without DatabaseSeeder/ContentSeeder.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-05 20:11:33 -03:00
286522d8a2 fix: keep Livewire temp uploads local when using R2
Avoid browser PUT to R2 (CORS) by defaulting Filament/Livewire temp disk to local, and document Dokploy tinker + R2 CORS gotchas.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-05 00:11:32 -03:00
3e68192cf3 fix: join Dokploy network so Compose reaches managed Postgres (#9)
Migrate could not resolve the database internal hostname because the
Compose stack used an isolated project network. Attach services to the
external dokploy-network used by Dokploy Postgres.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-04 23:15:52 -03:00
1a31dd1cf6 fix: surface Dokploy API errors and normalize panel URL (#8)
curl -f hid 404 bodies; strip accidental /api on DOKPLOY_URL so compose.deploy diagnostics are actionable.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-04 23:14:12 -03:00
7f4ea01f4b feat: prepare Dokploy staging and production deploy pipeline (#6)
Publish immutable FrankenPHP images to GHCR, auto-deploy staging after CI,
and promote the same digest to production with smoke, backup, and rollback docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-01 23:40:13 -03:00