Implements Spec 084 (verification-surfaces-unification). Highlights - Unifies tenant + onboarding verification start on `provider.connection.check` (OperationRun-based, enqueue-only). - Ensures completed blocked runs persist a schema-valid `context.verification_report` stub (DB-only viewers never show “unavailable”). - Adds tenant embedded verification report widget with DB-only rendering + canonical tenantless “View run” links. - Enforces 404/403 semantics for tenantless run viewing (workspace membership + tenant entitlement required; otherwise 404). - Fixes admin panel widgets to resolve tenant from record context so Owners can start verification and recent operations renders correctly. Tests - Ran: `vendor/bin/sail artisan test --compact tests/Feature/Verification/ tests/Feature/ProviderConnections/ProviderOperationBlockedGuidanceSpec081Test.php tests/Feature/Onboarding/OnboardingVerificationTest.php tests/Feature/RunAuthorizationTenantIsolationTest.php tests/Feature/Filament/TenantVerificationReportWidgetTest.php tests/Feature/Filament/RecentOperationsSummaryWidgetTest.php` Notes - Filament v5 / Livewire v4 compatible. - No new assets; no changes to provider registration. Co-authored-by: Ahmed Darrazi <ahmeddarrazi@MacBookPro.fritz.box> Reviewed-on: #102
132 lines
7.1 KiB
Markdown
132 lines
7.1 KiB
Markdown
# Implementation Plan: Verification Surfaces Unification
|
|
|
|
**Branch**: `084-verification-surfaces-unification` | **Date**: 2026-02-09 | **Spec**: `specs/084-verification-surfaces-unification/spec.md`
|
|
**Input**: Feature specification from `specs/084-verification-surfaces-unification/spec.md`
|
|
|
|
## Summary
|
|
|
|
Unify tenant “Verify configuration” and onboarding “Verify access” to the same `OperationRun`-based flow (`provider.connection.check`), with DB-only viewing and canonical tenantless run links. Ensure any **completed blocked** verification run persists a **schema-valid** `context.verification_report` stub so viewers never show “report unavailable” for blocked completions.
|
|
|
|
## Technical Context
|
|
|
|
**Language/Version**: PHP 8.4 (Laravel 12)
|
|
**Primary Dependencies**: Filament v5 (Livewire v4), Queue/Jobs (Laravel), Microsoft Graph via `GraphClientInterface`
|
|
**Storage**: PostgreSQL (JSONB-backed `OperationRun.context`)
|
|
**Testing**: Pest v4 (Feature tests), Filament/Livewire component testing where applicable
|
|
**Target Platform**: Web application (Sail-first local dev)
|
|
|
|
**Performance Goals**:
|
|
- Tenant detail + onboarding verification surfaces render DB-only with no external provider/Graph calls.
|
|
- Start action returns quickly (authorize → create/dedupe run → enqueue job → notify + “View run”).
|
|
|
|
**Constraints**:
|
|
- RBAC isolation: non-members are deny-as-not-found (404); members missing capability are 403 on execution.
|
|
- `OperationRun` active dedupe enforced (already handled via `OperationRunService::ensureRunWithIdentity()` + active-run checks).
|
|
|
|
**Scale/Scope**: Tenant-scoped verification for provider connection health + permission inventory refresh (existing behavior).
|
|
|
|
## Constitution Check
|
|
|
|
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
|
|
|
- Inventory-first / Read-write separation: PASS (verification is an explicit user-triggered operation; viewing is read-only).
|
|
- Graph contract path: PASS (provider verification uses `ProviderGateway` + `GraphClientInterface`; no render-time Graph calls).
|
|
- Workspace/Tenant isolation: PASS (tenantless canonical views must still enforce workspace + tenant entitlement; missing either is 404).
|
|
- RBAC-UX 404/403 split: PASS (start is 403 for members missing capability; non-members 404; Livewire calls included).
|
|
- Run observability: PASS (verification is queued and tracked as `OperationRun`; start surfaces enqueue-only; Monitoring is DB-only).
|
|
- Data minimization/safe logging: PASS (verification report stored in `OperationRun.context`; no secrets; next steps are link-only).
|
|
- Filament action safety: PASS (verification start uses `->action(...)`; any destructive action confirmations remain required).
|
|
|
|
No constitution violations are required for this feature.
|
|
|
|
## Project Structure
|
|
|
|
### Documentation (this feature)
|
|
|
|
```text
|
|
specs/084-verification-surfaces-unification/
|
|
├── plan.md
|
|
├── research.md
|
|
├── data-model.md
|
|
├── quickstart.md
|
|
└── contracts/
|
|
├── operation-run-context.provider-connection-check.schema.json
|
|
└── verification-surfaces.routes.md
|
|
```
|
|
|
|
### Source Code (existing, relevant)
|
|
|
|
```text
|
|
app/
|
|
├── Filament/
|
|
│ ├── Resources/
|
|
│ │ ├── TenantResource.php
|
|
│ │ └── TenantResource/Pages/ViewTenant.php
|
|
│ ├── Pages/Workspaces/ManagedTenantOnboardingWizard.php
|
|
│ └── Support/VerificationReportViewer.php
|
|
├── Jobs/ProviderConnectionHealthCheckJob.php
|
|
├── Services/
|
|
│ ├── Providers/ProviderOperationStartGate.php
|
|
│ ├── OperationRunService.php
|
|
│ └── Verification/StartVerification.php
|
|
└── Support/
|
|
├── OperationRunLinks.php
|
|
└── Verification/VerificationReportWriter.php
|
|
resources/views/filament/components/verification-report-viewer.blade.php
|
|
resources/views/filament/forms/components/managed-tenant-onboarding-verification-report.blade.php
|
|
```
|
|
|
|
## Phase 0 — Outline & Research
|
|
|
|
### Key decisions (grounded in current code)
|
|
|
|
- Use `provider.connection.check` as the unified verification run type.
|
|
- Already used by onboarding (`ManagedTenantOnboardingWizard::startVerification()`) and by `StartVerification::providerConnectionCheck()`.
|
|
- Tenant verification start surfaces (tenant detail and tenant list actions) will be refactored to start/dedupe `provider.connection.check` via `StartVerification`, always resolve the tenant's default provider connection, and always offer a canonical “View run” link.
|
|
- `StartVerification` API changes remain non-breaking in this feature (keep existing explicit-connection method; add a tenant-default start helper rather than replacing signatures).
|
|
- Blocked runs must write a schema-valid stub report:
|
|
- Implement stub generation immediately after `OperationRunService::finalizeBlockedRun()` for the `provider.connection.check` operation type, using `VerificationReportWriter::write(...)`.
|
|
- Tenantless canonical run viewing for tenant-associated runs is a foundational blocker and must enforce workspace membership + tenant entitlement with deny-as-not-found semantics before user-story completion.
|
|
|
|
### Outputs
|
|
|
|
- `research.md` records decisions + rationale + alternatives.
|
|
|
|
## Phase 1 — Design & Contracts
|
|
|
|
### Data model (no DB migration expected)
|
|
|
|
- Store verification report exclusively in `operation_runs.context.verification_report` (existing pattern).
|
|
- Enforce: when a `provider.connection.check` run completes with outcome `blocked`, `context.verification_report` is present and schema-valid.
|
|
|
|
### Contracts
|
|
|
|
- `contracts/operation-run-context.provider-connection-check.schema.json`
|
|
- Documents expected `OperationRun.context` keys for the verification run type.
|
|
- `contracts/verification-surfaces.routes.md`
|
|
- Documents user actions → routes/surfaces and the canonical run viewer URL.
|
|
|
|
### Outputs
|
|
|
|
- `data-model.md`, `contracts/*`, `quickstart.md`.
|
|
|
|
## Phase 2 — Implementation Planning (for `/speckit.tasks`)
|
|
|
|
Planned work items to convert into `tasks.md`:
|
|
|
|
1. Refactor tenant verification actions (tenant detail + tenant list) to use the unified start path (`provider.connection.check`) with default connection resolution, returning started/deduped/busy outcomes with a canonical run URL.
|
|
2. Add tenant embedded verification viewer:
|
|
- Select latest `provider.connection.check` run attempt for the tenant.
|
|
- Show DB-only empty state when none exists.
|
|
- Show DB-only “in progress” state when active with no report yet.
|
|
3. Ensure blocked verification runs always store a schema-valid stub report:
|
|
- Post-`finalizeBlockedRun()` write via `VerificationReportWriter` for `provider.connection.check`.
|
|
4. Authorization + isolation (blocking):
|
|
- Non-members: 404 for tenant routes and tenantless operations viewer of tenant-associated runs.
|
|
- Members missing capability: UI visible-but-disabled; server returns 403.
|
|
5. Tests (Pest):
|
|
- Blocked start produces a completed blocked run with a schema-valid `verification_report`.
|
|
- Tenant page and onboarding viewer render from stored report only (no external calls during render).
|
|
- Tenant render path never persists permission inventory updates and never uses synchronous verification paths.
|
|
- Canonical run links point to `admin.operations.view` (tenantless).
|