# Feature Specification: Spec 348 - Choose Environment Enterprise Selector **Feature Branch**: `348-choose-environment-enterprise-selector` **Created**: 2026-06-02 **Status**: Draft **Type**: Narrow UI productization / operator context selection **Input**: User asked to implement the enterprise best-practice findings from the in-app browser review of `/admin/choose-environment`. ## Spec Candidate Check - **Problem**: The environment chooser is conceptually correct but its card grid overflows at common desktop/tablet widths, hides secondary actions below the list, and does not scale well when a workspace has many environments. - **Today's failure**: Long environment names/domains and the raw `MANAGED_ENVIRONMENT` badge can spill out of cards, making the first context-selection step feel unreliable for enterprise operators. - **User-visible improvement**: The selector becomes a stable single-column work surface with search, top-level secondary actions, localized empty/search states, and card content that cannot overflow. - **Smallest enterprise-capable version**: Rework the existing `/admin/choose-environment` page and its custom Blade only. Add a Livewire search property and focused Feature tests. - **Explicit non-goals**: No new route, no new model/table, no new selector framework, no new global design component, no role/capability change, no destructive action, no provider integration change. - **Permanent complexity imported**: One public Livewire string property, one filtered collection method, localization keys, and focused tests. - **Why now**: The page is the first environment-context decision after workspace selection, and visible overflow undermines trust before the operator enters an admin workflow. - **Why not local**: The fix is local and intentionally stays local; a broader selector framework would be disproportionate. - **Approval class**: Cleanup. - **Red flags triggered**: UI surface change only. No persistence, status, taxonomy, or abstraction red flags. - **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitaet: 2 | Produktnaehe: 2 | Wiederverwendung: 1 | **Gesamt: 11/12** - **Decision**: approve. ## Spec Scope Fields - **Scope**: workspace + environment selector. - **Primary Routes**: `/admin/choose-environment`. - **Data Ownership**: No data model ownership changes. Existing workspace and managed-environment records remain authoritative. - **RBAC**: Existing workspace membership, environment entitlement, operability, and deny-as-not-found checks remain authoritative. ## UI Surface Impact - [ ] No UI surface impact - [x] Existing page changed - [ ] New page/route added - [ ] Navigation changed - [ ] Filament panel/provider surface changed - [x] New table/form/state added - [ ] Customer-facing surface changed - [ ] Dangerous action changed - [x] Workspace/environment context presentation changed ## UI/Productization Coverage - **Route/page/surface**: `/admin/choose-environment`, `App\Filament\Pages\ChooseEnvironment`, `resources/views/filament/pages/choose-environment.blade.php`. - **Current or new page archetype**: Workspace / Tenant Context, continuing route inventory row `UI-004`. - **Design depth**: Domain Pattern Surface. - **Repo-truth level**: repo-verified. - **Existing pattern reused**: Filament page, existing environment lifecycle presentation, existing workspace context, existing secondary action destinations. - **New pattern required**: none. The page keeps a local selector layout. - **Screenshot required**: no persistent audit screenshot for this narrow cleanup; browser verification is sufficient. - **Page audit required**: no new report required; route inventory classification stays valid. - **Customer-safe review required**: no. - **Dangerous-action review required**: no destructive/high-impact action is added. - **Coverage files updated or explicitly not needed**: Active spec documents the checked impact; durable route classification `UI-004` remains accurate. ## Cross-Cutting / Shared Pattern Reuse - **Cross-cutting feature?**: yes, narrowly. - **Interaction classes**: context selector, secondary action links, status badges. - **Existing patterns to extend**: TenantPilot enterprise UI standards for static/interactive rows, action hierarchy, and status-as-badge semantics. - **Allowed deviation and why**: none. - **Consistency impact**: Search and secondary actions must stay neutral; status remains badges; hidden raw provider/technical labels must not dominate the selector. ## OperationRun UX Impact N/A - no OperationRun start, completion, or link semantics touched. ## Provider Boundary / Platform Core Check - **Shared provider/platform boundary touched?**: yes, vocabulary only. - **Boundary classification**: platform-core selector wording. - **Seams affected**: visible labels and search matching over existing environment fields. - **Neutral platform terms preserved**: workspace, environment, active operating context. - **Provider-specific semantics retained and why**: none added. ## Proportionality Review - **New source of truth?**: no. - **New persisted entity/table/artifact?**: no. - **New abstraction?**: no. - **New enum/state/reason family?**: no. - **New cross-domain UI framework/taxonomy?**: no. - **Current operator problem**: overflow and poor scanability on the first environment-context decision. - **Existing structure is insufficient because**: the current dynamic grid produces columns too narrow for the Filament simple layout. - **Narrowest correct implementation**: one-page layout adjustment plus one local search property. - **Ownership cost**: one method and a few localized strings. - **Alternative intentionally rejected**: new reusable selector component; not justified by one page. - **Release truth**: current-release cleanup. ## Testing / Lane / Runtime Impact - **Test purpose / classification**: Feature. - **Validation lane(s)**: fast-feedback. - **Why sufficient**: The change is server-rendered Blade plus Livewire state; focused HTTP and Livewire Feature assertions prove visibility, filtering, and hidden raw label behavior. - **New or expanded test families**: none. - **Fixture/helper cost impact**: uses existing factories and `createUserWithTenant()`. - **Heavy-family visibility / justification**: no browser test added; in-app browser verification covers the visual regression for this task. - **Planned validation commands**: - `cd apps/platform && ./vendor/bin/sail artisan test tests/Feature/Workspaces/ChooseEnvironmentPageTest.php --compact` - `cd apps/platform && ./vendor/bin/sail pint app/Filament/Pages/ChooseEnvironment.php tests/Feature/Workspaces/ChooseEnvironmentPageTest.php` - `git diff --check` ## User Scenarios & Testing ### User Story 1 - Select an environment without layout ambiguity (P1) As a workspace operator, I need each environment row to stay readable at desktop, tablet, and mobile widths so I can safely choose the intended context. **Acceptance Criteria** 1. The chooser uses a single-column selector layout inside the Filament simple layout. 2. Raw `MANAGED_ENVIRONMENT` labels are not default-visible for ordinary managed environments. 3. Status remains shown as a small badge. ### User Story 2 - Find one environment in a larger workspace (P1) As an MSP/operator, I need search on the selector so I can narrow the list by environment name, domain, status, or visible context. **Acceptance Criteria** 1. Search filters the selectable environment collection without changing authorization scope. 2. The result count is visible while searching. 3. A no-results state provides a clear reset action. ### User Story 3 - Reach secondary context actions immediately (P2) As an operator, I need Add Environment and Switch Workspace visible near the top so I do not scroll past long environment lists for context-management actions. **Acceptance Criteria** 1. Secondary actions render in the selector header. 2. Actions use neutral styling and real routes. 3. No destructive action is introduced. ## Requirements - **FR-348-001**: The selector MUST not use dynamic two-/three-column grids inside the simple page container. - **FR-348-002**: Environment cards MUST include stable `data-testid` attributes for browser and feature assertions. - **FR-348-003**: Search MUST use Livewire v4-compatible debounced binding. - **FR-348-004**: Existing workspace/environment entitlement and operability checks MUST remain unchanged. - **FR-348-005**: The page MUST remain free of destructive/high-impact actions.