3.6 KiB
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.