# admin-content-management Specification

## Requirements

### Requirement: Filament admin panel

The system MUST provide a Filament 5 admin panel at `/admin` with Spanish labels, the brand name
"Piedra Total Perú", the logo from `piedra-total-peru.png`, and a custom primary color drawn from
the brand palette.

#### Scenario: Admin panel is branded in Spanish

- GIVEN an authenticated admin
- WHEN they open `/admin`
- THEN the panel shows the brand name "Piedra Total Perú", the brand logo, and Spanish labels

#### Scenario: Unauthenticated access is blocked

- GIVEN a visitor without an admin session
- WHEN they request `/admin`
- THEN they are redirected to the login screen

### Requirement: Admin authentication and access control

The system MUST support creating admin users, logging in, and restricting panel access through a
`FilamentUser` implementation.

#### Scenario: Authorized user accesses the panel

- GIVEN a user permitted by `FilamentUser::canAccessPanel`
- WHEN they log in
- THEN they can access the admin panel

#### Scenario: Unauthorized user is denied

- GIVEN a user not permitted by `FilamentUser::canAccessPanel`
- WHEN they attempt to access the panel
- THEN access is denied

### Requirement: Content CRUD resources

The admin MUST provide CRUD resources for StoneLine/Product (media gallery, spec fields,
availability, SEO fields), Category/Taxonomy for filters, Page (nosotros/empresas/contacto
content), BlogPost (rich editor, media, SEO), Project (photos, location, stone link, type),
QuoteRequest/Lead (view/list, statuses), and SiteSetting (brand, contact, WhatsApp numbers, hours,
map, social).

#### Scenario: Admin creates a product with specs and SEO

- GIVEN an admin on the Product resource
- WHEN they create a product with a media gallery, spec fields, availability, and SEO fields
- THEN the product is saved with those values

#### Scenario: Admin manages leads and statuses

- GIVEN stored leads
- WHEN an admin updates a lead's status
- THEN the new status is persisted

#### Scenario: Admin edits editable page content

- GIVEN the Page resource
- WHEN an admin edits the content of nosotros, empresas, or contacto
- THEN the public page reflects the saved content

### Requirement: Media upload and rich content editing

The admin MUST support image upload via FileUpload to the public disk and WordPress-like content
editing via RichEditor.

#### Scenario: Uploaded media is publicly available

- GIVEN an admin uploads an image through FileUpload
- WHEN the upload completes
- THEN the file is stored on the public disk and reachable by its public URL

#### Scenario: Rich content is authored

- GIVEN an admin editing a BlogPost
- WHEN they format content in the RichEditor
- THEN the formatted content is saved and rendered on the public article

### Requirement: Publishing regenerates the sitemap

Publishing or unpublishing content MUST regenerate the sitemap.

#### Scenario: Unpublishing removes the URL from the sitemap

- GIVEN a published product or article
- WHEN an admin unpublishes it
- THEN its URL is removed from `sitemap.xml`
