# Phase 0 Research — Provider Connections (Tenantless UI) **Branch**: `089-provider-connections-tenantless-ui` **Date**: 2026-02-12 This document resolves planning unknowns and records decisions with rationale. ## Findings (Repo Reality) - Provider connections already exist as a Filament resource with a tenant-scoped slug. - The app has a concept of an active workspace context (session-selected) and an active tenant context. - Workspace membership and tenant membership are treated as hard isolation boundaries (deny-as-not-found 404). - There are existing patterns for: - Query scoping by workspace + tenant membership - UI enforcement (disabled actions + tooltips) with server-side 403 enforcement - Audit logging (AuditLog) for state changes - OperationRun for observable run/health operations - Legacy redirect precedent (tenant-scoped → tenantless) for Operations ## Decisions ### D1 — Canonical routing (tenantless) **Decision**: Provider Connections will move to a canonical tenantless admin route: `/admin/provider-connections`. **Rationale**: Removes fragile tenant-route coupling, matches enterprise IA, and simplifies testing. **Alternatives considered**: - Keep tenant-scoped slug and add more navigation shortcuts. - Create a separate “workspace integrations” page and keep resource tenant-scoped. ### D2 — MVP provider scope **Decision**: MVP supports Microsoft (Graph) as the only provider; UI/IA remains generic “Provider Connections”. **Rationale**: Reduces scope while keeping the data model/provider column future-proof. **Alternatives considered**: - Rename IA to “Microsoft Graph Connections” (more precise but less extensible). - Support multiple providers in MVP (expensive and not required for current goal). ### D3 — Tenant context default filtering **Decision**: Default tenant filter resolves from active TenantContext (session/context switcher). If `tenant_id` is present in the query string, it takes precedence. **Rationale**: Matches existing tenant-context behavior across tenantless pages while enabling deep links (e.g., from tenant detail) without special referrer logic. **Alternatives considered**: - Only querystring (no session context) → worse UX and inconsistent with app patterns. - Persist per-page last filter only → adds state complexity and surprise. ### D4 — Zero-leak scoping strategy (JOIN-based) **Decision**: ProviderConnections list/query will be scoped using query-time membership joins (workspace + tenant), not large in-memory ID lists. **Rationale**: Supports MSP scale and avoids `whereIn([ids])` lists. **Alternatives considered**: - Load entitled tenant IDs in PHP and apply `whereIn` → doesn’t scale. ### D5 — Global search **Decision**: Provider Connections will not appear in Global Search. **Rationale**: Global search is a high-leak vector for cross-tenant metadata previews; navigation placement makes search unnecessary. **Alternatives considered**: - Enable global search with strict scoping → still increases risk surface and complexity. ### D6 — Auditability **Decision**: Manage/state-change actions write an AuditLog entry. Run/health actions create an OperationRun with canonical “view run” link. **Rationale**: Aligns with constitution: state changes are auditable and operations are observable. **Alternatives considered**: - Only AuditLog → loses operational traceability for runs. - Only OperationRun → weaker governance for state change events. ## Open Questions None remaining for planning. Implementation will confirm exact join table names and reuse existing scoping helpers.