TenantAtlas/specs/088-remove-tenant-graphoptions-legacy/plan.md
ahmido 1acbf8cc54 feat(spec-088): remove tenant graphOptions legacy path (#105)
## Summary
- remove tenant-based Graph options access from runtime service paths and enforce provider-only resolution
- add `MicrosoftGraphOptionsResolver` and `ProviderConfigurationRequiredException` for centralized, actionable provider-config errors
- turn `Tenant::graphOptions()` into a fail-fast kill switch to prevent legacy runtime usage
- add and update tests (including guardrail) to enforce no reintroduction in `app/`
- update Spec 088 artifacts (`spec`, `plan`, `research`, `tasks`, checklist)

## Validation
- `vendor/bin/sail bin pint --dirty`
- `vendor/bin/sail artisan test --compact --filter=NoLegacyTenantGraphOptions`
- `vendor/bin/sail artisan test --compact tests/Feature/Filament`
- `CI=1 vendor/bin/sail artisan test --compact`

## Notes
- Branch includes the guardrail test for legacy callsite detection in `app/`.
- Full suite currently green: 1227 passed, 5 skipped.

Co-authored-by: Ahmed Darrazi <ahmeddarrazi@MacBookPro.fritz.box>
Reviewed-on: #105
2026-02-12 10:14:44 +00:00

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 to tests/).
  • No new Graph endpoints; Graph calls remain routed through GraphClientInterface. Scale/Scope: Repo-wide refactor of call sites in app/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)

Phase 1 — Design & Implementation (planned)

  1. Kill-switch the deprecated accessor
  • Update Tenant::graphOptions() in app/Models/Tenant.php to throw a clear exception explaining that provider connections are required.
  1. 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.
  1. Add CI guardrail (Pest)
  • Add a new guard test under tests/Feature/Guards/ that scans app/ for forbidden patterns:
    • \$tenant->graphOptions(
    • Tenant::graphOptions(
  • Ensure failure message explains how to fix (use provider connection resolution).
  1. 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.md has been generated and Phase 1 is broken into smaller, reviewable steps.

Complexity Tracking

No constitution violations are required for this feature.