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

46 lines
2.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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).