TenantAtlas/specs/085-tenant-operate-hub/research.md
ahmido 2bf5de4663 085-tenant-operate-hub (#103)
Summary

Consolidates the “Tenant Operate Hub” work (Spec 085) and the follow-up adjustments from the 086 session merge into a single branch ready to merge into dev.
Primary focus: stabilize Ops/Operate Hub UX flows, tighten/align authorization semantics, and make the full Sail test suite green.
Key Changes

Ops UX / Verification
Readonly members can view verification operation runs (reports) while starting verification remains restricted.
Normalized failure reason-code handling and aligned UX expectations with the provider reason-code taxonomy.
Onboarding wizard UX
“Start verification” CTA is hidden while a verification run is active; “Refresh” is shown during in-progress runs.
Treats provider_permission_denied as a blocking reason (while keeping legacy compatibility).
Test + fixture hardening
Standardized use of default provider connection fixtures in tests where sync/restore flows require it.
Fixed multiple Filament URL/tenant-context test cases to avoid 404s and reduce tenancy routing brittleness.
Policy sync / restore safety
Enrollment configuration type collision classification tests now exercise the real sync path (with required provider connection present).
Restore edge-case safety tests updated to reflect current provider-connection requirements.
Testing

vendor/bin/sail artisan test --compact (green)
vendor/bin/sail bin pint --dirty (green)
Notes

Includes merged 086 session work already (no separate PR needed).

Co-authored-by: Ahmed Darrazi <ahmeddarrazi@ebc83aaa-d947-4a08-b88e-bd72ac9645f7.fritz.box>
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@MacBookPro.fritz.box>
Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.fritz.box>
Reviewed-on: #103
2026-02-11 13:02:03 +00:00

4.0 KiB

Research: Tenant Operate Hub / Tenant Overview IA (Spec 085)

Date: 2026-02-09
Branch: 085-tenant-operate-hub
Spec: specs/085-tenant-operate-hub/spec.md

This research consolidates repo evidence + the final clarification decisions, so the implementation plan and tests can be deterministic.

Repository Evidence (high-signal)

  • Canonical monitoring pages already exist in the Admin panel:
    • Operations index: app/Filament/Pages/Monitoring/Operations.php
    • Run detail (tenantless viewer): app/Filament/Pages/Operations/TenantlessOperationRunViewer.php
    • Alerts: app/Filament/Pages/Monitoring/Alerts.php
    • Audit log: app/Filament/Pages/Monitoring/AuditLog.php
  • Tenant selection + clear tenant context already exist (UI + route/controller):
    • Context bar partial: resources/views/filament/partials/context-bar.blade.php
    • Tenant select controller: app/Http/Controllers/SelectTenantController.php

Decisions (resolved)

Decision: Tenant context may use last-tenant memory for cross-panel flows

  • Decision: “Tenant context is active” on Monitoring pages is resolved from the active Filament tenant when present, otherwise from the remembered last-tenant id for the current workspace.
  • Rationale: Central Monitoring routes are canonical and tenantless, but users enter them from the tenant panel and expect consistent scoping.
  • Alternatives considered:
    • Query param ?tenant=: rejected (would introduce an implicit switching vector).

Decision: “Show all tenants” explicitly exits tenant context

  • Decision: The CTA “Show all tenants” clears tenant context (single meaning) and returns the user to workspace-wide Monitoring.
  • Rationale: Prevents the confusing state where tenant context is still active but filters are reset.
  • Alternatives considered:
    • Only reset table filter: rejected (context remains active and confuses scope semantics).

Decision: Stale tenant context is handled without leaks

  • Decision: If tenant context is active but the user is no longer entitled to that tenant, Monitoring pages behave as workspace-wide:
    • Scope shows Workspace — all tenants
    • No tenant name is shown
    • No “Back to tenant” is rendered
    • Tenant pages remain deny-as-not-found
  • Rationale: Preserves deny-as-not-found and avoids tenant existence hints.
  • Alternatives considered:
    • 404 the Monitoring page: rejected (feels like being “thrown out”).
    • Auto-clear tenant context implicitly: rejected (implicit context mutation).

Decision: Run detail shows an explicit tenant return + secondary escape hatch

  • Decision: When tenant context is active and entitled, run detail shows:
    • ← Back to <tenant name> (tenant dashboard)
    • secondary Show all operations/admin/operations
  • Rationale: “Back to tenant” is deterministic; the secondary link provides a canonical escape hatch.
  • Alternatives considered:
    • Only show Back to tenant: rejected by clarification (secondary escape hatch approved).

Decision: Tenant panel navigation uses a “Monitoring” group with central shortcuts

  • Decision: Replace the tenant-panel “Operations” item with group “Monitoring” containing shortcuts:
    • Runs → /admin/operations
    • Alerts → /admin/alerts
    • Audit Log → /admin/audit-log
  • Rationale: Keep tenant sidebar labels minimal while still providing correct central Monitoring entry points, while preserving canonical URLs and avoiding tenant-scoped monitoring routes.
  • Alternatives considered:
    • New tenant-scoped monitoring routes: rejected (explicitly forbidden).

Decision: “No outbound calls on render” is enforced by tests

  • Decision: Monitoring GET renders must not trigger outbound network calls or start background work as a side effect.
  • Rationale: Aligns with constitution (“Monitoring pages MUST be DB-only at render time”).
  • Alternatives considered:
    • Rely on convention: rejected; this needs regression protection.

Open Questions

None remaining for Phase 0. The spec clarifications cover all scope-affecting ambiguities.