TenantAtlas/specs/142-rbac-role-definition-diff-ux-upgrade/data-model.md
ahmido 3f6f80f7af feat: refine onboarding draft flow and RBAC diff UX (#171)
## Summary
- add the RBAC role definition diff UX upgrade as the first concrete consumer of the shared diff presentation foundation
- refine managed tenant onboarding draft routing, CTA labeling, and cancellation redirect behavior
- tighten related Filament and diff rendering regression coverage

## Testing
- updated focused Pest coverage for onboarding draft routing and lifecycle behavior
- updated focused Pest coverage for shared diff partials and RBAC finding rendering

## Notes
- Livewire v4.0+ compliance is preserved within the existing Filament v5 surfaces
- provider registration remains unchanged in bootstrap/providers.php
- no new Filament assets were added; existing deployment practice still relies on php artisan filament:assets when assets change

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #171
2026-03-14 20:09:54 +00:00

138 lines
4.8 KiB
Markdown

# Data Model: RBAC Role Definition Diff UX Upgrade
## Overview
This feature introduces no database schema changes. The data model is a presentation-layer model that adapts existing `Finding.evidence_jsonb.rbac_role_definition` content into shared diff presentation objects.
## Existing Input Model
### RbacRoleDefinitionEvidence
- **Source**: `Finding.evidence_jsonb.rbac_role_definition`
- **Purpose**: authoritative comparison payload already produced by the baseline comparison engine
- **Core fields**:
- `diff_kind`: string such as `metadata_only`, `missing`, or `unexpected`
- `diff_fingerprint`: stable change fingerprint for recurrence logic
- `changed_keys`: array of operator-facing diff keys that materially changed
- `metadata_keys`: array of metadata-related changed keys
- `permission_keys`: array of permission-related changed keys
- `baseline`: `RbacRoleDefinitionSide`
- `current`: `RbacRoleDefinitionSide`
### RbacRoleDefinitionSide
- **Source**: `rbac_role_definition.baseline` and `rbac_role_definition.current`
- **Purpose**: stores one side of the RBAC comparison
- **Core fields**:
- `normalized`: map of `field_key => value`
- `is_built_in`: nullable boolean used for role source display fallback
- `role_permission_count`: nullable integer used for permission-block summary fallback
## New Presentation Model
### RbacRoleDefinitionDiffBuilder
- **Type**: new consumer-local adapter class
- **Purpose**: translate `RbacRoleDefinitionEvidence` into shared `DiffPresentation`
- **Responsibilities**:
- merge baseline and current normalized rows
- apply RBAC label mapping
- apply deterministic field ordering
- mark Allowed Actions and other approved list-like fields for inline list rendering
- pass `changed_keys` through to shared state classification
- preserve no-change and sparse-data behavior
### DiffPresentation
- **Type**: existing shared DTO from Spec 141
- **Fields**:
- `summary`: `DiffSummary`
- `rows`: ordered array of `DiffRow`
- **Purpose**: single render-ready result consumed by the RBAC Blade entry
### DiffSummary
- **Type**: existing shared DTO
- **Fields**:
- `changedCount`
- `addedCount`
- `removedCount`
- `unchangedCount`
- `hasRows`
- `message`
- **Purpose**: drive summary badge counts and no-change/no-data messaging
### DiffRow
- **Type**: existing shared DTO
- **Fields**:
- `key`: stable field key
- `label`: operator-facing label
- `status`: `changed | unchanged | added | removed`
- `oldValue`
- `newValue`
- `isListLike`
- `addedItems`
- `removedItems`
- `unchangedItems`
- `meta`
- **Purpose**: represent one renderable field row in the RBAC diff region
## Consumer Configuration Model
### RbacFieldLabelMap
- **Type**: internal associative map in the builder
- **Purpose**: keep operator-facing labels stable and concise when internal keys need normalization or fallback handling
- **Examples**:
- `Role definition > Display name`
- `Role definition > Description`
- `Role definition > Role source`
- `Role definition > Permission blocks`
- `Permission block 1 > Allowed actions`
### RbacFieldOrderRules
- **Type**: internal ordering strategy in the builder
- **Purpose**: preserve predictable review order
- **Desired order**:
1. top-level role metadata
2. role source and permission-block summary
3. permission-block details
4. alphabetical fallback for unknown but valid keys
### RbacListFieldRules
- **Type**: internal field designation rules
- **Purpose**: identify which RBAC fields should intentionally use inline list diff rendering
- **Initial designated fields**:
- any `Permission block * > Allowed actions`
- optionally other simple list-valued RBAC keys that fit the same operator model, such as denied actions or conditions, if present and still readable
## State Derivation Rules
### Row status
- **Added**: key exists only on current side
- **Removed**: key exists only on baseline side
- **Changed**: key exists on both sides and either appears in `changed_keys` or has unequal values
- **Unchanged**: key exists on both sides and values are equal without change designation
### List fragments
- **Added items**: values present only in current list
- **Removed items**: values present only in baseline list
- **Unchanged items**: values present in both lists in shared order-preserving form
## Validation Rules
- Ignore empty or non-string field keys.
- Treat absent `baseline.normalized` and `current.normalized` maps as empty arrays.
- Preserve explicit `null`, boolean, scalar, and list values so `ValueStringifier` can render them consistently.
- Treat unknown metadata as optional and never required for row rendering.
## No Schema Change Statement
- No new tables, columns, indexes, or migrations are required.
- `findings.evidence_jsonb` remains the authoritative source for the RBAC consumer.