4.4 KiB
Implementation Plan: Remove Legacy Tenant Graph Options
Branch: 088-remove-tenant-graphoptions-legacy | Date: 2026-02-11 | Spec: spec.md
Input: Feature specification in spec.md
Summary
Hard cut removal of the deprecated tenant-based Graph options accessor. All Microsoft Graph configuration must be derived exclusively from a resolved ProviderConnection via ProviderConnectionResolver::resolveDefault() and ProviderGateway::graphOptions(). Add a CI guardrail scanning app/ for $tenant->graphOptions() / Tenant::graphOptions() and implement a kill-switch by making Tenant::graphOptions() throw.
Technical Context
Language/Version: PHP 8.4.15 (Laravel 12)
Primary Dependencies: Filament v5, Livewire v4, Pest v4
Storage: PostgreSQL (Sail locally)
Testing: Pest via vendor/bin/sail artisan test --compact
Target Platform: Containerized Linux deployment (Sail local, Dokploy staging/prod)
Project Type: Laravel web application (monolith)
Performance Goals: N/A (internal refactor + CI guard)
Constraints:
- No fallback to tenant-stored credentials.
- Guardrail scans
app/only (do not fail due totests/). - No new Graph endpoints; Graph calls remain routed through
GraphClientInterface. Scale/Scope: Repo-wide refactor of call sites inapp/Services/**.
Constitution Check
GATE: Must pass before implementation. Re-check after design decisions.
- Inventory-first / snapshots: N/A (no inventory/snapshot semantics change)
- Read/write separation: PASS (no new write surfaces; existing flows only refactored)
- Single contract path to Graph: PASS (Graph calls remain through
GraphClientInterface; only options sourcing changes) - Deterministic capabilities: N/A (no capability mapping changes)
- RBAC-UX / workspace isolation / tenant isolation: N/A (no routing or authorization semantic changes)
- Run observability: N/A (no new operations or run tracking changes)
- Data minimization / safe logging: PASS (no secrets introduced; provider credentials remain in credential store)
- Filament UI Action Surface Contract: N/A (no UI resources/pages are added or modified)
Project Structure
Documentation (this feature)
specs/088-remove-tenant-graphoptions-legacy/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
└── tasks.md # created by /speckit.tasks (later)
Source Code (repository root)
app/
├── Models/
│ └── Tenant.php
├── Services/
│ ├── Providers/
│ │ ├── ProviderConnectionResolver.php
│ │ └── ProviderGateway.php
│ └── ... (multiple Graph-enabled services)
tests/
└── Feature/
└── Guards/
Structure Decision: Laravel monolith; refactor stays within existing services/models.
Implementation Plan
Phase 0 — Outline & Research (completed)
- Documented decisions and call sites in research.md.
Phase 1 — Design & Implementation (planned)
- Kill-switch the deprecated accessor
- Update
Tenant::graphOptions()inapp/Models/Tenant.phpto throw a clear exception explaining that provider connections are required.
- Refactor all
app/call sites off$tenant->graphOptions()
- For each call site, resolve the default Microsoft provider connection via
ProviderConnectionResolver::resolveDefault($tenant, 'microsoft'). - If resolution fails, fail fast with a clear, actionable error (include the effective reason code/message).
- Replace option building with
ProviderGateway::graphOptions($connection, $overrides). - Update
app/Services/Intune/TenantConfigService.php(currently returns$tenant->graphOptions()), so it no longer provides a tenant-based path.
- Add CI guardrail (Pest)
- Add a new guard test under
tests/Feature/Guards/that scansapp/for forbidden patterns:\$tenant->graphOptions(Tenant::graphOptions(
- Ensure failure message explains how to fix (use provider connection resolution).
- Verification
- Run the guard test and the most relevant subsets described in quickstart.md.
- Run
vendor/bin/sail bin pint --dirty.
Phase 2 — Tasks (next step)
- Completed:
tasks.mdhas been generated and Phase 1 is broken into smaller, reviewable steps.
Complexity Tracking
No constitution violations are required for this feature.