# Tasks: Provider Connections (Tenantless UI + Tenant Transparency) **Input**: Design documents from `specs/089-provider-connections-tenantless-ui/` **Prerequisites**: plan.md (required), spec.md (required), research.md, data-model.md, contracts/ **Tests**: Required (Pest) — this feature changes runtime auth + routing. --- ## Phase 1: Setup (Shared Infrastructure) - [X] T001 Confirm spec artifacts present in specs/089-provider-connections-tenantless-ui/{spec,plan,research,data-model,quickstart,tasks}.md - [X] T002 [P] Validate existing provider capabilities exist in app/Support/Auth/Capabilities.php (PROVIDER_VIEW/PROVIDER_MANAGE/PROVIDER_RUN) - [X] T003 [P] Inventory existing Provider Connections routes/actions and update the UI Action Matrix in specs/089-provider-connections-tenantless-ui/spec.md (anchor to app/Filament/Resources/ProviderConnectionResource.php) --- ## Phase 2: Foundational (Blocking Prerequisites) - [X] T004 Define tenant-context default filter precedence contract for Provider Connections (query `tenant_id` overrides session TenantContext) in app/Filament/Resources/ProviderConnectionResource.php - [X] T005 Implement JOIN-based tenant-membership scoping query helper for Provider Connections in app/Filament/Resources/ProviderConnectionResource.php (no large in-memory tenant-id lists) - [X] T006 Ensure non-workspace member access is deny-as-not-found (404) for Provider Connections surfaces via existing middleware/policy wiring (verify and adjust in app/Policies/ProviderConnectionPolicy.php and panel middleware if needed) - [X] T007 Create baseline authorization regression tests for 404 vs 403 semantics in tests/Feature/ProviderConnections/AuthorizationSemanticsTest.php **Checkpoint**: Foundation ready (tenant resolution, scoping approach, baseline auth tests). --- ## Phase 3: User Story 1 — Workspace-weite Übersicht (Priority: P1) 🎯 MVP **Goal**: Canonical tenantless route + central navigation placement + tenant transparency on list with safe scoping and default filtering. **Independent Test**: Workspace member sees only entitled tenant rows at `/admin/provider-connections`, default filter respects TenantContext, `?tenant_id=` overrides, non-workspace member gets 404. ### Tests (write first) - [X] T008 [P] [US1] Add feature test for canonical list route 404 for non-workspace member in tests/Feature/ProviderConnections/TenantlessListRouteTest.php - [X] T009 [P] [US1] Add feature test for scoping: member of Tenant A not Tenant B sees only A rows in tests/Feature/ProviderConnections/TenantlessListScopingTest.php - [X] T010 [P] [US1] Add feature test for `tenant_id` query override (authorized tenant shows rows; unauthorized tenant shows 0 rows) in tests/Feature/ProviderConnections/TenantFilterOverrideTest.php ### Implementation - [X] T011 [US1] Change canonical Filament resource slug to tenantless in app/Filament/Resources/ProviderConnectionResource.php (from `tenants/{tenant}/provider-connections` to `provider-connections`) - [X] T012 [US1] Update Provider Connections navigation placement in app/Filament/Resources/ProviderConnectionResource.php (group: `Settings`, subgroup: `Integrations`, label: `Provider Connections`) - [X] T013 [US1] Update ProviderConnectionResource::getUrl behavior in app/Filament/Resources/ProviderConnectionResource.php to stop inferring `{tenant}` path params and instead support tenant filter via query string - [X] T014 [US1] Update ProviderConnectionResource::getEloquentQuery() in app/Filament/Resources/ProviderConnectionResource.php to allow tenantless list + record access while enforcing workspace + tenant membership scoping at query time - [X] T015 [US1] Update list query scoping in app/Filament/Resources/ProviderConnectionResource.php to: workspace-scope + membership join + optional tenant filter (`tenant_id` query > TenantContext default) - [X] T016 [US1] Add required tenant transparency columns + filters in app/Filament/Resources/ProviderConnectionResource.php (Tenant column with deep link to Tenant view + Tenant filter) - [X] T017 [US1] Add required list columns for last error reason/message in app/Filament/Resources/ProviderConnectionResource.php (reason code + truncated message, sanitized) - [X] T018 [US1] Ensure list has a clear inspection affordance and action-surface contract compliance in app/Filament/Resources/ProviderConnectionResource.php (prefer `recordUrl()` clickable rows; keep max 2 visible row actions) - [X] T019 [US1] Add meaningful empty state + CTA behavior to app/Filament/Resources/ProviderConnectionResource/Pages/ListProviderConnections.php ### Legacy redirect - [X] T020 [US1] Add legacy redirects for workspace-managed tenant routes in routes/web.php (302 only for entitled members; otherwise 404; no Location leaks): `/admin/tenants/{tenant:external_id}/provider-connections` → `/admin/provider-connections?tenant_id={tenant_external_id}`, `/admin/tenants/{tenant:external_id}/provider-connections/create` → `/admin/provider-connections/create?tenant_id={tenant_external_id}`, `/admin/tenants/{tenant:external_id}/provider-connections/{record}/edit` → `/admin/provider-connections/{record}/edit?tenant_id={tenant_external_id}` - [X] T021 [P] [US1] Add legacy redirect tests in tests/Feature/ProviderConnections/LegacyRedirectTest.php (302 for entitled; 404 for non-workspace/non-tenant members; assert no Location header for 404 cases; assert `/admin/t/{tenant_external_id}/provider-connections` remains 404 and does not redirect) **Checkpoint**: US1 delivers canonical tenantless list + safe scoping + redirect. --- ## Phase 4: User Story 2 — Sicherer Detail-/Edit-Zugriff ohne Secrets (Priority: P2) **Goal**: Secure view/edit + actions gated by capability; non-member 404; member missing capability 403; no plaintext secrets. **Independent Test**: Direct record access behaves as spec (404/403), manage actions are confirmed + audited, run actions create OperationRun, secrets never displayed. ### Tests (write first) - [X] T022 [P] [US2] Add feature test: non-tenant member direct record access is 404 in tests/Feature/ProviderConnections/RecordAccessNotFoundTest.php - [X] T023 [P] [US2] Add feature test: tenant member missing Capabilities::PROVIDER_VIEW gets 403 for list/detail in tests/Feature/ProviderConnections/CapabilityForbiddenTest.php (no raw capability strings) - [X] T024 [P] [US2] Add feature test: tenant member missing Capabilities::PROVIDER_MANAGE cannot mutate (403) in tests/Feature/ProviderConnections/ManageCapabilityEnforcementTest.php (no raw capability strings) ### Implementation - [X] T025 [US2] Add a Provider Connection View page (required for “detail” semantics) in app/Filament/Resources/ProviderConnectionResource/Pages/ViewProviderConnection.php and register it in app/Filament/Resources/ProviderConnectionResource.php getPages() - [X] T026 [US2] Update record routes to tenantless paths in app/Filament/Resources/ProviderConnectionResource.php and related Pages/* so record URLs no longer depend on `{tenant}` - [X] T027 [US2] Update authorization semantics (404 for non-members; 403 for missing capability; viewAny/view=Capabilities::PROVIDER_VIEW; create/update/delete=Capabilities::PROVIDER_MANAGE) in app/Policies/ProviderConnectionPolicy.php - [X] T028 [US2] Update Edit page tenant resolution to prefer record’s tenant (not route tenant) in app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php - [X] T029 [US2] Update Create page to require explicit tenant selection (query `tenant_id` or context default) in app/Filament/Resources/ProviderConnectionResource/Pages/CreateProviderConnection.php (abort 404 if no entitled tenant can be resolved) - [X] T030 [US2] Ensure all destructive-like/manage actions require confirmation in app/Filament/Resources/ProviderConnectionResource.php and app/Filament/Resources/ProviderConnectionResource/Pages/EditProviderConnection.php (enable/disable, set default, credential updates) - [X] T031 [US2] Ensure manage actions write AuditLog using the correct logger (tenant/workspace as appropriate) and do not include secrets in context (review and adjust in app/Filament/Resources/ProviderConnectionResource.php and Pages/EditProviderConnection.php) - [X] T032 [US2] Ensure run/health actions create/reuse OperationRun and link to canonical viewer (verify OperationRunLinks tenantless path usage in app/Filament/Resources/ProviderConnectionResource.php and Pages/EditProviderConnection.php) - [X] T033 [US2] Ensure UI never renders plaintext secrets and provides no secret copy affordances (confirm forms/columns in app/Filament/Resources/ProviderConnectionResource.php) **Checkpoint**: US2 secures detail/edit surfaces + action gating + confirmations. --- ## Phase 5: User Story 3 — Tenant-Detailseite zeigt effektiven Provider-State + Deep Link (Priority: P3) **Goal**: Tenant view shows effective default provider connection state and links to tenant-filtered canonical list. **Independent Test**: Tenant view displays default connection summary and CTA to `/admin/provider-connections?tenant_id=`. ### Tests (write first) - [X] T034 [P] [US3] Add feature test asserting tenant view contains CTA URL to canonical provider connections with tenant_id in tests/Feature/Tenants/TenantProviderConnectionsCtaTest.php ### Implementation - [X] T035 [US3] Update tenant header action URL to tenantless canonical list in app/Filament/Resources/TenantResource/Pages/ViewTenant.php (use `/admin/provider-connections?tenant_id={external_id}` semantics) - [X] T036 [US3] Add “Provider connection” effective state section to the tenant infolist in app/Filament/Resources/TenantResource.php (display name, status/health, last check; show needs-action state if missing) - [X] T037 [US3] Add a dedicated infolist entry view for the provider connection state in resources/views/filament/infolists/entries/provider-connection-state.blade.php **Checkpoint**: US3 completes tenant transparency from tenant detail. --- ## Phase 6: Polish & Cross-Cutting Concerns - [X] T038 [P] Run targeted test suite for Provider Connections changes: `vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections` (add notes to specs/089-provider-connections-tenantless-ui/quickstart.md if paths differ) - [X] T039 [P] Run formatting and fix any findings in app/** and tests/** using `vendor/bin/sail bin pint --dirty` - [X] T040 Review navigation grouping consistency for Settings → Integrations in app/Providers/Filament/AdminPanelProvider.php (ensure Provider Connections appears where spec requires) - [X] T041 Validate that Provider Connections remains excluded from global search in app/Filament/Resources/ProviderConnectionResource.php - [X] T042 [P] Add regression test asserting disabled actions render with helper text/tooltip for tenant members missing capability (UI enforcement) in tests/Feature/ProviderConnections/DisabledActionsTooltipTest.php (or add an explicit exemption in specs/089-provider-connections-tenantless-ui/spec.md if not feasible) - [X] T043 [P] Add regression test asserting required list filters exist and behave (Provider, Status, Health, Default-only) in tests/Feature/ProviderConnections/RequiredFiltersTest.php - [X] T044 [P] Add regression test asserting MVP provider scope remains Microsoft-only (no non-Microsoft provider options exposed) in tests/Feature/ProviderConnections/MvpProviderScopeTest.php --- ## Dependencies & Execution Order - Setup (T001–T003) → Foundational (T004–T007) → US1 (T008–T021) → US2 (T022–T033) → US3 (T034–T037) → Polish (T038–T044) ```mermaid graph TD P1[Phase 1: Setup] --> P2[Phase 2: Foundational] P2 --> US1[US1: Tenantless List] P2 --> US2[US2: Secure View/Edit] P2 --> US3[US3: Tenant View State] US1 --> Polish[Phase 6: Polish] US2 --> Polish US3 --> Polish ``` ## Parallel Execution Examples ### US1 - Run in parallel: - T008, T009, T010 (tests) - T020 + T021 (redirect + test) can be done alongside T011–T019 once slug decision is finalized ### US2 - Run in parallel: - T022–T024 (tests) - T025 (View page scaffolding) and T027 (policy fixes) can be developed independently ### US3 - Run in parallel: - T034 (test) and T037 (Blade entry view) while T036 changes TenantResource infolist ## Implementation Strategy - MVP = US1 only (canonical tenantless list + safe scoping + legacy redirect). - Add US2 next (secure detail/edit + action confirmations + audit/run correctness). - Add US3 last (tenant view effective-state + CTA).