Archive completed public-site and production-provider changes into main specs, remove duplicate active changes, and add complete-foundation-parity so Phase 0 staging and remaining foundation gaps block Phase 2 cleanly. Co-authored-by: Cursor <cursoragent@cursor.com>
120 lines
5.7 KiB
Markdown
120 lines
5.7 KiB
Markdown
# public-site-pages Specification
|
|
|
|
## Purpose
|
|
Define public routes, editorial home, catalog pages, institutional/error pages, and contact placeholder for the marketing site.
|
|
|
|
## Requirements
|
|
### Requirement: Public routes serve published content without authentication
|
|
|
|
The system SHALL expose the public routes of SPEC §5.1: `home` (`/`), `services.index` (`/servicos`), `portfolio.index` (`/portfolio`), `portfolio.show` (`/portfolio/{slug}`), `about` (`/sobre`), `contact` (`/contato`) and `privacy` (`/privacidade`). Every public route MUST respond without authentication and MUST NOT expose unpublished content, internal fields, or internal notes (SPEC §19).
|
|
|
|
#### Scenario: Guest reaches every public route
|
|
|
|
- **WHEN** an unauthenticated visitor requests any public route
|
|
- **THEN** the response status MUST be 200
|
|
- **AND** no redirect to `/admin/login` MUST occur
|
|
|
|
#### Scenario: Unpublished content is invisible
|
|
|
|
- **GIVEN** a service, portfolio case, or testimonial with `published_at` null
|
|
- **WHEN** a visitor loads the corresponding public page
|
|
- **THEN** the record MUST NOT appear in the rendered output
|
|
|
|
#### Scenario: Unpublished case detail returns 404
|
|
|
|
- **GIVEN** a portfolio case saved as draft
|
|
- **WHEN** a visitor requests `/portfolio/{slug}` for that case
|
|
- **THEN** the response status MUST be 404
|
|
|
|
#### Scenario: Published case detail becomes reachable
|
|
|
|
- **GIVEN** a portfolio case saved as draft
|
|
- **WHEN** an admin fills the required fields and publishes the case
|
|
- **THEN** `/portfolio/{slug}` MUST respond 200
|
|
- **AND** the case MUST appear in the `/portfolio` listing
|
|
|
|
### Requirement: Home renders the editorial structure from CMS content
|
|
|
|
The home page SHALL render, in the order defined by SPEC §6.2, header/navigation, hero, featured visual proof, services summary, working method, selected cases, testimonials, final briefing CTA, and footer with contact, social links and legal links (WEB-01). Hero copy, brand name and contact data MUST come from `site_settings`; services, cases and testimonials MUST come from published records.
|
|
|
|
#### Scenario: Published content is displayed in configured order
|
|
|
|
- **GIVEN** published services, cases and testimonials exist
|
|
- **WHEN** a visitor loads the home
|
|
- **THEN** the published content MUST be displayed following the `sort_order` and featured flags
|
|
- **AND** the hero MUST show the values stored in `site_settings`
|
|
|
|
#### Scenario: CTA leads to the briefing page
|
|
|
|
- **WHEN** a visitor activates the primary or final CTA on the home
|
|
- **THEN** the visitor MUST be taken to the `contact` route
|
|
|
|
#### Scenario: Empty content does not break the home
|
|
|
|
- **GIVEN** no published services, cases or testimonials
|
|
- **WHEN** a visitor loads the home
|
|
- **THEN** the response MUST be 200
|
|
- **AND** the affected sections MUST be omitted instead of rendering empty containers
|
|
|
|
#### Scenario: Home has no console errors
|
|
|
|
- **WHEN** the home is loaded in a real browser at desktop and mobile viewports
|
|
- **THEN** the browser console MUST contain no JavaScript errors
|
|
|
|
### Requirement: Listing and detail pages exist for catalog content
|
|
|
|
The system SHALL render a services listing (WEB-02) and a portfolio listing plus case detail (WEB-03). The case detail MUST present summary, event type, optional city/venue/date, challenge, solution, optional result, cover image and the ordered gallery.
|
|
|
|
#### Scenario: Services listing shows published services
|
|
|
|
- **WHEN** a visitor loads `/servicos`
|
|
- **THEN** every published service MUST be listed with title and summary in `sort_order`
|
|
|
|
#### Scenario: Gallery respects stored order
|
|
|
|
- **GIVEN** a published case with multiple gallery images
|
|
- **WHEN** a visitor loads the case detail
|
|
- **THEN** the images MUST be rendered ordered by `sort_order`
|
|
|
|
#### Scenario: Listings paginate open-ended growth
|
|
|
|
- **WHEN** the number of published cases exceeds the page size
|
|
- **THEN** `/portfolio` MUST paginate instead of rendering all records
|
|
|
|
### Requirement: Institutional and error pages have brand identity
|
|
|
|
The system SHALL provide the Sobre and Política de privacidade pages and branded error pages (WEB-07). The 404 page MUST use the public layout, and the 500 page MUST NOT expose stack traces or internal details when `APP_DEBUG` is false.
|
|
|
|
#### Scenario: Unknown URL renders branded 404
|
|
|
|
- **WHEN** a visitor requests a non-existent public URL
|
|
- **THEN** the response status MUST be 404
|
|
- **AND** the page MUST use the public layout and offer navigation back to the home
|
|
|
|
#### Scenario: Server error hides internals in production
|
|
|
|
- **GIVEN** `APP_DEBUG` is false
|
|
- **WHEN** an unhandled exception occurs on a public route
|
|
- **THEN** the response MUST be a generic branded error page
|
|
- **AND** MUST NOT contain a stack trace, file path, or environment variable
|
|
|
|
### Requirement: Contact page presents contact data as briefing placeholder
|
|
|
|
The `contact` route SHALL render the contact page using `site_settings` (e-mail, phone, city, social links) so the home CTA has a valid destination before the briefing form exists. The page MUST NOT create leads in this change.
|
|
|
|
#### Scenario: Contact page shows configured contact data
|
|
|
|
- **WHEN** a visitor loads `/contato`
|
|
- **THEN** the e-mail and phone stored in `site_settings` MUST be displayed
|
|
- **AND** no lead record MUST be created
|
|
|
|
### Requirement: Public pages avoid N+1 queries
|
|
|
|
Public pages SHALL load related content with explicit eager loading through dedicated read Queries in the Application layer. Rendering a page MUST NOT issue one query per related record (SPEC §19).
|
|
|
|
#### Scenario: Case detail loads gallery in bounded queries
|
|
|
|
- **WHEN** a case detail page with many gallery images is rendered
|
|
- **THEN** the gallery MUST be loaded with eager loading
|
|
- **AND** the query count MUST NOT grow with the number of images
|