Implements the 074 verification checklist framework. Highlights: - Versioned verification report contract stored in operation_runs.context.verification_report (DB-only viewer). - Strict sanitizer/redaction (evidence pointers only; no tokens/headers/payloads) + schema validation. - Centralized BADGE-001 semantics for check status, severity, and overall report outcome. - Deterministic start (dedupe while active) via shared StartVerification service; capability-first authorization (non-member 404, member missing capability 403). - Completion audit event (verification.completed) with redacted metadata. - Integrations: OperationRun detail viewer, onboarding wizard verification step, provider connection start surfaces. Tests: - vendor/bin/sail artisan test --compact tests/Feature/Verification tests/Unit/Badges/VerificationBadgesTest.php - vendor/bin/sail bin pint --dirty Co-authored-by: Ahmed Darrazi <ahmeddarrazi@MacBookPro.fritz.box> Reviewed-on: #89
80 lines
2.9 KiB
Markdown
80 lines
2.9 KiB
Markdown
# Quickstart: Verification Checklist Framework (074)
|
|
|
|
This quickstart explains how to *write* and *render* a verification report attached to an `OperationRun`.
|
|
|
|
## 1) Writing a report (queued job / service)
|
|
|
|
**Goal**: produce a `verification_report` JSON document and store it in `OperationRun->context`.
|
|
|
|
Guidelines:
|
|
- Generate reports inside queued execution (not in a Filament page render).
|
|
- Keep evidence pointer-only (IDs/masked/hashes), never raw payloads or tokens.
|
|
- Keep next steps navigation-only in v1.
|
|
|
|
Pseudo-code sketch:
|
|
|
|
```php
|
|
$context = is_array($run->context) ? $run->context : [];
|
|
|
|
$context['verification_report'] = [
|
|
'schema_version' => '1.0',
|
|
'flow' => $run->type,
|
|
'generated_at' => now('UTC')->toIso8601String(),
|
|
'identity' => [
|
|
'tenant_id' => (int) $run->tenant_id,
|
|
'provider_connection_id' => (int) data_get($run->context, 'provider_connection_id', 0),
|
|
],
|
|
'summary' => [
|
|
'overall' => 'needs_attention',
|
|
'counts' => [
|
|
'total' => 5,
|
|
'pass' => 3,
|
|
'fail' => 2,
|
|
'warn' => 0,
|
|
'skip' => 0,
|
|
'running' => 0,
|
|
],
|
|
],
|
|
'checks' => [
|
|
[
|
|
'key' => 'provider_connection.token_acquisition',
|
|
'title' => 'Token acquisition works',
|
|
'status' => 'fail',
|
|
'severity' => 'high',
|
|
'blocking' => true,
|
|
'reason_code' => 'permission_denied',
|
|
'message' => 'The app cannot acquire a token with the configured credentials.',
|
|
'evidence' => [
|
|
['kind' => 'provider_connection_id', 'value' => (int) data_get($run->context, 'provider_connection_id')],
|
|
],
|
|
'next_steps' => [
|
|
['label' => 'Review connection credentials', 'url' => '/admin/...'],
|
|
['label' => 'Microsoft docs: app permissions', 'url' => 'https://learn.microsoft.com/...'],
|
|
],
|
|
],
|
|
],
|
|
];
|
|
|
|
$run->update(['context' => $context]);
|
|
```
|
|
|
|
## 2) Rendering the report (Filament, DB-only)
|
|
|
|
Recommended integration points:
|
|
- Monitoring → Operations: in the `OperationRun` view page, show a “Verification report” section when `context.verification_report` exists.
|
|
- Flow pages (e.g., onboarding wizard): embed the same viewer component using the run ID stored in wizard state.
|
|
|
|
**Hard requirement**: rendering must not trigger any outbound HTTP (no Graph calls, no jobs dispatched, no side effects).
|
|
|
|
## 3) Authorization split
|
|
|
|
- Viewing a report: allowed for tenant-scoped members.
|
|
- Starting verification: requires a specific capability.
|
|
- Non-members: deny-as-not-found (404) for tenant-scoped pages and actions.
|
|
|
|
## 4) Tests to add
|
|
|
|
- Viewer DB-only render test: `Http::fake()` + assert no requests during render.
|
|
- Evidence redaction test: report JSON contains none of `access_token`, `client_secret`, `Authorization`, bearer tokens, or raw payload dumps.
|
|
- Dedupe test: repeated starts while active reuse the same run.
|