TenantAtlas/specs/048-backup-restore-ui-graph-safety/research.md
2026-01-11 00:35:29 +01:00

2.5 KiB
Raw Blame History

Research: Backup/Restore UI Graph-Safety (048)

Decision: Enforce Graph-safety via fail-hard feature renders

  • Decision: Add Pest feature tests that actingAs(...) and GET Filament page URLs while binding App\Services\Graph\GraphClientInterface to a fail-hard implementation (throws on any call).
  • Rationale: A full HTTP render exercises the real Filament request lifecycle (middleware, tenancy, resource/page boot) and will fail immediately if any UI render path touches Graph.
  • Alternatives considered:
    • Livewire component tests only → can miss route/middleware/tenancy boot and wont reflect “real render” regressions as reliably.
    • Binding Graph to NullGraphClient → would allow silent Graph usage to slip through.

Decision: Use Resource::getUrl() for stable Filament routes (tenant-scoped)

  • Decision: Use Filaments URL helpers in tests:
    • BackupSetResource::getUrl('index', tenant: $tenant)
    • RestoreRunResource::getUrl('create', tenant: $tenant)
  • Rationale: Avoids hardcoding route paths and keeps tests resilient to panel path / tenancy prefix changes.
  • Repo evidence:
    • tests/Feature/Filament/InventorySyncRunResourceTest.php uses ->get(InventorySyncRunResource::getUrl('index', tenant: $tenant)).
  • Alternatives considered:
    • Hardcoded /admin/t/{tenant}/... paths → brittle if the panel path or tenant prefix changes.

Decision: Assert HTTP 200 + stable marker

  • Decision: Guard tests assert ->assertOk() plus a stable marker string per page.
  • Rationale: Reduces false positives (e.g., a redirect to login) and makes failures easier to diagnose.
  • Alternatives considered:
    • Status-only (200) → may still pass with empty/partial output or wrong page.

Decision: Fallback label masking format

  • Decision: Mask unresolved external IDs as …<last8> (last 8 characters, prefixed with ellipsis).
  • Rationale: Keeps UI readable while avoiding full identifier disclosure.
  • Alternatives considered:
    • Full ID → increases accidental disclosure.
    • Hash → less readable for operators.

Decision: Filament panel + tenancy routing assumptions

  • Decision: Treat the Filament admin panel as tenant-scoped under the configured path/prefix:
    • Panel path: admin
    • Tenant route prefix: t
    • Tenant slug attribute: external_id
  • Rationale: This is the repos current canonical setup (App\Providers\Filament\AdminPanelProvider).
  • Alternatives considered:
    • Non-tenant-scoped pages → not applicable (TenantPilot is tenant-first).