# portfolio-cases Specification ## Purpose Define editorial, publication, authorization, and gallery behavior for portfolio cases. ## Requirements ### Requirement: Portfolio cases support editorial content and ordered gallery The system SHALL allow admins to manage portfolio cases (SPEC WEB-03) with title, unique slug, summary, event type, optional city/venue/event date, challenge, solution, optional result, cover image with alt text, featured flag, sort order, `published_at`, and optional SEO meta fields. Each case MUST support an ordered gallery via `portfolio_images` (path, alt text, optional caption, sort order). #### Scenario: Draft case is not publicly visible - **WHEN** a portfolio case has `published_at` null - **THEN** the `published()` scope MUST exclude it #### Scenario: Published case meets acceptance criteria - **WHEN** an admin fills required fields and sets `published_at` - **THEN** the case MUST be included in the `published()` scope - **AND** cover and gallery images MUST have alt text when present #### Scenario: Gallery images maintain order - **WHEN** an admin reorders gallery images in Filament - **THEN** `sort_order` MUST reflect the chosen order per `portfolio_case_id` #### Scenario: Assistant cannot manage portfolio - **WHEN** an assistant attempts to access portfolio cases - **THEN** access MUST be denied with HTTP 403 #### Scenario: Cascade delete removes gallery images - **WHEN** a portfolio case is deleted - **THEN** associated `portfolio_images` records MUST be removed (FK cascade)