TenantAtlas/specs/077-workspace-nav-monitoring-hub/spec.md

13 KiB
Raw Blame History

Feature Specification: Workspace-first Navigation & Monitoring Hub

Feature Branch: 077-workspace-nav-monitoring-hub
Created: 2026-02-06
Status: Draft
Input: User description: "Workspace-first navigation and monitoring hub for an enterprise admin suite: remove workspace navigation ambiguity, lock canonical operations deep links, apply tenant context only as default filters, and enforce strict 404/403 access semantics without information leakage."

Clarifications

Session 2026-02-06

  • Q: What is the authorization plane + status-code rule for /admin/workspaces ("Manage workspaces")? → A: Tenant plane (/admin, Entra users). Workspace management is workspace-scoped: non-members receive 404 (deny-as-not-found); members missing required capabilities receive 403.
  • Q: How should the tenant-context default filter on /admin/operations be implemented? → A: Server-side default state with a removable filter chip; URL remains /admin/operations.
  • Q: What happens when a user visits a workspace-scoped page (e.g. /admin/operations) with no current_workspace_id selected? → A: Redirect to /admin/choose-workspace and return to the originally requested URL after selection.
  • Q: If tenant context is active but the tenant is not in the current workspace (e.g., user switches workspaces), what should happen? → A: Auto-clear tenant context and continue on tenantless workspace pages.

User Scenarios & Testing (mandatory)

User Story 1 - Switch workspace without ambiguity (Priority: P1)

As an operator/admin, I need to switch my active workspace (portfolio) using a clear, single-purpose entry point, so that I never confuse "switch workspace" with "manage workspaces".

Why this priority: Workspace context is foundational. If its confusing, every other module becomes harder to use and support.

Independent Test: A user can find "Switch workspace", select a workspace they are a member of, and the application context updates while workspace management remains separate.

Acceptance Scenarios:

  1. Given I am signed in and belong to multiple workspaces, When I choose "Switch workspace", Then I see only workspaces I am a member of and can select one.
  2. Given I can manage workspaces, When I open "Manage workspaces", Then I can access workspace CRUD screens and breadcrumbs stay within the management area.
  3. Given I cannot manage workspaces, When I look at navigation, Then I do not see "Manage workspaces".

User Story 2 - Use Monitoring hub from canonical links (Priority: P2)

As an operator, I need monitoring pages (starting with Operations) to be reachable via stable, shareable links that never depend on tenant context, so that support, alerts, and notifications can deep-link reliably.

Why this priority: Monitoring must be dependable across contexts; deep links are critical for incident response and support.

Independent Test: Visiting the canonical operations URLs works with and without tenant context, and the system enforces membership checks.

Acceptance Scenarios:

  1. Given I am a member of a workspace, When I visit /admin/operations, Then I can view a workspace-wide list of operations.
  2. Given I have an active tenant context, When I visit /admin/operations, Then operations are pre-filtered to that tenant but the URL remains /admin/operations.
  3. Given I have a run link /admin/operations/{run}, When I open it, Then I see the run detail regardless of tenant context.

User Story 3 - Navigate and search without leaking inaccessible data (Priority: P3)

As a user, I should never learn about workspaces/tenants/runs I cannot access through navigation labels, breadcrumbs, counts, or global search results.

Why this priority: Preventing information leakage is a core enterprise requirement and reduces risk in multi-tenant MSP environments.

Independent Test: An unauthorized user receives not-found responses for out-of-scope resources and does not see them in search.

Acceptance Scenarios:

  1. Given I am not a member of a workspace, When I attempt to access that workspaces monitoring data or runs, Then I receive a not-found response.
  2. Given I am a workspace member but lack a capability for a protected workspace-scoped screen or action, When I attempt to access it directly, Then I receive a forbidden response.
  3. Given I use global search, When I search for entities outside my scope, Then they do not appear in results (no partial hints).

Edge Cases

  • User is a member of zero workspaces.
  • User loses workspace membership while having an active session.
  • Tenant context is active but the tenant does not belong to the current workspace.
  • A run is referenced by an external deep link after it was deleted or moved.
  • User can view monitoring but cannot perform mutations (e.g., cancel/retry) if those actions exist.

Requirements (mandatory)

Constitution alignment (required): This feature changes navigation and authorization behavior but does not introduce new external API calls or background jobs. Any mutation actions added later (e.g., cancel/retry) must follow the platforms safety gates (confirmation/audit) and be covered by authorization tests.

Constitution alignment (RBAC-UX):

  • Authorization plane(s) involved:
    • Tenant plane (Entra users) only.
    • Platform plane (/system) is out of scope for this feature.
  • Authorization planes:
    • Workspace-level pages (e.g., monitoring hub, workspace management) are governed by workspace membership and workspace capabilities.
    • Tenant context is secondary and must not change canonical routing for monitoring pages.
  • Isolation model note (workspace scope):
    • “Workspace-scoped” monitoring is an explicit, access-checked aggregation scope over the managed tenants that belong to the selected workspace.
    • All reads remain bounded to the current workspace; there is no cross-workspace monitoring view in this feature.
  • 404 vs 403 semantics (strict):
    • Non-member / not entitled to the workspace scope → 404 (deny-as-not-found)
    • Workspace member but missing the required capability for a protected screen/action → 403
  • Server-side enforcement: Navigation visibility must not be treated as authorization; all access control is enforced on the server for every protected page and every mutation.
  • Global search non-leakage: Global search must not show titles, counts, or partial matches for inaccessible workspaces/tenants/runs. Inaccessible entities behave as not-found.

