5.2 KiB
Context
WeddingPackage já cobre cards ordenados + CTA WhatsApp/briefing (change restructure-home-weddings-corporate, capability ainda só no delta completo). Campos atuais: name, level, summary, scope_items (json), cta_label, sort_order, published_at. Sem slug, sem corpo de detalhe, sem imagens. Portfólio (portfolio.show, FindPublishedPortfolioCaseBySlug, PageMeta, sitemap) é o padrão de detalhe a espelhar. Mock visual: /home/manoelfreitas/Downloads/amare-assessoria-completa.html. Tokens: DESIGN.md / resources/css/tokens.css (Heritage Editorial) — não Cormorant/Inter do HTML estático.
Goals / Non-Goals
Goals:
- Detalhe CMS-driven
/pacotes/{slug}para as 3 modalidades, publish-gated. - Composição mock → tokens do projeto (olive accent, EB Garamond via stack existente, bg cream).
- CTA final = mesmo canal contextual dos cards (
wa.meou/briefing?servico_interesse=). - SEO mínimo: meta por registro, canonical, OG image (hero ou default), entrada no sitemap.
- Admin Filament editável sem deploy de copy.
Non-Goals:
- Rota índice
/pacotes; substituir cards da home; WhatsApp Business API; preços; multi-idioma; Livewire público; gallery multi-imagem além de hero + audience.
Decisions
Estender WeddingPackage, não criar modelo novo
Uma entidade comercial já existe e é o que home/serviços já consomem. Detalhe é projeção do mesmo agregado. Modelo paralelo geraria sync de publicação/slug e viola YAGNI.
Slug único + publicação por published_at
Igual portfólio: URL estável, scope published(), query Application FindPublishedWeddingPackageBySlug. Draft/inexistente → 404 HTTP, sem vazar campos internos.
Campos de detalhe (additive)
| Campo | Uso |
|---|---|
slug |
string unique |
eyebrow |
ex. "Assessoria" |
title_line |
parte romana do H1 |
title_emphasis |
parte itálica do H1 |
hero_lead |
parágrafo do hero |
hero_image_path / hero_image_alt |
foto hero |
benefits |
jsonb [{icon_key,label}] — faixa escura |
included_items |
jsonb [{icon_key,title,description}] — grid 3 col |
audience_heading |
default editorial se vazio ok |
audience_intro |
texto |
audience_points |
jsonb string[] checklist |
audience_image_path / audience_image_alt |
foto 50/50 |
final_cta_heading / final_cta_body |
bloco final |
meta_title / meta_description |
SEO opcional |
Manter summary + scope_items para cards. Não migrar cards para included_items neste ciclo.
Catálogo fechado de ícones (PackageIconCatalog)
Select Filament → icon_key string. Map PHP/Blade para SVGs inline (ou partials). Sem upload de SVG arbitrário (XSS/ops). Chaves mínimas cobrem mock (ex.: calendar, checklist, users, map, heart, spark — nomes estáveis kebab).
Hero de pacote vs photo-hero genérico
Mock exige H1 bipartido (linha + ênfase itálica), divisor vertical, CTA outline no hero e foto. Preferir componente dedicado x-public.package-hero (ou estender photo-hero só se API ficar genérica sem branching feio). Seções: package-benefits, package-included, package-audience, reutilizar final-cta se encaixar.
CTA WhatsApp
Reutilizar VO/helper já usado nos cards (digits de SiteSetting.whatsapp_number, mensagem com nome da modalidade). Mesma regra de fallback briefing. Não duplicar lógica de normalização.
Links a partir dos cards
Card: título/área → route('packages.show', $package) quando slug presente; botão CTA continua WhatsApp/briefing. Sem quebrar testes de CTA existentes.
Imagens
PublicImageUploadRules + disk público existente + x-media.image. Paths nullable; se hero ausente, layout degrada (omitir slot de imagem).
Camada Application
FindPublishedWeddingPackageBySlug- Estender
GetSitemapEntriescom slugs de pacotes publicados - PageMeta no controller (espelhar PortfolioCaseController)
Sem repository genérico / BaseAction.
Risks / Trade-offs
- [Capability
wedding-packagesainda não está emopenspec/specs/] → delta ADDED nesta change; ao arquivar, consolidar com requirements de cards do change completo ou arquivar ambos em ordem. - [Copy das 3 modalidades incompleta] → seeder: Essenza = mock; Conduzione/Grand Jour estrutura paralela adaptada; admin pode editar.
- [Ícones insuficientes no catálogo] → adicionar chave no map + opção Filament; sem free-text SVG.
- [Cards sem slug durante migrate] → migration backfill slug a partir do name; seeder garante os 3 oficiais.
- [Duplicação visual mock vs tokens] → testes de tokens existentes + asserts de classes/roles; não copiar hex do HTML.
Migration Plan
- Deploy migration additive + código + assets Blade juntos.
- Rodar seeder/update das 3 modalidades (slug + detalhe).
- Verificar
/pacotes/essenza(etc.), 404 draft, sitemap, CTA WA. - Rollback: remover rota/views; colunas additive podem permanecer; unpublish pacotes se necessário.
Open Questions
- Nenhuma bloqueante (decisões de produto já confirmadas: detalhe-only, extend model, 3 modalidades, WA CTA).
- WEB-ID dedicado a package detail: não existe no SPEC; rastrear via WEB-02 + padrão WEB-03 até SPEC ganhar ID explícito.