feat: reestruturar jornada pública de casamentos
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-08-11
|
||||
@@ -0,0 +1,58 @@
|
||||
## Context
|
||||
|
||||
The public site currently sends every commercial CTA to `/contato`, where the detailed event briefing lives. Its home chapters reflect the original editorial sequence, while the CMS only has generic `Service` records. Production seed gating already distinguishes environmental content but the public portfolio needs an explicit empty-acervo state so no demonstrative case can be mistaken for proof.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Keep the public surface server-rendered Blade with progressive vanilla JS and a single Heritage Editorial visual language.
|
||||
- Make wedding modalities typed, publishable, ordered CMS content; derive their WhatsApp CTA server-side with an explicit briefing fallback.
|
||||
- Split prospect and partner submissions at route, request, controller, mail and success-state boundaries.
|
||||
- Keep public data minimised: partner submissions are mailed, never persisted.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- No WhatsApp API/integration, CRM Lead creation, partner directory, Corporate service inventory, Corporate case, invented evidence or page builder.
|
||||
- No production migration of fixture cases into real proof; the authorized client content remains an operational prerequisite.
|
||||
|
||||
## Decisions
|
||||
|
||||
### Typed `WeddingPackage` content instead of a JSON setting
|
||||
|
||||
`wedding_packages` has a dedicated model, migration, factory, policy, Filament resource and public query. This matches the existing publication/order model for Services and keeps content validation, ordering and authorization visible. A JSON array in `site_settings` would be faster initially but would weaken publication control and future editing.
|
||||
|
||||
### WhatsApp is a deeplink, not an integration
|
||||
|
||||
The setting stores digits-normalized `whatsapp_number`; a small value object builds `https://wa.me/<digits>?text=<encoded contextual message>`. If the setting is absent or invalid, the same CTA points to `/briefing?servico_interesse=<package>` so conversion still works. This offers the authorized official channel without violating SPEC §4.2's prohibition on an official integration.
|
||||
|
||||
### Separate partner boundary, not a mode on briefing
|
||||
|
||||
`PartnerInquiryRequest`, `PartnerInquiryController` and `PartnerInquiry` mailable have their own payload, honeypot key, throttle and session duplicate hash. It prevents event fields, marketing origin and confirmations from crossing into the partnership flow. A single controller with a discriminated input was rejected because it increases the chance of accidental routing or data disclosure.
|
||||
|
||||
### Honest public availability states
|
||||
|
||||
The home consumes `GetHomeContent`, which returns only actual published cases in production. The portfolio chapter itself remains present and shows an acervo-em-preparação note on empty data. Non-production visual fixtures continue to seed only for development/staging. Corporate remains copy plus a briefing CTA, deliberately without data-driven claims, media or a service list.
|
||||
|
||||
### Navigation links use canonical home fragments
|
||||
|
||||
Header/footer link to `/#amare`, `/#casamentos`, `/#corporate`, `/#portfolio` and `/#depoimentos` from other routes, and native fragments on the home. This preserves deep links and no-JS behavior; CSS scroll margin compensates for the sticky header.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [Official WhatsApp number is not configured at deploy] → every package CTA has a deterministic briefing fallback and settings label calls out the operational requirement.
|
||||
- [Client proof is still unavailable] → production renders no fixture cases, a visible acervo note and no Corporate cases.
|
||||
- [New contact route changes incoming links] → `/contato` remains available for partners and header/footer continue to expose it; event CTA links move deliberately to `/briefing`.
|
||||
- [Detailed forms duplicate markup] → shared field styles and narrow controllers are preferred over generic, condition-heavy form components.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Deploy the additive table/column migrations and code together.
|
||||
2. Run the content seeder to install official wedding modalities; set the official WhatsApp number in Filament before promoting CTAs.
|
||||
3. In production, leave portfolio cases unpublished until real authorized material is loaded; verify the empty-acervo state.
|
||||
4. Rollback is code-safe because routes remain additive and the legacy setting data is untouched; if necessary, unset the new WhatsApp column and retain the package rows without public publication.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Corporate institutional copy and authorized proof (MAN-98/MAN-99) remain client dependencies; no placeholder claims will be added.
|
||||
- The official WhatsApp number must be supplied before the campaign links are promoted.
|
||||
@@ -0,0 +1,31 @@
|
||||
## Why
|
||||
|
||||
A home atual apresenta os conteúdos do CMS, mas não conduz com clareza as duas frentes da Amare nem separa o pedido de proposta da relação com fornecedores. A estrutura de lançamento precisa tornar Casamentos e Corporate compreensíveis sem inventar prova, preservar o acervo real como requisito de publicação e abrir um canal mínimo, privado e específico para parcerias.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Reorganizar a home em capítulos editoriais ancoráveis: apresentação, Amare, vertentes, Casamentos, Corporate, acervo, depoimentos e fechamento.
|
||||
- Adicionar modalidades de casamento publicáveis e ordenáveis no CMS, com conteúdo inicial oficial para Essenza, Conduzione e Grand Jour.
|
||||
- Adicionar número oficial de WhatsApp às configurações e tornar as CTAs das modalidades contextuais, com fallback para o briefing.
|
||||
- Mover o formulário de pedido de proposta para `/briefing`; transformar `/contato` em uma jornada independente para fornecedores e parcerias.
|
||||
- Enviar a consulta de parceiro por e-mail próprio, sem criar Lead ou persistir dados; manter CSRF, honeypot, rate limit, validação e aviso de privacidade proporcional à finalidade.
|
||||
- Manter Corporate como apresentação institucional e CTA até haver copy, fotos e cases autorizados; em produção, não publicar fixtures de portfólio e informar que o acervo está em preparação.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `wedding-packages`: modalidades de casamento gerenciadas no CMS e CTAs contextuais de WhatsApp/briefing.
|
||||
- `partner-inquiries`: formulário público mínimo, privado e não persistente para fornecedores e parcerias.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `public-site-pages`: nova estrutura editorial da home, âncoras e separação entre briefing e contato de parceiros.
|
||||
- `service-catalog`: aprofundamento de serviços passa a apresentar as modalidades de casamento publicadas.
|
||||
- `site-settings`: configurações tipadas passam a incluir o número oficial de WhatsApp.
|
||||
- `transactional-email`: e-mail operacional separado para consultas de parceiros.
|
||||
- `content-media`: fixtures de casos ficam limitadas a desenvolvimento e staging; produção só mostra acervo real publicado.
|
||||
|
||||
## Impact
|
||||
|
||||
Afeta rotas, controllers, requests, mailables, modelos/migrations/seeders, Filament, consultas de marketing, componentes Blade, navegação, estilos e testes feature/browser. A mudança atende WEB-01, WEB-02, WEB-03, WEB-05, WEB-06 e WEB-07, sem introduzir integração oficial com WhatsApp, CRM, persistência de leads, marketplace ou outros itens fora do MVP (SPEC.md §4.2).
|
||||
@@ -0,0 +1,8 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Production never promotes visual fixture cases as Amare proof
|
||||
The content seeder SHALL restrict visual fixture portfolio cases to non-production environments. Production public output SHALL only render cases that were explicitly loaded and published as authorized content.
|
||||
|
||||
#### Scenario: Production seed does not create fixture cases
|
||||
- **WHEN** the content seeder runs with the production environment
|
||||
- **THEN** no fixture portfolio case or fixture portfolio image is published
|
||||
@@ -0,0 +1,16 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Partners have a separate, non-persistent contact journey
|
||||
The system SHALL expose `/contato` as a supplier and partnership form. It MUST collect name, optional professional/company name, e-mail, service/activity, coverage area, message, optional portfolio/social link and optional telephone. It SHALL send a dedicated internal e-mail and MUST NOT persist a Lead or partner record.
|
||||
|
||||
#### Scenario: Valid partner inquiry is delivered separately
|
||||
- **WHEN** a visitor submits valid partner data on `/contato`
|
||||
- **THEN** the configured internal recipient receives the dedicated partner inquiry e-mail
|
||||
- **AND** no briefing confirmation or Lead is created
|
||||
|
||||
### Requirement: Partner inquiry is protected and transparent
|
||||
The partner form SHALL enforce CSRF, server-side limits, honeypot, rate limiting and duplicate-click protection. It MUST show a purpose-specific privacy notice linking to the privacy policy.
|
||||
|
||||
#### Scenario: Honeypot blocks automated partner form submissions
|
||||
- **WHEN** the partner honeypot is filled
|
||||
- **THEN** the system reports generic success without sending an e-mail
|
||||
@@ -0,0 +1,38 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Home presents the weddings and corporate editorial journey
|
||||
The home SHALL expose anchored chapters for presentation, Amare, service directions, weddings, Corporate, portfolio/acervo, testimonials and final contact paths. It MUST retain the photographic hero, tonal fields, fine rules, EB Garamond and progressive/reduced-motion behavior. Corporate SHALL present only institutional copy and a briefing CTA until authorized copy and proof exist.
|
||||
|
||||
#### Scenario: Canonical anchor journey is reachable
|
||||
- **WHEN** a visitor loads the home or follows a `/#chapter` link from another public page
|
||||
- **THEN** the relevant chapter exists with a stable id and is reachable without JavaScript
|
||||
|
||||
#### Scenario: Corporate does not imply unauthorized proof
|
||||
- **WHEN** a visitor loads the Corporate chapter before client proof is published
|
||||
- **THEN** no Corporate service list, image, metric or case is rendered
|
||||
|
||||
### Requirement: Production portfolio remains truthful when no cases are published
|
||||
The public portfolio chapter SHALL render a visible acervo-em-preparação note when no real published cases are available. Production seeders MUST NOT publish development fixture cases.
|
||||
|
||||
#### Scenario: Empty production acervo is explicit
|
||||
- **GIVEN** production has no published portfolio cases
|
||||
- **WHEN** a visitor loads the home
|
||||
- **THEN** the portfolio chapter displays the acervo preparation note and no case card
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Contact page presents contact data as briefing placeholder
|
||||
|
||||
The `contact` route SHALL render the partner and supplier inquiry page using `site_settings` contact data. The detailed event proposal form SHALL be served by the `briefing` route at `/briefing`; public proposal CTAs MUST target that route. Neither public form MUST create a Lead in the launch scope.
|
||||
|
||||
#### Scenario: Contact page shows partner journey
|
||||
|
||||
- **WHEN** a visitor loads `/contato`
|
||||
- **THEN** partner-specific copy, fields and privacy notice MUST be displayed
|
||||
- **AND** the detailed event briefing MUST NOT be rendered
|
||||
|
||||
#### Scenario: Briefing route remains reachable for prospects
|
||||
|
||||
- **WHEN** a visitor loads `/briefing`
|
||||
- **THEN** the detailed event proposal form MUST be displayed
|
||||
- **AND** no Lead record MUST be created
|
||||
@@ -0,0 +1,9 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Services explain published wedding modalities
|
||||
The public services experience SHALL present published wedding modalities as the available Casamentos scope, including level, summary and ordered scope items. It MUST not treat unpublished modalities as public services.
|
||||
|
||||
#### Scenario: Draft modality remains private
|
||||
- **GIVEN** a wedding modality with `published_at` null
|
||||
- **WHEN** a visitor loads `/servicos`
|
||||
- **THEN** that modality MUST NOT be rendered
|
||||
@@ -0,0 +1,8 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Official WhatsApp number is a typed site setting
|
||||
The typed site settings singleton SHALL include an optional `whatsapp_number`. The admin form MUST validate and label it as the official number used by public modality CTAs; it MUST NOT create an external WhatsApp integration.
|
||||
|
||||
#### Scenario: Admin stores official WhatsApp number
|
||||
- **WHEN** an admin saves a valid number in site settings
|
||||
- **THEN** public wedding modality CTAs can derive the contextual deeplink
|
||||
@@ -0,0 +1,9 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Partner inquiries use a dedicated transactional message
|
||||
The system SHALL send supplier and partnership submissions in a dedicated `PartnerInquiry` mailable to the configured internal site recipient. It MUST NOT send the visitor briefing confirmation for this form.
|
||||
|
||||
#### Scenario: Partner email does not cross into briefing mail
|
||||
- **WHEN** a valid partner inquiry is submitted
|
||||
- **THEN** the recipient receives the partner field set
|
||||
- **AND** the visitor does not receive `ContactBriefingConfirmation`
|
||||
@@ -0,0 +1,26 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Wedding modalities are managed as publishable ordered content
|
||||
The system SHALL let an admin manage `WeddingPackage` records with name, level, summary, ordered scope items, CTA label, sort order and `published_at`. Only published records SHALL appear in public wedding sections, in ascending `sort_order`.
|
||||
|
||||
#### Scenario: Published modalities follow CMS order
|
||||
- **GIVEN** published and draft wedding modalities with different sort orders
|
||||
- **WHEN** a visitor loads the home or services page
|
||||
- **THEN** only published modalities appear in ascending `sort_order`
|
||||
|
||||
#### Scenario: Official initial modalities are available
|
||||
- **WHEN** the content seeder runs
|
||||
- **THEN** Essenza, Conduzione and Grand Jour are created as the official initial modalities
|
||||
|
||||
### Requirement: Wedding modality CTA has a contextual channel and conversion fallback
|
||||
The system SHALL build a WhatsApp deeplink containing the selected modality when `whatsapp_number` is valid. When it is missing or invalid, the CTA SHALL point to `/briefing` with the modality prefilled as `servico_interesse`.
|
||||
|
||||
#### Scenario: Valid WhatsApp setting creates contextual link
|
||||
- **GIVEN** a valid official WhatsApp number
|
||||
- **WHEN** a visitor activates a wedding modality CTA
|
||||
- **THEN** the link targets `wa.me` with a URL-encoded message naming that modality
|
||||
|
||||
#### Scenario: Missing WhatsApp setting preserves briefing conversion
|
||||
- **GIVEN** no valid official WhatsApp number
|
||||
- **WHEN** a visitor activates a wedding modality CTA
|
||||
- **THEN** the visitor reaches `/briefing` with `servico_interesse` prefilled
|
||||
@@ -0,0 +1,25 @@
|
||||
## 1. CMS and public content model
|
||||
|
||||
- [x] 1.1 Add the typed official WhatsApp setting with migration, model/form validation and regression coverage.
|
||||
- [x] 1.2 Add the publishable, ordered WeddingPackage model, migration, factory, policy and Filament resource with failing-first coverage.
|
||||
- [x] 1.3 Add official Essenza, Conduzione and Grand Jour seed content and production-safe visual fixture gating.
|
||||
- [x] 1.4 Extend the public marketing query/data object to load wedding modalities and truthful acervo state.
|
||||
|
||||
## 2. Proposal and partner boundaries
|
||||
|
||||
- [x] 2.1 Move the existing event proposal request/form/mail route to `/briefing`, including prefilled modality interest.
|
||||
- [x] 2.2 Add the isolated partner inquiry request, controller, rate limit, honeypot, duplicate guard and dedicated mailable.
|
||||
- [x] 2.3 Cover each public form's validation, delivery, privacy copy, anti-spam path and absence of cross-flow mail/persistence.
|
||||
|
||||
## 3. Editorial public journey
|
||||
|
||||
- [x] 3.1 Recompose home chapters and stable anchors for Amare, directions, weddings, Corporate, acervo and testimonials.
|
||||
- [x] 3.2 Render published wedding modalities with contextual WhatsApp/fallback CTAs and keep Corporate proof-free.
|
||||
- [x] 3.3 Update navigation, footer and deep-route `/#chapter` links; preserve the services, portfolio, about and privacy deep dives.
|
||||
- [x] 3.4 Update `/servicos`, `/briefing` and `/contato` with the approved factual copy and Heritage Editorial form/layout treatment.
|
||||
|
||||
## 4. Verification and handoff
|
||||
|
||||
- [x] 4.1 Run the focused feature suite and static/formatting gates; fix all scoped regressions.
|
||||
- [x] 4.2 Run browser coverage at desktop and mobile, keyboard/axe and reduced-motion checks without visual snapshots.
|
||||
- [x] 4.3 Validate the OpenSpec change and update every completed task only with recorded verification evidence.
|
||||
Reference in New Issue
Block a user