# Implementation Plan: Backup/Restore UI Graph-Safety (Phase 1)

**Branch**: `feat/048-backup-restore-ui-graph-safety` | **Date**: 2026-01-11 | **Spec**: specs/048-backup-restore-ui-graph-safety/spec.md
**Input**: Feature specification from `specs/048-backup-restore-ui-graph-safety/spec.md`

## Summary

Ensure Backup/Restore Filament UI is Graph-safe by construction:

- No Microsoft Graph calls during render/mount/options/typeahead.
- Restore wizard group mapping UI shows DB-only fallback labels (`…<last8>`) instead of resolving names via Graph.
- Add fail-hard Pest feature tests that bind `GraphClientInterface` to throw and still allow:
  - Backup Sets index to render (HTTP 200 + stable marker)
  - Restore wizard to render (HTTP 200 + stable marker)

## Technical Context

**Language/Version**: PHP 8.2+ (repo guidance targets PHP 8.4.x)  
**Primary Dependencies**: Laravel 12, Filament 4, Livewire 3  
**Storage**: PostgreSQL (JSON columns used for snapshots/preview/results/mappings)  
**Testing**: Pest 4 (via `php artisan test`), PHPUnit 12 under the hood  
**Target Platform**: Sail-first local dev (Docker), Dokploy-first staging/prod (containers)  
**Project Type**: Laravel monolith (Filament admin UI + jobs/services)  
**Performance Goals**: N/A (UI correctness + safety)  
**Constraints**:
- UI render must be DB-only (no Graph in request lifecycle)
- No new tables/migrations in Phase 1
- Keep surface area minimal and low-risk
**Scale/Scope**: Multi-tenant admin app; tests must enforce tenant scoping and guardrails

## Constitution Check

*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*

- Inventory-first: PASS (this phase only hardens UI render boundaries; no changes to SoT semantics)
- Read/write separation: PASS (no restore execution changes; tests cover render only)
- Single contract path to Graph: PASS (goal is “no Graph in UI render”; Graph stays behind `GraphClientInterface`)
- Deterministic capabilities: PASS (no capability derivation changes)
- Tenant isolation: PASS (tests use tenant-scoped URLs and seeded tenant data)
- Automation idempotent/observable: PASS (no job/scheduler changes in Phase 1)
- Data minimization & safe logging: PASS (no new stored data or logs)

## Project Structure

### Documentation (this feature)

```text
specs/048-backup-restore-ui-graph-safety/
├── plan.md              # This file (/speckit.plan output)
├── research.md          # Phase 0 output
├── data-model.md        # Phase 1 output
├── quickstart.md        # Phase 1 output
├── contracts/           # Phase 1 output
└── tasks.md             # Task breakdown (already present)
```

### Source Code (repository root)

```text
app/
├── Filament/
│   ├── Resources/
│   │   ├── BackupSetResource.php
│   │   └── RestoreRunResource.php
│   └── Resources/*/Pages/
├── Providers/
│   ├── AppServiceProvider.php            # GraphClientInterface binding
│   └── Filament/AdminPanelProvider.php   # panel path + tenant routing
├── Services/
│   └── Graph/
│       ├── GraphClientInterface.php
│       └── NullGraphClient.php

database/migrations/
tests/Feature/
```

**Structure Decision**: Laravel monolith (Filament admin UI + services). No new top-level folders.

## Complexity Tracking

None.