Functional Requirements

  • FR-001 (One label, one meaning): The application MUST provide two distinct, clearly-labeled entry points:

    • "Switch workspace" for selecting the active workspace context.
    • "Manage workspaces" for workspace CRUD/administration.
  • FR-002 (Canonical workspace switch route): "Switch workspace" MUST navigate to /admin/choose-workspace.

  • FR-003 (Canonical workspace management route): "Manage workspaces" MUST navigate to /admin/workspaces and MUST NOT be labeled simply "Workspaces".

  • FR-004 (Breadcrumb correctness): Breadcrumbs in workspace management MUST point back to /admin/workspaces and must not send users to the workspace switcher.

  • FR-005 (Monitoring is workspace-level): Monitoring pages MUST be workspace-scoped and reachable without tenant context.

  • FR-006 (Canonical Operations URLs): Operations MUST remain canonical and tenantless:

    • index: /admin/operations
    • detail: /admin/operations/{run}
  • FR-007 (Tenant context affects defaults, not routing): If tenant context is active, the operations index MUST default to showing runs for that tenant using server-side default filter state, and users MUST be able to clear that default to view workspace-wide operations. The canonical URL MUST remain /admin/operations and the default MUST present a visible, removable filter chip (no required querystring parameters).

  • FR-008 (Tenant shortcut to operations): Tenant detail screens MUST offer a "Recent operations" summary and a "View all operations" call-to-action that leads to the canonical operations index.

  • FR-009 (Membership gating): Users MUST be a member of a workspace to access workspace-scoped pages. Non-members MUST receive a not-found response.

  • FR-010 (Capability gating for management): Workspace-scoped management/mutations MUST be restricted to users with the appropriate capability/capabilities (from the canonical registry). Unauthorized workspace members MUST receive a forbidden response.

    • Canonical capabilities used by this feature:
      • workspace.manage (Capabilities::WORKSPACE_MANAGE): create/edit workspace fields.
      • workspace_membership.manage (Capabilities::WORKSPACE_MEMBERSHIP_MANAGE): add/remove members and change roles.
  • FR-011 (Monitoring hub IA): The sidebar MUST provide a "Monitoring" area that is the canonical home for Operations now, with reserved surfaces for future Alerts and Audit Log.

  • FR-012 (Deep-link stability): Any monitoring entity intended for support workflows MUST have a stable deep link that does not depend on tenant context.

  • FR-013 (No workspace selected): If a user visits a workspace-scoped page without a selected workspace context, the system MUST redirect to /admin/choose-workspace and then return the user to their originally requested URL after a successful selection.

  • FR-014 (Invalid tenant context): If tenant context is active but the tenant does not belong to the current workspace, the system MUST auto-clear tenant context and continue on workspace-level pages without tenant scoping.

  • FR-077-016 (Header context bar): The header MUST provide an always-available context bar for Suite navigation:

    • FR-077-016-A (Workspace visible): If a workspace is selected, show Workspace: <name> and allow the user to open the existing workspace switcher (/admin/choose-workspace).
    • FR-077-016-B (Tenant accessible on tenantless pages): The header MUST surface tenant context even on tenantless pages (e.g., /admin/operations). If there is an active tenant context, show Tenant: <tenant name> (fallback to a safe identifier). If there is no active tenant but there is a last-selected tenant in the current workspace session, show it.
    • FR-077-016-C (No implicit switching): Canonical pages MUST NOT silently switch tenant or workspace. The context bar is an explicit control only.
    • FR-077-016-D (No leakage): Tenant picker contents MUST include only tenants the user is entitled to view within the current workspace. Unauthorized tenant selection via direct URL MUST remain deny-as-not-found (404).
    • FR-077-016-E (Filament-native): Implementation MUST use Filament v5 mechanisms (topbar/user-menu render hooks + Filament tenancy) and Livewire v4 where needed.

Key Entities (include if feature involves data)

  • Workspace: Primary context container for a customer/portfolio.
  • Workspace Membership: The relationship that entitles a user to a workspace.
  • Managed Tenant: Secondary context within a workspace; used for scoping defaults and tenant workflows.
  • Operation Run: A record representing an operational execution that belongs to a workspace and may be associated with a tenant.
  • Capability: A named permission that gates management/mutation behavior.

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001 (Reduced confusion): In a moderated test with new users, at least 90% correctly choose the right destination (switch vs manage) on first attempt.
  • SC-002 (Faster workspace switching): Users can switch to a known workspace in under 15 seconds without using search.
  • SC-003 (Reliable deep links): Support can open /admin/operations/{run} successfully regardless of tenant context in 100% of tested cases.
  • SC-004 (No leakage regressions): Security regression tests confirm 0 instances of inaccessible workspaces/tenants/runs appearing in navigation or global search.

Acceptance details (pinned)

Recent operations summary (FR-008)

  • Show the most recent 5 operation runs for the current tenant, ordered by created_at descending (fallback: id descending).
  • Display, at minimum: type (label), status, outcome, created_at (or since), and a link to the run detail.
  • Provide a "View all operations" CTA that navigates to canonical /admin/operations (no tenant prefix / no required query params).

Header context bar (FR-077-016)

  • The header shows a stable, compact context bar:
    • Workspace: <name> (clickable)
    • Tenant: <name> (picker)
  • Tenant picker is available on tenantless pages.
  • No automatic tenant selection occurs when opening canonical URLs.

Mandatory Tests (pinned)

  • T-077-016-1 (Tenant dropdown on tenantless pages): With a selected workspace and an active tenant context, visiting /admin/operations shows the tenant picker and selecting a tenant navigates to tenant home.
  • T-077-016-2 (Security filtering): Only entitled tenants within the current workspace appear in the picker; posting /navigating to an unauthorized tenant results in 404.
  • T-077-016-3 (No implicit switching): Visiting /admin/operations/{run} from a deep link MUST NOT auto-switch tenant.