Files
amare/openspec/specs/public-seo/spec.md
manoel freitas 9dd6fcf409 docs: sync OpenSpec archives and propose foundation parity
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>
2026-08-01 21:55:04 -03:00

4.1 KiB

public-seo Specification

Purpose

Define per-page SEO metadata, Open Graph, sitemap, robots, structured data, and conditional analytics for public routes.

Requirements

Requirement: Every public page emits title, description and canonical

The system SHALL render a unique <title>, a <meta name="description"> and a <link rel="canonical"> on every public route (SPEC §6.6, §19). Portfolio cases MUST use meta_title/meta_description when filled and fall back to title/summary otherwise. Pages without page-level metadata MUST fall back to default_meta_title and default_meta_description from site_settings.

Scenario: Page-level metadata overrides defaults

  • GIVEN a published case with meta_title and meta_description filled
  • WHEN a visitor loads the case detail
  • THEN the rendered title and description MUST use the case values

Scenario: Missing metadata falls back to site defaults

  • GIVEN a published case without meta_title
  • WHEN a visitor loads the case detail
  • THEN the rendered title MUST be derived from the case title
  • AND the description MUST fall back to the case summary or the site default

Scenario: Canonical points to the absolute route URL

  • WHEN any public page is rendered
  • THEN the canonical URL MUST be the absolute URL of that route without query parameters

Requirement: Open Graph metadata is emitted for sharing

The system SHALL emit Open Graph tags (og:title, og:description, og:type, og:url, og:image) on public pages. The image MUST use the page cover image when available and default_og_image_path from site_settings otherwise.

Scenario: Case detail uses its cover as OG image

  • GIVEN a published case with a cover image
  • WHEN the case detail is rendered
  • THEN og:image MUST reference the case cover image URL

Scenario: Pages without cover use the default OG image

  • WHEN a page without its own image is rendered
  • THEN og:image MUST reference default_og_image_path

Requirement: Sitemap and robots are served by the application

The system SHALL serve /sitemap.xml listing the home, institutional routes, the services listing, the portfolio listing and every published case slug with its last modification date. /robots.txt MUST be served by an application route referencing the sitemap URL.

Scenario: Sitemap contains only published slugs

  • GIVEN one published case and one draft case
  • WHEN /sitemap.xml is requested
  • THEN the response MUST include the published slug
  • AND MUST NOT include the draft slug

Scenario: Newly published case enters the sitemap

  • WHEN an admin publishes a case
  • THEN the case slug MUST appear in /sitemap.xml on the next request

Scenario: Robots references the sitemap

  • WHEN /robots.txt is requested
  • THEN the response MUST be text/plain
  • AND MUST contain the absolute /sitemap.xml URL

Requirement: Basic structured data is emitted where applicable

The system SHALL emit JSON-LD structured data: Organization on the home using site_settings, and Article or equivalent creative work on the case detail.

Scenario: Home exposes organization data

  • WHEN the home is rendered
  • THEN a JSON-LD block of type Organization MUST be present with brand name and contact data

Scenario: Structured data is valid JSON

  • WHEN any public page emits JSON-LD
  • THEN the script content MUST parse as valid JSON

Requirement: Analytics script is injected only when explicitly enabled

The system SHALL render the analytics snippet from site_settings only when analytics_enabled is true and the script field is non-empty (WEB-06). Analytics MUST be disabled by default.

Scenario: Analytics disabled emits nothing

  • GIVEN analytics_enabled is false
  • WHEN any public page is rendered
  • THEN the analytics snippet MUST NOT appear in the HTML

Scenario: Analytics enabled injects the configured snippet

  • GIVEN analytics_enabled is true and a snippet is configured
  • WHEN a public page is rendered
  • THEN the snippet MUST be present exactly once