feat: ship public site with SEO and visuals (#3)

* feat: ship public site with SEO and visuals

Publish CMS content on public routes with responsive media,
accessibility checks, and deterministic visual baselines.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: make browser visual CI deterministic for media

Mount host public storage into FrankenPHP so seeded fixtures are served,
and replace PNG-as-JPG fixtures with real JPEGs so Chromium can render them.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix: serve public media on same-origin storage paths

Pest Browser hosts on 127.0.0.1:port while Storage::url used
http://localhost, so screenshots captured broken images. Use relative
/storage URLs for media and absolutize only OG tags via url().

Co-authored-by: Cursor <cursoragent@cursor.com>

* test: refresh visual baselines from CI Ubuntu screenshots

Media now loads on same-origin /storage paths, so baselines must
capture the rendered fixtures. Use full-page snapshots from the CI
runner to keep Pest's exact snapshot match stable across environments.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-29 10:12:24 -03:00
committed by GitHub
parent 7a858b52af
commit 3dc1f449ee
102 changed files with 3992 additions and 61 deletions

View File

@@ -0,0 +1,45 @@
## Why
O CMS da Fase 1 está concluído (`site-settings`, `service-catalog`, `portfolio-cases`, `testimonials`, `content-media`), mas nenhum conteúdo publicado chega ao visitante: a única rota pública é `/` com um placeholder estático "Em breve". Sem o site público, o critério de saída da Fase 1 ("site público aprovado visualmente") não é atendido, a hipótese de aquisição do SPEC §2.2 não pode ser testada e a Fase 2 (briefing/leads) não tem onde ancorar o CTA.
## What Changes
- Implementar as rotas públicas do SPEC §5.1 ainda ausentes: `/servicos`, `/portfolio`, `/portfolio/{slug}`, `/sobre`, `/privacidade`, `/contato` (shell) e `/sitemap.xml`.
- Substituir a home placeholder por home editorial dirigida por conteúdo publicado, na ordem do SPEC §6.2 (WEB-01).
- Renderizar SEO por página: title, meta description, canonical, Open Graph, dados estruturados básicos, `robots.txt` servido por rota e sitemap com slugs publicados (SPEC §6.6).
- Injetar script de analytics apenas quando `analytics_enabled` estiver ativo em `site_settings` (WEB-06).
- Entregar mídia responsiva: variantes geradas no upload, `srcset`/`sizes`, `loading="lazy"` fora da primeira dobra e dimensões reservadas contra CLS (SPEC §6.4).
- Páginas de erro 404 com identidade visual e 500 sem stack trace em produção (WEB-07).
- Adicionar regressão visual determinística desktop/mobile para as telas do SPEC §13.5 já existentes nesta fase e testes automatizados de acessibilidade nas rotas públicas (SPEC §6.5, §13.8).
- Elevar o gate `browser` do CI para incluir snapshots visuais e acessibilidade, publicando artefatos diagnósticos em falha.
## Non-Goals
Conforme [SPEC.md §4.2](../../SPEC.md) e a divisão de fases:
- Formulário de briefing (WEB-05) e captura de lead — Fase 2. Esta change entrega apenas a página `/contato` com dados de contato do `site_settings`; o componente Livewire do briefing e as jornadas E2E-01/E2E-02 ficam para `build-lead-capture`.
- Snapshots de Briefing, Login, Dashboard e Detalhe do evento (SPEC §13.5) — dependem de telas de fases posteriores.
- Page builder, editor visual de páginas, busca no site, i18n, PWA.
- Password reset do painel interno (lacuna conhecida de `internal-authentication`, sem relação com o site público).
- Auditoria de publicação/despublicação (ADM-02) — Fase 5.
## Capabilities
### New Capabilities
- `public-site-pages`: rotas, layout e páginas públicas que exibem somente conteúdo publicado (WEB-01, WEB-02, WEB-03, WEB-04, WEB-07, SPEC §19).
- `public-seo`: metadados por página, canonical, Open Graph, dados estruturados, sitemap, robots e analytics condicional (SPEC §6.6, WEB-06).
- `visual-regression`: snapshots determinísticos desktop/mobile das telas públicas (SPEC §13.5).
- `web-accessibility`: verificação automatizada de acessibilidade das rotas públicas (SPEC §6.5, §13.8).
### Modified Capabilities
- `content-media`: além de validar upload, o sistema MUST gerar/servir variantes responsivas, aplicar lazy loading fora da primeira dobra e reservar dimensões (SPEC §6.4).
- `quality-gates`: o gate `browser` MUST executar snapshots visuais e acessibilidade e publicar artefatos diagnósticos em falha (SPEC §13.4, §14.1).
## Impact
- **Cria**: `routes/web.php` (rotas públicas), controllers em `app/Http/Controllers/PublicSite/`, Queries em `app/Application/Queries/Marketing/`, componentes Blade em `resources/views/components/` e páginas em `resources/views/pages/`, testes em `tests/Feature/PublicSite/` e `tests/Browser/`, baselines de snapshot versionadas.
- **Altera**: `resources/views/layouts/public.blade.php` (head SEO, landmarks, skip link), `app/Support/PublicImageUploadRules.php` e Filament Resources (geração de variantes), `ContentSeeder` (dados determinísticos para snapshots), `.github/workflows/ci.yml`, `public/robots.txt` (substituído por rota), `composer.json` se novo script for necessário.
- **Depende de**: specs `site-settings`, `service-catalog`, `portfolio-cases`, `testimonials`, `content-media`, `design-tokens`.
- **Risco**: instabilidade de snapshot (mitigada por relógio congelado, seed determinístico, fontes na imagem e animações desabilitadas — SPEC §13.5, §20).