# Implementation Plan: Workspace Switch Semantic Fix

**Branch**: `121-workspace-switch-fix` | **Date**: 2026-03-07 | **Spec**: [spec.md](./spec.md)
**Input**: Feature specification from `/specs/121-workspace-switch-fix/spec.md`

## Summary

Correct the context-bar `Switch workspace` affordance so it uses the canonical chooser flow and remains the only workspace-switching affordance. The implementation will keep the topbar partial targeting `ChooseWorkspace::getUrl(panel: 'admin').'?choose=1'`, remove the duplicate admin user-menu shortcut, preserve the current chooser redirect behavior (`WorkspaceIntendedUrl` / `WorkspaceRedirectResolver`), and leave workspace management reachable only through its separate administrative navigation path. Validation stays focused on response-level topbar rendering plus regression coverage that management navigation and chooser semantics remain distinct.

## Technical Context

**Language/Version**: PHP 8.4.15 / Laravel 12  
**Primary Dependencies**: Filament v5 + Livewire v4.0+ + Tailwind CSS v4  
**Storage**: PostgreSQL + session-backed workspace context; no schema changes  
**Testing**: Pest v4 feature tests (HTTP response assertions and existing workspace flow regression tests)  
**Target Platform**: Web admin and tenant panels (`/admin`, `/admin/t/...`) running in Laravel Sail / container deployment  
**Project Type**: Laravel monolith / Filament web application  
**Performance Goals**: No additional remote calls or new query paths; topbar render remains effectively unchanged except for link destination  
**Constraints**: Preserve existing RBAC and workspace isolation rules; preserve chooser post-selection behavior; avoid hardcoded management URLs for switch intent; keep workspace switching in context surfaces rather than account surfaces; no CRUD behavior changes  
**Scale/Scope**: One context-bar Blade partial, one admin panel provider cleanup, plus targeted workspace/navigation tests; no data migration, no new services, no new routes

## Constitution Check

*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*

- Inventory-first: PASS (feature only changes navigation semantics; no inventory or backup semantics affected).
- Read/write separation: PASS (no new writes or mutations introduced; chooser selection behavior remains existing behavior).
- Graph contract path: PASS (no Microsoft Graph calls; all affected surfaces are DB/session-only).
- Deterministic capabilities: PASS (no new capabilities; existing workspace membership and management capability rules remain canonical).
- RBAC-UX: PASS (feature stays in `/admin`; non-member and capability behavior are unchanged because only the destination link changes).
- Workspace isolation: PASS (`?choose=1` intentionally forces the chooser while preserving existing workspace membership enforcement and post-selection resolution).
- Destructive confirmation: PASS / N/A (no destructive actions are added or changed).
- Global search: PASS / N/A (no global search behavior changes).
- Tenant isolation: PASS (chooser and management separation remains explicit; no tenant data exposure changes).
- Run observability: PASS / N/A (no long-running or operational work; no `OperationRun` usage).
- Ops-UX 3-surface feedback: PASS / N/A (no operation lifecycle involved).
- Automation: PASS / N/A (no scheduled or queued work).
- Data minimization: PASS (no new persisted data or logging payloads).
- Badge semantics (BADGE-001): PASS / N/A (no new status-like badges).
- Filament UI Action Surface Contract: PASS with exemption note. The affected surface is a topbar/context-bar navigation link, not a CRUD Resource/RelationManager/Page action surface.
- Filament UI UX-001: PASS with exemption note. The feature preserves the existing chooser page and does not alter Create/Edit/View layouts.

## Project Structure

### Documentation (this feature)

```text
specs/121-workspace-switch-fix/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
│   └── routes.md
└── tasks.md
```

### Source Code (repository root)

```text
app/
├── Filament/
│   └── Pages/
│       └── ChooseWorkspace.php                 # reference-only canonical chooser
├── Http/
│   └── Middleware/
│       └── EnsureWorkspaceSelected.php         # reference-only forced chooser semantics
├── Providers/
│   └── Filament/
│       └── AdminPanelProvider.php              # MODIFY — remove duplicate user-menu switch shortcut
└── Support/
    └── Workspaces/
        ├── WorkspaceIntendedUrl.php            # reference-only existing post-selection flow
        └── WorkspaceRedirectResolver.php       # reference-only existing post-selection flow

resources/
└── views/
    └── filament/
        └── partials/
            └── context-bar.blade.php           # MODIFY — switch link target

tests/
└── Feature/
    ├── Monitoring/
    │   └── HeaderContextBarTest.php            # MODIFY — assert chooser target from context bar
    └── Workspaces/
        ├── WorkspaceSwitchUserMenuTest.php     # MODIFY — assert user menu no longer exposes workspace switching
        ├── ChooseWorkspacePageTest.php         # reference or extend — management remains reachable
        └── WorkspaceNavigationHubTest.php      # reference-only IA separation guard
```

**Structure Decision**: Keep the change inside the existing Laravel/Filament monolith. Implementation is a narrowly scoped view-level routing correction backed by targeted Pest feature tests and existing workspace chooser/navigation helpers.

## Complexity Tracking

> No Constitution Check violations. No justifications needed.

| Violation | Why Needed | Simpler Alternative Rejected Because |
|-----------|------------|-------------------------------------|
| — | — | — |

## Phase 0 — Research (output: `research.md`)

See: [research.md](./research.md)

Research goals:
- Confirm the canonical workspace-switch destination and whether forced chooser semantics require `?choose=1`.
- Confirm whether chooser post-selection redirect behavior should remain unchanged.
- Confirm the smallest reliable test surface for a context-bar-only switch rule plus management-navigation regression coverage.

## Phase 1 — Design & Contracts (outputs: `data-model.md`, `contracts/`, `quickstart.md`)

See:
- [data-model.md](./data-model.md)
- [contracts/routes.md](./contracts/routes.md)
- [quickstart.md](./quickstart.md)

Design focus:
- Treat the context-bar link as a pure navigation contract update, not a behavior rewrite.
- Reuse the existing chooser page and `?choose=1` forced-chooser convention to preserve manual switching semantics.
- Remove the duplicate user-menu shortcut so workspace switching stays anchored to the context bar.
- Preserve existing management navigation, chooser redirect resolution, and capability boundaries unchanged.
- Validate the semantic split with response-level topbar assertions plus regression checks around management reachability.

## Phase 2 — Implementation Outline (tasks created in `/speckit.tasks`)

### UI routing correction
- Replace the context-bar `Switch workspace` link target in `context-bar.blade.php`.
- Use the canonical chooser helper (`ChooseWorkspace::getUrl(panel: 'admin')`) with the forced chooser query parameter.
- Keep the link as navigation-only; no action/mutation flow is added.
- Remove the duplicate Filament user-menu switch action from the admin panel provider.

### Regression protection
- Extend the real rendered topbar test to assert the context-bar switch link points at the chooser URL rather than workspace CRUD.
- Update user-menu coverage to assert no workspace-switch shortcut is registered there.
- Reuse or mirror existing workspace chooser tests to prove management navigation remains separate and accessible through its dedicated path.
- Keep existing middleware/chooser tests as the source of truth for post-selection branching.

### Verification
- Run focused Pest coverage for context bar + workspace navigation semantics.
- Run Pint on dirty files through Sail.

## Constitution Check (Post-Design)

Re-check result: PASS. The design keeps workspace switching and workspace management semantically separate, reuses the existing chooser and middleware contract, introduces no new authorization rules or operational flows, and limits the implementation to a navigation target correction plus regression tests.
