TenantAtlas/specs/121-workspace-switch-fix/plan.md
2026-03-08 01:55:28 +01:00

8.4 KiB

Implementation Plan: Workspace Switch Semantic Fix

Branch: 121-workspace-switch-fix | Date: 2026-03-07 | Spec: 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)

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

Source Code (repository root)

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 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:

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.