Spec 196: finalize hard Filament nativity cleanup artifacts #231
4
.github/agents/copilot-instructions.md
vendored
4
.github/agents/copilot-instructions.md
vendored
@ -176,6 +176,8 @@ ## Active Technologies
|
|||||||
- PHP 8.4.15 + Laravel 12, Filament v5, Livewire v4, Pest v4, Tailwind CSS v4, existing `UiEnforcement`, existing audit loggers (`AuditLogger`, `WorkspaceAuditLogger`, `SystemConsoleAuditLogger`), existing mutation services (`FindingExceptionService`, `FindingWorkflowService`, `TenantReviewLifecycleService`, `EvidenceSnapshotService`, `OperationRunTriageService`) (194-governance-friction-hardening)
|
- PHP 8.4.15 + Laravel 12, Filament v5, Livewire v4, Pest v4, Tailwind CSS v4, existing `UiEnforcement`, existing audit loggers (`AuditLogger`, `WorkspaceAuditLogger`, `SystemConsoleAuditLogger`), existing mutation services (`FindingExceptionService`, `FindingWorkflowService`, `TenantReviewLifecycleService`, `EvidenceSnapshotService`, `OperationRunTriageService`) (194-governance-friction-hardening)
|
||||||
- PHP 8.4.15 + Laravel 12, Filament v5, Livewire v4, Pest v4, Tailwind CSS v4, existing `ActionSurfaceDiscovery`, `ActionSurfaceValidator`, `ActionSurfaceExemptions`, `GovernanceActionCatalog`, `UiEnforcement`, `WorkspaceContext`, and existing system/onboarding/auth helpers (195-action-surface-closure)
|
- PHP 8.4.15 + Laravel 12, Filament v5, Livewire v4, Pest v4, Tailwind CSS v4, existing `ActionSurfaceDiscovery`, `ActionSurfaceValidator`, `ActionSurfaceExemptions`, `GovernanceActionCatalog`, `UiEnforcement`, `WorkspaceContext`, and existing system/onboarding/auth helpers (195-action-surface-closure)
|
||||||
- PostgreSQL through existing workspace-owned, tenant-owned, and system-visible models; no schema change planned (195-action-surface-closure)
|
- PostgreSQL through existing workspace-owned, tenant-owned, and system-visible models; no schema change planned (195-action-surface-closure)
|
||||||
|
- PHP 8.4.15 + Laravel 12, Filament v5, Livewire v4, Pest v4, Tailwind CSS v4, existing `DependencyQueryService`, `DependencyTargetResolver`, `TenantRequiredPermissionsViewModelBuilder`, `ArtifactTruthPresenter`, `WorkspaceContext`, Filament `InteractsWithTable`, Filament `TableComponent`, and existing badge and action-surface helpers (196-hard-filament-nativity-cleanup)
|
||||||
|
- PostgreSQL through existing tenant-owned and workspace-context models (`InventoryItem`, `InventoryLink`, `TenantPermission`, `EvidenceSnapshot`, `TenantReview`); no schema change planned (196-hard-filament-nativity-cleanup)
|
||||||
|
|
||||||
- PHP 8.4.15 (feat/005-bulk-operations)
|
- PHP 8.4.15 (feat/005-bulk-operations)
|
||||||
|
|
||||||
@ -210,8 +212,8 @@ ## Code Style
|
|||||||
PHP 8.4.15: Follow standard conventions
|
PHP 8.4.15: Follow standard conventions
|
||||||
|
|
||||||
## Recent Changes
|
## Recent Changes
|
||||||
|
- 196-hard-filament-nativity-cleanup: Added PHP 8.4.15 + Laravel 12, Filament v5, Livewire v4, Pest v4, Tailwind CSS v4, existing `DependencyQueryService`, `DependencyTargetResolver`, `TenantRequiredPermissionsViewModelBuilder`, `ArtifactTruthPresenter`, `WorkspaceContext`, Filament `InteractsWithTable`, Filament `TableComponent`, and existing badge and action-surface helpers
|
||||||
- 195-action-surface-closure: Added PHP 8.4.15 + Laravel 12, Filament v5, Livewire v4, Pest v4, Tailwind CSS v4, existing `ActionSurfaceDiscovery`, `ActionSurfaceValidator`, `ActionSurfaceExemptions`, `GovernanceActionCatalog`, `UiEnforcement`, `WorkspaceContext`, and existing system/onboarding/auth helpers
|
- 195-action-surface-closure: Added PHP 8.4.15 + Laravel 12, Filament v5, Livewire v4, Pest v4, Tailwind CSS v4, existing `ActionSurfaceDiscovery`, `ActionSurfaceValidator`, `ActionSurfaceExemptions`, `GovernanceActionCatalog`, `UiEnforcement`, `WorkspaceContext`, and existing system/onboarding/auth helpers
|
||||||
- 195-action-surface-closure: Added PostgreSQL through existing workspace-owned, tenant-owned, and system-visible models; no schema change planned
|
- 195-action-surface-closure: Added PostgreSQL through existing workspace-owned, tenant-owned, and system-visible models; no schema change planned
|
||||||
- 194-governance-friction-hardening: Added PHP 8.4.15 + Laravel 12, Filament v5, Livewire v4, Pest v4, Tailwind CSS v4, existing `UiEnforcement`, existing audit loggers (`AuditLogger`, `WorkspaceAuditLogger`, `SystemConsoleAuditLogger`), existing mutation services (`FindingExceptionService`, `FindingWorkflowService`, `TenantReviewLifecycleService`, `EvidenceSnapshotService`, `OperationRunTriageService`)
|
|
||||||
<!-- MANUAL ADDITIONS START -->
|
<!-- MANUAL ADDITIONS START -->
|
||||||
<!-- MANUAL ADDITIONS END -->
|
<!-- MANUAL ADDITIONS END -->
|
||||||
|
|||||||
@ -0,0 +1,36 @@
|
|||||||
|
# Specification Quality Checklist: Hard Filament Nativity Cleanup
|
||||||
|
|
||||||
|
**Purpose**: Validate specification completeness and quality before proceeding to planning
|
||||||
|
**Created**: 2026-04-13
|
||||||
|
**Feature**: [spec.md](../spec.md)
|
||||||
|
|
||||||
|
## Content Quality
|
||||||
|
|
||||||
|
- [x] No implementation details (languages, frameworks, APIs)
|
||||||
|
- [x] Focused on user value and business needs
|
||||||
|
- [x] Written for non-technical stakeholders
|
||||||
|
- [x] All mandatory sections completed
|
||||||
|
|
||||||
|
## Requirement Completeness
|
||||||
|
|
||||||
|
- [x] No [NEEDS CLARIFICATION] markers remain
|
||||||
|
- [x] Requirements are testable and unambiguous
|
||||||
|
- [x] Success criteria are measurable
|
||||||
|
- [x] Success criteria are technology-agnostic (no implementation details)
|
||||||
|
- [x] All acceptance scenarios are defined
|
||||||
|
- [x] Edge cases are identified
|
||||||
|
- [x] Scope is clearly bounded
|
||||||
|
- [x] Dependencies and assumptions identified
|
||||||
|
|
||||||
|
## Feature Readiness
|
||||||
|
|
||||||
|
- [x] All functional requirements have clear acceptance criteria
|
||||||
|
- [x] User scenarios cover primary flows
|
||||||
|
- [x] Feature meets measurable outcomes defined in Success Criteria
|
||||||
|
- [x] No implementation details leak into specification
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Validated after initial draft on 2026-04-13.
|
||||||
|
- Framework-specific language appears only where the feature itself and constitution require naming the native admin contract; the spec does not prescribe code-level implementation choices, new abstractions, or dependency changes.
|
||||||
|
- No clarification questions were required from the user because scope, non-goals, and acceptance expectations were already explicit.
|
||||||
@ -0,0 +1,395 @@
|
|||||||
|
openapi: 3.1.0
|
||||||
|
info:
|
||||||
|
title: Filament Nativity Cleanup Logical Contract
|
||||||
|
version: 0.1.0
|
||||||
|
description: >-
|
||||||
|
Logical planning contract for Spec 196. This artifact defines the expected
|
||||||
|
state ownership, filter semantics, scope guarantees, and row projections for
|
||||||
|
the three cleaned UI surfaces. It is not a runtime API definition.
|
||||||
|
servers:
|
||||||
|
- url: https://logical-spec.local
|
||||||
|
description: Non-runtime planning contract
|
||||||
|
paths:
|
||||||
|
/internal/ui/inventory-items/{inventoryItemId}/dependencies:
|
||||||
|
get:
|
||||||
|
summary: Read dependency section state for one inventory item detail surface
|
||||||
|
operationId: getInventoryItemDependenciesView
|
||||||
|
parameters:
|
||||||
|
- name: inventoryItemId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: integer
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Dependency detail-surface state and rows
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- data
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/components/schemas/DependencyEdgesView'
|
||||||
|
'404':
|
||||||
|
description: Returned when the actor is not entitled to the tenant or inventory-item scope.
|
||||||
|
/internal/ui/tenants/{tenantExternalId}/required-permissions:
|
||||||
|
get:
|
||||||
|
summary: Read required-permissions page state for one route-scoped tenant
|
||||||
|
operationId: getTenantRequiredPermissionsView
|
||||||
|
parameters:
|
||||||
|
- name: tenantExternalId
|
||||||
|
in: path
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- name: status
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/RequiredPermissionsStatus'
|
||||||
|
- name: type
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/PermissionTypeFilter'
|
||||||
|
- name: features
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
- name: search
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Required-permissions page state, summary, and rows
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- data
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/components/schemas/RequiredPermissionsView'
|
||||||
|
'404':
|
||||||
|
description: Returned when workspace or tenant membership is absent for the route-scoped tenant.
|
||||||
|
/internal/ui/evidence-overview:
|
||||||
|
get:
|
||||||
|
summary: Read workspace evidence overview table state and rows
|
||||||
|
operationId: getEvidenceOverviewView
|
||||||
|
parameters:
|
||||||
|
- name: tenantId
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
description: Optional entitled tenant prefilter; unauthorized tenant identifiers must not reveal row existence.
|
||||||
|
schema:
|
||||||
|
anyOf:
|
||||||
|
- type: integer
|
||||||
|
- type: 'null'
|
||||||
|
- name: search
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: Workspace evidence overview state and rows
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- data
|
||||||
|
properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/components/schemas/EvidenceOverviewView'
|
||||||
|
'404':
|
||||||
|
description: Returned when workspace membership is absent for the evidence overview surface.
|
||||||
|
components:
|
||||||
|
schemas:
|
||||||
|
DependencyDirection:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- all
|
||||||
|
- inbound
|
||||||
|
- outbound
|
||||||
|
RelationshipTypeKey:
|
||||||
|
type: string
|
||||||
|
description: Recognized relationship type key from the existing dependency domain.
|
||||||
|
RequiredPermissionsStatus:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- missing
|
||||||
|
- present
|
||||||
|
- error
|
||||||
|
- all
|
||||||
|
PermissionTypeFilter:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- all
|
||||||
|
- application
|
||||||
|
- delegated
|
||||||
|
DependencyEdgesState:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- inventoryItemId
|
||||||
|
- tenantId
|
||||||
|
- direction
|
||||||
|
properties:
|
||||||
|
inventoryItemId:
|
||||||
|
type: integer
|
||||||
|
tenantId:
|
||||||
|
type: integer
|
||||||
|
direction:
|
||||||
|
$ref: '#/components/schemas/DependencyDirection'
|
||||||
|
relationshipType:
|
||||||
|
anyOf:
|
||||||
|
- $ref: '#/components/schemas/RelationshipTypeKey'
|
||||||
|
- type: 'null'
|
||||||
|
DependencyEdgeRow:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- relationshipType
|
||||||
|
- targetType
|
||||||
|
- renderedTarget
|
||||||
|
- isMissing
|
||||||
|
- missingTitle
|
||||||
|
properties:
|
||||||
|
relationshipType:
|
||||||
|
type: string
|
||||||
|
targetType:
|
||||||
|
type: string
|
||||||
|
targetId:
|
||||||
|
anyOf:
|
||||||
|
- type: string
|
||||||
|
- type: 'null'
|
||||||
|
renderedTarget:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
isMissing:
|
||||||
|
type: boolean
|
||||||
|
missingTitle:
|
||||||
|
type: string
|
||||||
|
DependencyEdgesView:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- state
|
||||||
|
- rows
|
||||||
|
properties:
|
||||||
|
state:
|
||||||
|
$ref: '#/components/schemas/DependencyEdgesState'
|
||||||
|
rows:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/DependencyEdgeRow'
|
||||||
|
RequiredPermissionsState:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- routeTenantExternalId
|
||||||
|
- status
|
||||||
|
- type
|
||||||
|
- features
|
||||||
|
- search
|
||||||
|
- routeTenantAuthoritative
|
||||||
|
- seededFromQuery
|
||||||
|
properties:
|
||||||
|
routeTenantExternalId:
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
$ref: '#/components/schemas/RequiredPermissionsStatus'
|
||||||
|
type:
|
||||||
|
$ref: '#/components/schemas/PermissionTypeFilter'
|
||||||
|
features:
|
||||||
|
type: array
|
||||||
|
uniqueItems: true
|
||||||
|
description: Normalized unique list of known feature keys.
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
search:
|
||||||
|
type: string
|
||||||
|
routeTenantAuthoritative:
|
||||||
|
type: boolean
|
||||||
|
const: true
|
||||||
|
seededFromQuery:
|
||||||
|
type: boolean
|
||||||
|
RequiredPermissionsSummary:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- counts
|
||||||
|
- freshness
|
||||||
|
- featureImpacts
|
||||||
|
- copyPayloads
|
||||||
|
- issues
|
||||||
|
properties:
|
||||||
|
counts:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: integer
|
||||||
|
overall:
|
||||||
|
anyOf:
|
||||||
|
- type: string
|
||||||
|
- type: 'null'
|
||||||
|
freshness:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
featureImpacts:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
copyPayloads:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
issues:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
PermissionReviewRow:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- permissionKey
|
||||||
|
- type
|
||||||
|
- status
|
||||||
|
properties:
|
||||||
|
permissionKey:
|
||||||
|
type: string
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
features:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
details:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
RequiredPermissionsView:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- state
|
||||||
|
- summary
|
||||||
|
- rows
|
||||||
|
properties:
|
||||||
|
state:
|
||||||
|
$ref: '#/components/schemas/RequiredPermissionsState'
|
||||||
|
summary:
|
||||||
|
$ref: '#/components/schemas/RequiredPermissionsSummary'
|
||||||
|
rows:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/PermissionReviewRow'
|
||||||
|
EvidenceOverviewState:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- workspaceId
|
||||||
|
- authorizedTenantIds
|
||||||
|
- tenantFilter
|
||||||
|
- search
|
||||||
|
- seededFromQuery
|
||||||
|
properties:
|
||||||
|
workspaceId:
|
||||||
|
type: integer
|
||||||
|
authorizedTenantIds:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: integer
|
||||||
|
tenantFilter:
|
||||||
|
anyOf:
|
||||||
|
- type: integer
|
||||||
|
- type: 'null'
|
||||||
|
search:
|
||||||
|
type: string
|
||||||
|
seededFromQuery:
|
||||||
|
type: boolean
|
||||||
|
EvidenceOverviewRow:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- tenantId
|
||||||
|
- tenantName
|
||||||
|
- snapshotId
|
||||||
|
- artifactTruth
|
||||||
|
- freshness
|
||||||
|
- missingDimensions
|
||||||
|
- staleDimensions
|
||||||
|
- nextStep
|
||||||
|
- viewUrl
|
||||||
|
properties:
|
||||||
|
tenantId:
|
||||||
|
type: integer
|
||||||
|
tenantName:
|
||||||
|
type: string
|
||||||
|
snapshotId:
|
||||||
|
type: integer
|
||||||
|
artifactTruth:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
freshness:
|
||||||
|
type: object
|
||||||
|
additionalProperties: true
|
||||||
|
generatedAt:
|
||||||
|
anyOf:
|
||||||
|
- type: string
|
||||||
|
- type: 'null'
|
||||||
|
missingDimensions:
|
||||||
|
type: integer
|
||||||
|
staleDimensions:
|
||||||
|
type: integer
|
||||||
|
nextStep:
|
||||||
|
type: string
|
||||||
|
viewUrl:
|
||||||
|
type: string
|
||||||
|
EvidenceOverviewView:
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- state
|
||||||
|
- rows
|
||||||
|
properties:
|
||||||
|
state:
|
||||||
|
$ref: '#/components/schemas/EvidenceOverviewState'
|
||||||
|
rows:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/components/schemas/EvidenceOverviewRow'
|
||||||
|
x-spec-196-notes:
|
||||||
|
consumerScope: illustrative core consumers only; Blade views and focused verification files are tracked in plan.md, quickstart.md, and tasks.md
|
||||||
|
consumers:
|
||||||
|
- apps/platform/app/Filament/Resources/InventoryItemResource.php
|
||||||
|
- apps/platform/app/Livewire/InventoryItemDependencyEdgesTable.php
|
||||||
|
- apps/platform/app/Filament/Pages/TenantRequiredPermissions.php
|
||||||
|
- apps/platform/app/Filament/Pages/Monitoring/EvidenceOverview.php
|
||||||
|
- apps/platform/app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php
|
||||||
|
- apps/platform/tests/Feature/InventoryItemDependenciesTest.php
|
||||||
|
- apps/platform/tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php
|
||||||
|
- apps/platform/tests/Feature/Evidence/EvidenceOverviewPageTest.php
|
||||||
|
invariants:
|
||||||
|
- route tenant stays authoritative on required-permissions
|
||||||
|
- evidence overview only exposes entitled tenant rows
|
||||||
|
- dependency rendering remains tenant-isolated and DB-only
|
||||||
|
- query values may seed initial state but not stay the primary contract
|
||||||
|
nonGoals:
|
||||||
|
- runtime API exposure
|
||||||
|
- new persistence
|
||||||
|
- new provider or route families
|
||||||
|
- global context shell redesign
|
||||||
|
- monitoring page-state architecture rewrite
|
||||||
|
- audit log selected-record or inspect duality cleanup
|
||||||
|
- finding exceptions queue dual-inspect cleanup
|
||||||
|
- baseline compare matrix or other special-visualization work
|
||||||
|
- verification report viewer families or onboarding verification report variants
|
||||||
|
- normalized diff or settings viewer families
|
||||||
|
- restore preview, restore results, or enterprise-detail layout rework
|
||||||
|
- raw anchor-to-component link consistency sweeps
|
||||||
|
- badge-only, banner-only, or style-only polish work
|
||||||
|
- new CI guardrail, review-enforcement, or constitution frameworks
|
||||||
212
specs/196-hard-filament-nativity-cleanup/data-model.md
Normal file
212
specs/196-hard-filament-nativity-cleanup/data-model.md
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
# Data Model: Hard Filament Nativity Cleanup
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This feature introduces no new persisted entity, table, enum, or product-domain source of truth. It refactors three existing UI surfaces by replacing pseudo-native interaction contracts with native page-owned or component-owned state.
|
||||||
|
|
||||||
|
The data model for planning is therefore a set of derived UI-state and row-projection models that answer four questions:
|
||||||
|
|
||||||
|
1. What state is authoritative for each cleaned surface?
|
||||||
|
2. Which source truths continue to produce the rows and summaries?
|
||||||
|
3. Which values may be seeded from deeplinks, and which values must remain route- or entitlement-authoritative?
|
||||||
|
4. Which invariants must remain true after the cleanup?
|
||||||
|
|
||||||
|
## Existing Source Truths Reused Without Change
|
||||||
|
|
||||||
|
The following truths remain authoritative and are not redefined by this feature:
|
||||||
|
|
||||||
|
- `InventoryItem`, `InventoryLink`, `DependencyQueryService`, and `DependencyTargetResolver` for dependency edges and rendered targets
|
||||||
|
- the current tenant-context inventory route and inventory-record scope rules
|
||||||
|
- `TenantRequiredPermissionsViewModelBuilder`, `TenantPermission`, permission configuration, and provider guidance links for required-permissions truth
|
||||||
|
- the route-scoped tenant on `/admin/tenants/{tenant:external_id}/required-permissions`
|
||||||
|
- `EvidenceSnapshot`, `TenantReview`, `ArtifactTruthPresenter`, and the current workspace-context entitlement rules for evidence overview rows
|
||||||
|
- existing capability registries, `WorkspaceContext`, tenant membership checks, and current deny-as-not-found boundaries
|
||||||
|
|
||||||
|
This feature changes how these truths are controlled and rendered, not what they mean.
|
||||||
|
|
||||||
|
## New Derived Planning Models
|
||||||
|
|
||||||
|
### DependencyEdgesTableState
|
||||||
|
|
||||||
|
**Type**: embedded detail-surface state
|
||||||
|
**Source**: Livewire component state on inventory item detail
|
||||||
|
|
||||||
|
| Field | Type | Notes |
|
||||||
|
|------|------|-------|
|
||||||
|
| `inventoryItemId` | int | Required current detail record key |
|
||||||
|
| `tenantId` | int | Required tenant-context key derived from the current panel or record scope |
|
||||||
|
| `direction` | string | Allowed values: `all`, `inbound`, `outbound`; default `all` |
|
||||||
|
| `relationshipType` | string or null | Null means all relationship types; otherwise one allowed relationship type key |
|
||||||
|
|
||||||
|
**Validation rules**
|
||||||
|
|
||||||
|
- `inventoryItemId` must resolve to the current authorized record.
|
||||||
|
- `tenantId` must match the current tenant-context scope.
|
||||||
|
- `direction` must stay inside the three allowed values.
|
||||||
|
- `relationshipType` must be null or a recognized relationship type value.
|
||||||
|
|
||||||
|
### DependencyEdgeRow
|
||||||
|
|
||||||
|
**Type**: derived row projection
|
||||||
|
**Source**: `DependencyQueryService` plus `DependencyTargetResolver`
|
||||||
|
|
||||||
|
| Field | Type | Notes |
|
||||||
|
|------|------|-------|
|
||||||
|
| `relationshipType` | string | Canonical relationship family for grouping or filter matching |
|
||||||
|
| `targetType` | string | Current target kind, including `missing` when unresolved |
|
||||||
|
| `targetId` | string or null | External or internal target identifier |
|
||||||
|
| `renderedTarget` | array | Existing rendered badge and link payload |
|
||||||
|
| `isMissing` | boolean | Derived from `targetType === missing` |
|
||||||
|
| `missingTitle` | string | Existing descriptive fallback text for unresolved targets |
|
||||||
|
|
||||||
|
**Invariants**
|
||||||
|
|
||||||
|
- Row membership must stay tenant-isolated.
|
||||||
|
- Missing-target rendering must preserve current operator hints.
|
||||||
|
- Render-time behavior must remain DB-only with no Graph access.
|
||||||
|
|
||||||
|
### RequiredPermissionsTableState
|
||||||
|
|
||||||
|
**Type**: page-owned derived table state
|
||||||
|
**Source**: native Filament table filters and search on `TenantRequiredPermissions`
|
||||||
|
|
||||||
|
| Field | Type | Notes |
|
||||||
|
|------|------|-------|
|
||||||
|
| `routeTenantExternalId` | string | Authoritative tenant scope from the route |
|
||||||
|
| `status` | string | Allowed values: `missing`, `present`, `error`, `all` |
|
||||||
|
| `type` | string | Allowed values: `all`, `application`, `delegated` |
|
||||||
|
| `features` | list<string> | Zero or more selected feature keys |
|
||||||
|
| `search` | string | Native table search text |
|
||||||
|
| `seededFromQuery` | boolean | True only during initial mount when deeplink values were present |
|
||||||
|
|
||||||
|
**Validation rules**
|
||||||
|
|
||||||
|
- The route tenant always wins over tenant-like query values.
|
||||||
|
- Query values may seed `status`, `type`, `features`, and `search` only at initial mount.
|
||||||
|
- `features` must be a normalized unique list of known feature keys.
|
||||||
|
|
||||||
|
### RequiredPermissionsSummaryProjection
|
||||||
|
|
||||||
|
**Type**: derived page summary model
|
||||||
|
**Source**: `TenantRequiredPermissionsViewModelBuilder` evaluated against the currently active normalized filter state
|
||||||
|
|
||||||
|
| Field | Type | Notes |
|
||||||
|
|------|------|-------|
|
||||||
|
| `counts` | object | Existing counts for missing application, missing delegated, present, and error rows |
|
||||||
|
| `overall` | string or null | Existing overall readiness state |
|
||||||
|
| `freshness` | object | Existing freshness payload including stale or not stale |
|
||||||
|
| `featureImpacts` | list<object> | Existing per-feature impact summary |
|
||||||
|
| `copyPayloads` | object | Existing application and delegated copy payloads |
|
||||||
|
| `issues` | list<object> | Existing derived guidance and next-step content |
|
||||||
|
|
||||||
|
**Invariants**
|
||||||
|
|
||||||
|
- Summary and table rows must be derived from the same active filter state.
|
||||||
|
- Copy payload semantics must remain consistent with current expectations.
|
||||||
|
- Tenant scope must not be mutable through filter state.
|
||||||
|
|
||||||
|
### PermissionReviewRow
|
||||||
|
|
||||||
|
**Type**: derived table row
|
||||||
|
**Source**: `TenantRequiredPermissionsViewModelBuilder`
|
||||||
|
|
||||||
|
| Field | Type | Notes |
|
||||||
|
|------|------|-------|
|
||||||
|
| `permissionKey` | string | Stable permission identifier |
|
||||||
|
| `type` | string | `application` or `delegated` |
|
||||||
|
| `status` | string | Current permission review status |
|
||||||
|
| `description` | string | Human-readable permission description |
|
||||||
|
| `features` | list<string> | Feature tags associated with the permission |
|
||||||
|
| `details` | object | Existing supporting metadata used for inline review only |
|
||||||
|
|
||||||
|
### EvidenceOverviewTableState
|
||||||
|
|
||||||
|
**Type**: workspace-context table state
|
||||||
|
**Source**: native Filament table search and optional query-seeded entitled tenant prefilter
|
||||||
|
|
||||||
|
| Field | Type | Notes |
|
||||||
|
|------|------|-------|
|
||||||
|
| `workspaceId` | int | Required current workspace context |
|
||||||
|
| `authorizedTenantIds` | list<int> | Entitled tenant ids available to the actor |
|
||||||
|
| `tenantFilter` | int or null | Current entitled tenant prefilter, nullable when not active |
|
||||||
|
| `search` | string | Native table search across tenant-facing row labels |
|
||||||
|
| `seededFromQuery` | boolean | True only when the initial request carried a prefilter |
|
||||||
|
|
||||||
|
**Validation rules**
|
||||||
|
|
||||||
|
- `tenantFilter` must be null or one of the actor's entitled tenant ids.
|
||||||
|
- Missing workspace membership continues to produce `404`.
|
||||||
|
- Non-entitled tenant ids must not leak through filter state, row counts, or drilldowns.
|
||||||
|
|
||||||
|
### EvidenceOverviewRow
|
||||||
|
|
||||||
|
**Type**: derived workspace report row
|
||||||
|
**Source**: current snapshot query plus `ArtifactTruthPresenter`
|
||||||
|
|
||||||
|
| Field | Type | Notes |
|
||||||
|
|------|------|-------|
|
||||||
|
| `tenantId` | int | Entitled tenant identifier |
|
||||||
|
| `tenantName` | string | Current display label |
|
||||||
|
| `snapshotId` | int | Current active snapshot id for drilldown |
|
||||||
|
| `artifactTruth` | object | Existing truth badge and explanation payload |
|
||||||
|
| `freshness` | object | Existing freshness badge payload |
|
||||||
|
| `generatedAt` | string or null | Timestamp label |
|
||||||
|
| `missingDimensions` | int | Existing burden metric |
|
||||||
|
| `staleDimensions` | int | Existing burden metric |
|
||||||
|
| `nextStep` | string | Existing next-step text |
|
||||||
|
| `viewUrl` | string | Current tenant evidence drilldown URL |
|
||||||
|
|
||||||
|
**Invariants**
|
||||||
|
|
||||||
|
- Row drilldowns must stay workspace-safe and tenant-entitlement-safe.
|
||||||
|
- Derived-state memoization must remain effective.
|
||||||
|
- Render-time behavior must remain DB-only.
|
||||||
|
|
||||||
|
### CleanupAdmissionCandidate
|
||||||
|
|
||||||
|
**Type**: planning-only admission check
|
||||||
|
**Source**: implementation audit only when a possible extra hit is discovered
|
||||||
|
|
||||||
|
| Field | Type | Notes |
|
||||||
|
|------|------|-------|
|
||||||
|
| `surfaceKey` | string | Stable human-readable identifier |
|
||||||
|
| `path` | string | File or route path for the potential extra surface |
|
||||||
|
| `matchesProblemClass` | boolean | Must be true to qualify |
|
||||||
|
| `opensArchitectureQuestion` | boolean | Must be false to qualify |
|
||||||
|
| `decision` | string | `include` or `defer` |
|
||||||
|
| `reason` | string | Explicit justification for the decision |
|
||||||
|
|
||||||
|
## State Transition Rules
|
||||||
|
|
||||||
|
### Rule 1 - Deeplink seed to native active state
|
||||||
|
|
||||||
|
- Initial request query values may seed filter state on `TenantRequiredPermissions` and `EvidenceOverview`.
|
||||||
|
- After initial mount, active state belongs to the native page table or component, not to `request()`.
|
||||||
|
|
||||||
|
### Rule 2 - Route scope remains authoritative
|
||||||
|
|
||||||
|
- `TenantRequiredPermissions` may never replace its route tenant from query values.
|
||||||
|
- Inventory dependency state may never replace the current detail record or tenant context.
|
||||||
|
- Evidence overview may never reveal non-entitled tenant rows through a prefilter.
|
||||||
|
|
||||||
|
### Rule 3 - No new persistence or mirrored helper truth
|
||||||
|
|
||||||
|
- Filter state stays session-backed or Livewire-backed only where Filament already provides that behavior.
|
||||||
|
- No new database table, JSON helper artifact, or persisted UI-state mirror is introduced.
|
||||||
|
|
||||||
|
## Safety Rules
|
||||||
|
|
||||||
|
- No cleaned surface may introduce a second wrapper contract that simply restyles the current non-native behavior.
|
||||||
|
- No cleaned surface may widen current workspace or tenant scope behavior.
|
||||||
|
- No cleaned surface may lose current empty-state meaning, next-step clarity, or inspect destination correctness.
|
||||||
|
- No page or component may call Graph or other remote APIs during render as part of this cleanup.
|
||||||
|
|
||||||
|
## Planned Test Mapping
|
||||||
|
|
||||||
|
| Model / Rule | Existing Coverage | Planned Additions |
|
||||||
|
|---|---|---|
|
||||||
|
| `DependencyEdgesTableState` | `tests/Feature/InventoryItemDependenciesTest.php`, dependency tenant-isolation and query-service tests | native component test for direction and relationship interaction |
|
||||||
|
| `RequiredPermissionsTableState` | `tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php`, unit filter normalization tests | page-level native table test |
|
||||||
|
| `RequiredPermissionsSummaryProjection` | current unit tests for freshness, overall state, feature impacts, and copy payloads | page-level summary consistency assertions |
|
||||||
|
| `EvidenceOverviewTableState` | `tests/Feature/Evidence/EvidenceOverviewPageTest.php` | native table assertions and any new table-standard guard alignment |
|
||||||
|
| `EvidenceOverviewRow` DB-only invariant | `tests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php` | update assertions to reflect native table rendering without losing memoization guarantees |
|
||||||
296
specs/196-hard-filament-nativity-cleanup/plan.md
Normal file
296
specs/196-hard-filament-nativity-cleanup/plan.md
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
# Implementation Plan: Hard Filament Nativity Cleanup
|
||||||
|
|
||||||
|
**Branch**: `196-hard-filament-nativity-cleanup` | **Date**: 2026-04-13 | **Spec**: `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/196-hard-filament-nativity-cleanup/spec.md`
|
||||||
|
**Input**: Feature specification from `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/196-hard-filament-nativity-cleanup/spec.md`
|
||||||
|
|
||||||
|
**Note**: This plan keeps the work inside the existing Filament v5 / Livewire v4 page layer, the current derived view-model services, the existing dependency query and target-resolution services, and the current focused RBAC and reporting tests. It explicitly avoids adding a new runtime UI framework, new persistence, or a broader shell or monitoring-state architecture.
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
Remove the three hard nativity bypasses called out by Spec 196 by reusing repo-proven native Filament patterns. Convert `EvidenceOverview` and `TenantRequiredPermissions` into page-owned native table surfaces with native filter state and unchanged scope semantics. Replace the GET-form dependency micro-UI on inventory item detail with an embedded Livewire table component that owns direction and relationship state inside the current detail surface. Preserve existing domain truth, authorization, empty states, and drilldowns, and prove the cleanup through focused feature, Livewire, RBAC, and Filament guard coverage.
|
||||||
|
|
||||||
|
## Technical Context
|
||||||
|
|
||||||
|
**Language/Version**: PHP 8.4.15
|
||||||
|
**Primary Dependencies**: Laravel 12, Filament v5, Livewire v4, Pest v4, Tailwind CSS v4, existing `DependencyQueryService`, `DependencyTargetResolver`, `TenantRequiredPermissionsViewModelBuilder`, `ArtifactTruthPresenter`, `WorkspaceContext`, Filament `InteractsWithTable`, Filament `TableComponent`, and existing badge and action-surface helpers
|
||||||
|
**Storage**: PostgreSQL through existing tenant-owned and workspace-context models (`InventoryItem`, `InventoryLink`, `TenantPermission`, `EvidenceSnapshot`, `TenantReview`); no schema change planned
|
||||||
|
**Testing**: Pest feature, Livewire, unit, and existing guard tests run through Laravel Sail; browser smoke only if an implementation detail proves impossible to cover with existing feature or Livewire layers
|
||||||
|
**Target Platform**: Laravel monolith web application under `apps/platform`, spanning tenant-context admin routes under `/admin/t/{tenant}/...`, tenant-specific admin routes under `/admin/tenants/{tenant:external_id}/...`, and workspace-context canonical admin routes under `/admin/...`
|
||||||
|
**Project Type**: web application
|
||||||
|
**Performance Goals**: Preserve DB-only render behavior, keep dependency and evidence rendering free of Graph calls, avoid request-reload control flows, preserve current row-count and summary derivation cost, and avoid introducing extra persistence or polling
|
||||||
|
**Constraints**: No new persistence, no new enum or status family, no new wrapper microframework, no global shell or monitoring-state refactor, no provider or panel registration changes, no weakening of current 404 or 403 semantics, no destructive-action expansion, and no new asset pipeline work
|
||||||
|
**Scale/Scope**: 3 core surfaces, 1 embedded tenant detail micro-surface, 1 tenant workflow page, 1 workspace report page, and a focused verification pack touching roughly 12 existing or new test files; optional extra hits are allowed only if no new architecture question opens
|
||||||
|
|
||||||
|
## Constitution Check
|
||||||
|
|
||||||
|
*GATE: Passed before Phase 0 research. Re-checked after Phase 1 design and still passing.*
|
||||||
|
|
||||||
|
| Principle | Pre-Research | Post-Design | Notes |
|
||||||
|
|-----------|--------------|-------------|-------|
|
||||||
|
| Inventory-first / snapshots-second | PASS | PASS | Inventory dependencies and evidence overview remain read-only views over existing inventory and evidence truth. |
|
||||||
|
| Read/write separation | PASS | PASS | The cleanup changes interaction contracts only. Existing follow-up writes remain on their current confirmed destinations. |
|
||||||
|
| Graph contract path | N/A | N/A | No new Graph calls or contract-registry changes are introduced. |
|
||||||
|
| Deterministic capabilities | PASS | PASS | Existing capability registries, tenant access checks, and page authorization remain authoritative. |
|
||||||
|
| Workspace + tenant isolation | PASS | PASS | Tenant required permissions keeps the route tenant authoritative; evidence overview keeps workspace-context entitlement filtering; inventory detail remains tenant-context scoped. |
|
||||||
|
| RBAC-UX authorization semantics | PASS | PASS | Non-members remain `404`, in-scope capability denial remains unchanged, and no new mutation path bypasses server-side authorization. |
|
||||||
|
| Run observability / Ops-UX | PASS | PASS | No new `OperationRun` flow is introduced. Existing run-linked destinations remain unchanged. |
|
||||||
|
| Data minimization | PASS | PASS | No new persisted UI-state mirror or helper artifact is added, and DB-only rendering remains required. |
|
||||||
|
| Proportionality / anti-bloat | PASS | PASS | The design reuses existing Filament patterns and adds no new persistence or generic UI layer. |
|
||||||
|
| UI semantics / few layers | PASS | PASS | The plan maps directly from current domain truth to native UI primitives without a new presenter framework. |
|
||||||
|
| Filament-native UI | PASS | PASS | All three target surfaces move toward native Filament tables, filters, or shared primitives and away from pseudo-native contracts. |
|
||||||
|
| Surface taxonomy / decision-first roles | PASS | PASS | Inventory dependencies remains a secondary context sub-surface; tenant required permissions and evidence overview remain primary decision surfaces. |
|
||||||
|
| Filament v5 / Livewire v4 compliance | PASS | PASS | All touched surfaces remain inside the current Filament v5 + Livewire v4 stack. |
|
||||||
|
| Provider registration location | PASS | PASS | No provider changes are required; Laravel 11+ provider registration remains in `apps/platform/bootstrap/providers.php`. |
|
||||||
|
| Global search hard rule | PASS | PASS | No searchable resource is added or modified. `TenantRequiredPermissions` and `EvidenceOverview` are pages, and inventory resource search behavior is unchanged. |
|
||||||
|
| Destructive action safety | PASS | PASS | No new destructive action is introduced. Existing destructive follow-up actions remain on their current confirmed surfaces. |
|
||||||
|
| Asset strategy | PASS | PASS | No new global or on-demand assets are required. Existing deployment handling of `cd apps/platform && php artisan filament:assets` remains unchanged. |
|
||||||
|
|
||||||
|
## Filament-Specific Compliance Notes
|
||||||
|
|
||||||
|
- **Livewire v4.0+ compliance**: The implementation remains entirely inside Filament v5 + Livewire v4 and does not introduce legacy Filament or Livewire APIs.
|
||||||
|
- **Provider registration location**: No provider changes are required; panel providers remain registered in `apps/platform/bootstrap/providers.php`.
|
||||||
|
- **Global search**: No resource search behavior changes. `InventoryItemResource` already has a view page, but this spec does not change its global-search status. `TenantRequiredPermissions` and `EvidenceOverview` remain pages, not searchable resources.
|
||||||
|
- **Destructive actions**: No new destructive actions are added. Existing linked destinations retain their current confirmation and authorization behavior.
|
||||||
|
- **Asset strategy**: No new assets are planned. Existing deployment handling of `cd apps/platform && php artisan filament:assets` remains sufficient and unchanged.
|
||||||
|
- **Testing plan**: Cover the cleanup through `InventoryItemDependenciesTest`, a new Livewire or table-component dependency test, `TenantRequiredPermissionsTrustedStateTest`, a new required-permissions page-table test, `EvidenceOverviewPageTest`, `EvidenceOverviewDerivedStateMemoizationTest`, and guard coverage such as `FilamentTableStandardsGuardTest` where native table adoption becomes guardable.
|
||||||
|
|
||||||
|
## Phase 0 Research
|
||||||
|
|
||||||
|
Research outcomes are captured in `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/196-hard-filament-nativity-cleanup/research.md`.
|
||||||
|
|
||||||
|
Key decisions:
|
||||||
|
|
||||||
|
- Reuse the repo's existing native page-table pattern from `ReviewRegister` and `InventoryCoverage` for `TenantRequiredPermissions` and `EvidenceOverview`.
|
||||||
|
- Keep `TenantRequiredPermissions` and `EvidenceOverview` on derived data and current services instead of adding new projections, tables, or materialized helper models.
|
||||||
|
- Replace inventory dependency GET-form controls with an embedded Livewire `TableComponent` because the surface is detail-context and not a true relation manager or a standalone page.
|
||||||
|
- Treat query parameters as one-time seed or deeplink inputs only; after mount, native page or component state owns filter interaction.
|
||||||
|
- No additional low-risk same-class hit is confirmed in planning; default implementation scope stays at the three named core surfaces unless implementation audit finds one trivial match that does not widen scope.
|
||||||
|
- Extend existing focused tests and the current Filament table guard where possible instead of introducing a new browser-only verification layer.
|
||||||
|
|
||||||
|
## Phase 1 Design
|
||||||
|
|
||||||
|
Design artifacts are created under `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/196-hard-filament-nativity-cleanup/`:
|
||||||
|
|
||||||
|
- `research.md`: implementation-shape decisions and rejected alternatives for each surface
|
||||||
|
- `data-model.md`: derived UI-state and row-projection models for dependency scope, required-permissions filtering, and evidence overview rows
|
||||||
|
- `contracts/filament-nativity-cleanup.logical.openapi.yaml`: internal logical contract for page state, derived rows, scope rules, and deeplink semantics
|
||||||
|
- `quickstart.md`: implementation and verification sequence for the feature
|
||||||
|
|
||||||
|
Design highlights:
|
||||||
|
|
||||||
|
- `EvidenceOverview` adopts `InteractsWithTable` + `HasTable` and keeps derived rows via a records callback similar to `InventoryCoverage`.
|
||||||
|
- `TenantRequiredPermissions` adopts a native table and native table-owned filter state while keeping summary, copy, and guidance sections above the table body.
|
||||||
|
- Inventory dependencies stays embedded on inventory detail but moves its interactive controls into a dedicated Livewire table component rather than a request-driven Blade fragment.
|
||||||
|
- Existing domain services stay authoritative: dependency rows still come from `DependencyQueryService` and `DependencyTargetResolver`; permission truth still comes from `TenantRequiredPermissionsViewModelBuilder` when an adapter is needed; evidence truth still comes from `ArtifactTruthPresenter` and current snapshot queries.
|
||||||
|
- No new schema, enum, or shared microframework is introduced.
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
### Documentation (this feature)
|
||||||
|
|
||||||
|
```text
|
||||||
|
specs/196-hard-filament-nativity-cleanup/
|
||||||
|
├── plan.md
|
||||||
|
├── research.md
|
||||||
|
├── data-model.md
|
||||||
|
├── quickstart.md
|
||||||
|
├── spec.md
|
||||||
|
├── contracts/
|
||||||
|
│ └── filament-nativity-cleanup.logical.openapi.yaml
|
||||||
|
└── checklists/
|
||||||
|
└── requirements.md
|
||||||
|
```
|
||||||
|
|
||||||
|
### Source Code (repository root)
|
||||||
|
|
||||||
|
```text
|
||||||
|
apps/platform/
|
||||||
|
├── app/
|
||||||
|
│ ├── Filament/
|
||||||
|
│ │ ├── Pages/
|
||||||
|
│ │ │ ├── TenantRequiredPermissions.php # MODIFY
|
||||||
|
│ │ │ └── Monitoring/
|
||||||
|
│ │ │ └── EvidenceOverview.php # MODIFY
|
||||||
|
│ │ └── Resources/
|
||||||
|
│ │ └── InventoryItemResource.php # MODIFY
|
||||||
|
│ ├── Livewire/
|
||||||
|
│ │ └── InventoryItemDependencyEdgesTable.php # NEW
|
||||||
|
│ └── Services/
|
||||||
|
│ └── Intune/
|
||||||
|
│ └── TenantRequiredPermissionsViewModelBuilder.php # MODIFY or REVIEW FOR ADAPTERS
|
||||||
|
├── resources/
|
||||||
|
│ └── views/
|
||||||
|
│ └── filament/
|
||||||
|
│ ├── components/
|
||||||
|
│ │ └── dependency-edges.blade.php # MODIFY
|
||||||
|
│ └── pages/
|
||||||
|
│ ├── tenant-required-permissions.blade.php # MODIFY
|
||||||
|
│ └── monitoring/
|
||||||
|
│ └── evidence-overview.blade.php # MODIFY
|
||||||
|
└── tests/
|
||||||
|
├── Feature/
|
||||||
|
│ ├── InventoryItemDependenciesTest.php # MODIFY
|
||||||
|
│ ├── Evidence/
|
||||||
|
│ │ └── EvidenceOverviewPageTest.php # MODIFY
|
||||||
|
│ ├── Filament/
|
||||||
|
│ │ ├── EvidenceOverviewDerivedStateMemoizationTest.php # MODIFY
|
||||||
|
│ │ ├── InventoryItemDependencyEdgesTableTest.php # NEW
|
||||||
|
│ │ └── TenantRequiredPermissionsPageTest.php # NEW
|
||||||
|
│ ├── Guards/
|
||||||
|
│ │ └── FilamentTableStandardsGuardTest.php # MODIFY
|
||||||
|
│ └── Rbac/
|
||||||
|
│ └── TenantRequiredPermissionsTrustedStateTest.php # MODIFY
|
||||||
|
└── Unit/
|
||||||
|
├── TenantRequiredPermissionsFilteringTest.php # REUSE
|
||||||
|
├── TenantRequiredPermissionsCopyPayloadTest.php # REUSE
|
||||||
|
├── TenantRequiredPermissionsOverallStatusTest.php # REUSE
|
||||||
|
├── TenantRequiredPermissionsFeatureImpactTest.php # REUSE
|
||||||
|
└── TenantRequiredPermissionsFreshnessTest.php # REUSE
|
||||||
|
```
|
||||||
|
|
||||||
|
**Structure Decision**: Keep the work entirely inside the existing Laravel/Filament monolith under `apps/platform`. Add at most one new Livewire table component for the dependency sub-surface, then modify the three target page or resource files and focused tests. Do not add a new service layer, persistence shape, or cross-surface UI abstraction.
|
||||||
|
|
||||||
|
## Complexity Tracking
|
||||||
|
|
||||||
|
No constitution violation or BLOAT-triggered structural expansion is planned. The feature deliberately avoids new persistence, new enums, new UI taxonomies, or new cross-page infrastructure.
|
||||||
|
|
||||||
|
## Proportionality Review
|
||||||
|
|
||||||
|
Not triggered beyond the spec-level review already completed. The implementation plan adds no new enum, presenter framework, persisted entity, or registry. The narrowest correct implementation is to reuse native Filament tables and one embedded `TableComponent`.
|
||||||
|
|
||||||
|
## Implementation Strategy
|
||||||
|
|
||||||
|
Execution sequence for this plan is test-first at two levels: complete the shared test and guard scaffolding before story work starts, then land each story's focused tests before its implementation changes.
|
||||||
|
|
||||||
|
### Phase 0.5 - Establish shared test and guard scaffolding
|
||||||
|
|
||||||
|
Goal: create the blocking Spec 196 test entry points and shared guard coverage before surface refactors begin.
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
- Create the new focused test entry points for the dependency table component and required-permissions page table.
|
||||||
|
- Extend shared guard coverage for new native page-table expectations and faux-control regressions.
|
||||||
|
- Add shared regression coverage for mount-only query seeding versus authoritative scope on required permissions and evidence overview.
|
||||||
|
|
||||||
|
Tests:
|
||||||
|
|
||||||
|
- This phase establishes the focused test harness and is itself the blocking prerequisite for later story delivery.
|
||||||
|
|
||||||
|
### Phase A - Replace the inventory dependency GET form with an embedded Livewire table component
|
||||||
|
|
||||||
|
Goal: keep the dependencies surface on inventory item detail, but move direction and relationship controls into native component state instead of a request-driven Blade fragment.
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
- Introduce `App\Livewire\InventoryItemDependencyEdgesTable` as a Filament `TableComponent` that owns direction and relationship filter state.
|
||||||
|
- Keep the surface embedded in the current `InventoryItemResource` detail section rather than moving it to a standalone route or relation manager.
|
||||||
|
- Move the current request-query dependency fetch into the component so the Blade fragment no longer parses `request()` or submits a GET form.
|
||||||
|
- Preserve existing target rendering, missing-target labels, and tenant-isolated dependency resolution through `DependencyQueryService` and `DependencyTargetResolver`.
|
||||||
|
- Keep render-time behavior DB-only and preserve the no-Graph-call guard.
|
||||||
|
|
||||||
|
Tests:
|
||||||
|
|
||||||
|
- Extend the listed story tests before landing implementation changes.
|
||||||
|
- Modify `tests/Feature/InventoryItemDependenciesTest.php` to assert the preserved result logic while removing dependence on manual query-string filter submission.
|
||||||
|
- Add `tests/Feature/Filament/InventoryItemDependencyEdgesTableTest.php` to cover direction changes, relationship narrowing, missing-target rendering, and tenant isolation through the native component.
|
||||||
|
- Reuse existing unit and feature tests around `DependencyQueryService`, `DependencyTargetResolver`, and tenant isolation as domain and safety regression coverage.
|
||||||
|
|
||||||
|
### Phase B - Convert `TenantRequiredPermissions` into a native page-owned table and filter contract
|
||||||
|
|
||||||
|
Goal: remove pseudo-native filter controls while preserving the page's summary, guidance, copy payloads, and tenant-authoritative routing semantics.
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
- Add `HasTable` and `InteractsWithTable` to `App\Filament\Pages\TenantRequiredPermissions`.
|
||||||
|
- Replace the manual public filter properties and `updated*()` handlers with native table filters and native table search, using a derived-records callback because permission rows are view-model based rather than Eloquent-backed.
|
||||||
|
- Keep the route tenant authoritative and allow query parameters only to seed initial filter state when the page first mounts.
|
||||||
|
- Keep the summary, copy, and guidance blocks, but derive their values from the same normalized filter state that drives the native table rows.
|
||||||
|
- Preserve the current behavior where copy payloads remain driven by the intended filter dimensions and do not silently widen tenant scope.
|
||||||
|
|
||||||
|
Tests:
|
||||||
|
|
||||||
|
- Extend the listed story tests before landing implementation changes.
|
||||||
|
- Modify `tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php` to keep route-tenant authority and safe deeplink behavior after native filter adoption.
|
||||||
|
- Add `tests/Feature/Filament/TenantRequiredPermissionsPageTest.php` to cover native filter behavior, summary consistency, and no-results states.
|
||||||
|
- Reuse current unit tests for filtering, freshness, feature impacts, overall status, and copy payload derivation as unchanged domain-truth guards.
|
||||||
|
- Extend `tests/Feature/Guards/FilamentTableStandardsGuardTest.php` if the page becomes subject to shared page-table standards.
|
||||||
|
|
||||||
|
### Phase C - Convert `EvidenceOverview` into a native workspace table
|
||||||
|
|
||||||
|
Goal: remove the hand-built report table and make filtering, empty state, and row inspection native without changing workspace-safe scope behavior.
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
- Add `HasTable` and `InteractsWithTable` to `App\Filament\Pages\Monitoring\EvidenceOverview`.
|
||||||
|
- Move row generation out of the Blade table contract and into a native table records callback, following the derived-row pattern already used by `InventoryCoverage`.
|
||||||
|
- Convert the current `tenantFilter` query handling into native filter state seeded from an entitled tenant prefilter only.
|
||||||
|
- Add native table search across tenant-facing row labels.
|
||||||
|
- Keep the existing row inspect destination to tenant evidence detail through a single native inspect model.
|
||||||
|
- Replace the Blade table markup with a page wrapper that renders the native table and keeps any lightweight surrounding layout only if still needed.
|
||||||
|
|
||||||
|
Tests:
|
||||||
|
|
||||||
|
- Extend the listed story tests before landing implementation changes.
|
||||||
|
- Modify `tests/Feature/Evidence/EvidenceOverviewPageTest.php` to assert native table output, native search behavior, workspace safety, entitled-tenant filtering, and current drilldowns.
|
||||||
|
- Modify `tests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php` to keep DB-only derived-state guarantees after table conversion.
|
||||||
|
- Extend `tests/Feature/Guards/FilamentTableStandardsGuardTest.php` if the new page-owned table should now satisfy shared table standards.
|
||||||
|
|
||||||
|
### Phase D - Verification, guard alignment, and explicit scope stop
|
||||||
|
|
||||||
|
Goal: confirm the cleanup remains bounded to the three core surfaces and that the repo's existing guard layer reflects newly native table surfaces where appropriate.
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
- Extend guard coverage only where native table adoption now makes a page eligible for existing table standards.
|
||||||
|
- Run focused Sail verification for the modified feature, RBAC, and guard tests.
|
||||||
|
- Record the release close-out in `specs/196-hard-filament-nativity-cleanup/quickstart.md`, including cleaned surfaces, deferred themes, optional extra hits, and touched follow-up specs.
|
||||||
|
- Document any optional additional same-class hit only if it was truly included; otherwise record that no extra candidate was confirmed.
|
||||||
|
- Stop immediately if implementation reaches shared micro-UI family, monitoring-state, or shell-context architecture.
|
||||||
|
|
||||||
|
Tests:
|
||||||
|
|
||||||
|
- Focused feature and Livewire test pack for the three surfaces.
|
||||||
|
- Existing RBAC and derived-state regression tests retained.
|
||||||
|
- Pint run after touched files are complete.
|
||||||
|
|
||||||
|
## Risk Assessment
|
||||||
|
|
||||||
|
### Risk 1 - Scope creep into shared monitoring or detail-micro-UI architecture
|
||||||
|
|
||||||
|
Mitigation:
|
||||||
|
|
||||||
|
- Keep `EvidenceOverview` limited to native table conversion, not broader monitoring-shell cleanup.
|
||||||
|
- Keep inventory dependencies embedded on the existing detail page and do not generalize a new micro-UI framework.
|
||||||
|
- Reject any additional surface that opens shared-family or shell questions.
|
||||||
|
|
||||||
|
### Risk 2 - Deeplink or initial-state regressions on required permissions and evidence overview
|
||||||
|
|
||||||
|
Mitigation:
|
||||||
|
|
||||||
|
- Treat query values strictly as initial seed state.
|
||||||
|
- Keep route tenant and entitled tenant scope authoritative.
|
||||||
|
- Preserve and extend current trusted-state tests.
|
||||||
|
|
||||||
|
### Risk 3 - Derived-data performance or DB-only regressions after native table adoption
|
||||||
|
|
||||||
|
Mitigation:
|
||||||
|
|
||||||
|
- Reuse the repo's existing derived-records page pattern from `InventoryCoverage`.
|
||||||
|
- Preserve current eager-loading and memoization behavior.
|
||||||
|
- Keep the current no-Graph and DB-only tests in the verification pack.
|
||||||
|
|
||||||
|
### Risk 4 - Over-correcting custom read-only rendering into an unnecessary generic surface
|
||||||
|
|
||||||
|
Mitigation:
|
||||||
|
|
||||||
|
- Keep only the controls and state contract native.
|
||||||
|
- Allow custom read-only cell or row presentation to remain where it carries real domain value.
|
||||||
|
- Avoid relation-manager or standalone-page moves for the dependency section.
|
||||||
|
|
||||||
|
## Implementation Order Recommendation
|
||||||
|
|
||||||
|
1. Establish the shared test and guard scaffolding first so story work starts from the same blocking regression baseline captured in the task plan.
|
||||||
|
2. Replace inventory dependencies second, with the focused story tests landing before the implementation changes.
|
||||||
|
3. Convert `TenantRequiredPermissions` third, again extending the story tests before code changes.
|
||||||
|
4. Convert `EvidenceOverview` fourth, with its focused page and derived-state tests updated before the refactor lands.
|
||||||
|
5. Run the final focused verification pack, formatting, and release close-out last, and only then consider whether any optional same-class extra hit truly qualifies.
|
||||||
165
specs/196-hard-filament-nativity-cleanup/quickstart.md
Normal file
165
specs/196-hard-filament-nativity-cleanup/quickstart.md
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
# Quickstart: Hard Filament Nativity Cleanup
|
||||||
|
|
||||||
|
## Goal
|
||||||
|
|
||||||
|
Implement Spec 196 by replacing three pseudo-native UI contracts with native Filament or Livewire interaction models while preserving current scope, summaries, empty states, and drilldown behavior.
|
||||||
|
|
||||||
|
## Implementation Sequence
|
||||||
|
|
||||||
|
### 1. Prepare shared test and guard scaffolding
|
||||||
|
|
||||||
|
Touch:
|
||||||
|
|
||||||
|
- `apps/platform/tests/Feature/Filament/InventoryItemDependencyEdgesTableTest.php`
|
||||||
|
- `apps/platform/tests/Feature/Filament/TenantRequiredPermissionsPageTest.php`
|
||||||
|
- `apps/platform/tests/Feature/Guards/FilamentTableStandardsGuardTest.php`
|
||||||
|
- `apps/platform/tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php`
|
||||||
|
- `apps/platform/tests/Feature/Evidence/EvidenceOverviewPageTest.php`
|
||||||
|
|
||||||
|
Do:
|
||||||
|
|
||||||
|
- create the new focused surface-test entry points before story implementation starts
|
||||||
|
- add the shared guard expectations for new native page-table and faux-control regressions
|
||||||
|
- add the shared mount-only query-seeding regression coverage that later story work depends on
|
||||||
|
|
||||||
|
### 2. Replace the inventory dependency GET form with an embedded `TableComponent`
|
||||||
|
|
||||||
|
Touch:
|
||||||
|
|
||||||
|
- `apps/platform/app/Filament/Resources/InventoryItemResource.php`
|
||||||
|
- `apps/platform/app/Livewire/InventoryItemDependencyEdgesTable.php`
|
||||||
|
- `apps/platform/resources/views/filament/components/dependency-edges.blade.php`
|
||||||
|
|
||||||
|
Do:
|
||||||
|
|
||||||
|
- extend the focused dependency tests before landing implementation changes
|
||||||
|
- embed a native Filament `TableComponent` inside the existing inventory detail section
|
||||||
|
- move direction and relationship state into the component
|
||||||
|
- fetch dependency rows through current dependency services
|
||||||
|
- keep missing-target rendering and target-link behavior intact
|
||||||
|
|
||||||
|
Do not:
|
||||||
|
|
||||||
|
- create a new standalone route for dependencies
|
||||||
|
- convert the surface into a RelationManager
|
||||||
|
- keep `request()` as the primary interaction-state source
|
||||||
|
|
||||||
|
### 3. Convert `TenantRequiredPermissions` to a native page-owned filter and table contract
|
||||||
|
|
||||||
|
Touch:
|
||||||
|
|
||||||
|
- `apps/platform/app/Filament/Pages/TenantRequiredPermissions.php`
|
||||||
|
- `apps/platform/resources/views/filament/pages/tenant-required-permissions.blade.php`
|
||||||
|
- `apps/platform/app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php` only if a small adapter is needed
|
||||||
|
|
||||||
|
Do:
|
||||||
|
|
||||||
|
- extend the focused required-permissions tests before landing implementation changes
|
||||||
|
- add `HasTable` and `InteractsWithTable`
|
||||||
|
- replace pseudo-native filter controls with native filters and native search
|
||||||
|
- derive the summary, guidance, and copy payload blocks from the same normalized filter state that drives the table rows
|
||||||
|
- keep the route tenant authoritative and allow query values only as initial seed state
|
||||||
|
|
||||||
|
Do not:
|
||||||
|
|
||||||
|
- let query values redefine tenant scope
|
||||||
|
- split the page into a new resource or standalone workflow
|
||||||
|
- introduce a wrapper abstraction that merely hides the old filter bar
|
||||||
|
|
||||||
|
### 4. Convert `EvidenceOverview` to a native page-owned table
|
||||||
|
|
||||||
|
Touch:
|
||||||
|
|
||||||
|
- `apps/platform/app/Filament/Pages/Monitoring/EvidenceOverview.php`
|
||||||
|
- `apps/platform/resources/views/filament/pages/monitoring/evidence-overview.blade.php`
|
||||||
|
|
||||||
|
Do:
|
||||||
|
|
||||||
|
- extend the focused evidence overview tests before landing implementation changes
|
||||||
|
- add `HasTable` and `InteractsWithTable`
|
||||||
|
- move current row construction into a native table records callback
|
||||||
|
- convert the current tenant query prefilter into a native filter seeded from entitled query input only
|
||||||
|
- add native search across tenant-facing row labels
|
||||||
|
- keep row inspect behavior pointed at the existing tenant evidence drilldown
|
||||||
|
- keep empty-state behavior explicit and native
|
||||||
|
|
||||||
|
Do not:
|
||||||
|
|
||||||
|
- introduce a new read model or persistence layer
|
||||||
|
- widen the workspace-context route into a tenant-context route
|
||||||
|
- make remote calls during render
|
||||||
|
|
||||||
|
### 5. Run the final focused verification pack and formatting
|
||||||
|
|
||||||
|
Touch:
|
||||||
|
|
||||||
|
- `apps/platform/tests/Feature/InventoryItemDependenciesTest.php`
|
||||||
|
- `apps/platform/tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php`
|
||||||
|
- `apps/platform/tests/Feature/Evidence/EvidenceOverviewPageTest.php`
|
||||||
|
- `apps/platform/tests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php`
|
||||||
|
- `apps/platform/tests/Feature/Filament/InventoryItemDependencyEdgesTableTest.php`
|
||||||
|
- `apps/platform/tests/Feature/Filament/TenantRequiredPermissionsPageTest.php`
|
||||||
|
- `apps/platform/tests/Feature/Guards/FilamentTableStandardsGuardTest.php` if newly applicable
|
||||||
|
|
||||||
|
Do:
|
||||||
|
|
||||||
|
- preserve current scope and authorization assertions
|
||||||
|
- replace GET-form assumptions with native Livewire or table-state assertions
|
||||||
|
- keep DB-only and no-Graph render guarantees
|
||||||
|
- keep unit tests for permission filtering and copy payload logic as domain-truth guards
|
||||||
|
- run the full focused Sail pack and `pint` only after the three story slices are complete
|
||||||
|
|
||||||
|
### 6. Stop on scope boundaries
|
||||||
|
|
||||||
|
If implementation touches any of the following, stop and defer instead of half-solving them here:
|
||||||
|
|
||||||
|
- shared detail micro-UI contract work
|
||||||
|
- monitoring page-state architecture
|
||||||
|
- global context shell behavior
|
||||||
|
- verification report viewer families
|
||||||
|
- diff, settings, restore preview, or enterprise-detail layout families
|
||||||
|
|
||||||
|
### 7. Record the release close-out in this quickstart
|
||||||
|
|
||||||
|
When implementation is complete, update this file with a short close-out note that records:
|
||||||
|
|
||||||
|
- which surfaces were actually cleaned
|
||||||
|
- whether any optional same-class extra hit was included or explicitly rejected
|
||||||
|
- which related themes stayed out of scope and were deferred
|
||||||
|
- which follow-up specs or artifacts were touched
|
||||||
|
|
||||||
|
## Suggested Test Pack
|
||||||
|
|
||||||
|
Run the minimum targeted verification pack through Sail.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export PATH="/bin:/usr/bin:/usr/local/bin:$PATH"
|
||||||
|
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/InventoryItemDependenciesTest.php
|
||||||
|
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/InventoryItemDependencyEdgesTableTest.php
|
||||||
|
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php
|
||||||
|
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/TenantRequiredPermissionsPageTest.php
|
||||||
|
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Evidence/EvidenceOverviewPageTest.php
|
||||||
|
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php
|
||||||
|
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Guards/FilamentTableStandardsGuardTest.php
|
||||||
|
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/TenantRequiredPermissionsFilteringTest.php
|
||||||
|
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/TenantRequiredPermissionsCopyPayloadTest.php
|
||||||
|
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/TenantRequiredPermissionsOverallStatusTest.php
|
||||||
|
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/TenantRequiredPermissionsFeatureImpactTest.php
|
||||||
|
cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/TenantRequiredPermissionsFreshnessTest.php
|
||||||
|
cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent
|
||||||
|
```
|
||||||
|
|
||||||
|
## Manual Smoke Checklist
|
||||||
|
|
||||||
|
1. Open an inventory item detail page and confirm dependency direction and relationship changes happen without a foreign apply-and-reload workflow.
|
||||||
|
2. Open tenant required permissions and confirm the filter surface feels native, while summary counts, guidance, and copy flows remain correct.
|
||||||
|
3. Open evidence overview and confirm the table behaves like a native Filament report with clear empty state and row inspect behavior.
|
||||||
|
4. Confirm no cleaned surface leaks scope through query manipulation.
|
||||||
|
5. Confirm no implementation expanded into monitoring-state, shell, or shared micro-UI redesign work.
|
||||||
|
|
||||||
|
## Deployment Notes
|
||||||
|
|
||||||
|
- No migration is expected.
|
||||||
|
- No provider registration change is expected.
|
||||||
|
- No new assets are expected.
|
||||||
|
- Existing `cd apps/platform && php artisan filament:assets` deployment handling remains sufficient and unchanged.
|
||||||
90
specs/196-hard-filament-nativity-cleanup/research.md
Normal file
90
specs/196-hard-filament-nativity-cleanup/research.md
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
# Research: Hard Filament Nativity Cleanup
|
||||||
|
|
||||||
|
## Decision: Reuse the repo's existing native page-table pattern for `EvidenceOverview` and `TenantRequiredPermissions`
|
||||||
|
|
||||||
|
### Rationale
|
||||||
|
|
||||||
|
The codebase already has two strong native examples for page-owned tables outside normal resource index pages: `ReviewRegister` and `InventoryCoverage`. Both use `InteractsWithTable`, `HasTable`, native Filament filters, Filament-managed filter state, native empty states, and one consistent inspect model. That makes them the narrowest repo-consistent replacement for the two current page-level bypasses.
|
||||||
|
|
||||||
|
`EvidenceOverview` is currently a hand-built Blade report table, and `TenantRequiredPermissions` is currently a custom page with pseudo-native filter controls. Both are better modeled as page-owned native tables than as bespoke Blade contracts.
|
||||||
|
|
||||||
|
### Alternatives considered
|
||||||
|
|
||||||
|
- Keep the current Blade table and filter bars, but restyle them more convincingly: rejected because that preserves the separate contract instead of removing it.
|
||||||
|
- Move either surface into a Resource or RelationManager: rejected because both already have correct route and page ownership; only their internal interaction model is wrong.
|
||||||
|
|
||||||
|
## Decision: Keep both page-level surfaces on derived data instead of adding new projections or schema
|
||||||
|
|
||||||
|
### Rationale
|
||||||
|
|
||||||
|
`EvidenceOverview` rows are already derived from `EvidenceSnapshot`, `TenantReview`, and `ArtifactTruthPresenter`, while `TenantRequiredPermissions` rows and summaries are already derived through `TenantRequiredPermissionsViewModelBuilder`. The current product truth is sufficient. The problem is not missing data infrastructure, but the non-native way the data is exposed.
|
||||||
|
|
||||||
|
Using derived table records keeps the implementation proportional and avoids importing persistence or a second source of truth for UI state.
|
||||||
|
|
||||||
|
### Alternatives considered
|
||||||
|
|
||||||
|
- Add dedicated read models or materialized projections for overview rows: rejected because the spec is cleanup, not reporting-architecture expansion.
|
||||||
|
- Convert the permission or evidence pages into query-first Eloquent resources: rejected because the current derived summaries and guidance would still need a second layer and would not simplify the domain.
|
||||||
|
|
||||||
|
## Decision: Replace inventory dependency GET controls with an embedded Livewire `TableComponent`
|
||||||
|
|
||||||
|
### Rationale
|
||||||
|
|
||||||
|
The dependency surface is not a standalone page and not a true Eloquent relationship that should become a RelationManager. It is a detail-context sub-surface inside inventory item view. The narrowest native replacement is therefore an embedded Livewire `TableComponent` that owns direction and relationship state, renders native filters, and stays inside the current inventory detail section.
|
||||||
|
|
||||||
|
The repo already uses Filament `TableComponent` in `BackupSetPolicyPickerTable`, which proves the pattern is acceptable and reusable here.
|
||||||
|
|
||||||
|
### Alternatives considered
|
||||||
|
|
||||||
|
- Convert the dependency section into a RelationManager: rejected because dependency edges are query-driven, not a direct relationship manager surface.
|
||||||
|
- Move dependencies to a new standalone page: rejected because it would break the current inspect-one-record workflow and widen scope.
|
||||||
|
- Keep a custom Blade fragment with `wire:model` on raw inputs: rejected because that still leaves a pseudo-native control surface instead of a real native table contract.
|
||||||
|
|
||||||
|
## Decision: Query parameters may seed initial state, but they do not remain the authoritative interaction contract
|
||||||
|
|
||||||
|
### Rationale
|
||||||
|
|
||||||
|
Both `TenantRequiredPermissions` and `EvidenceOverview` have valid deeplink or workflow-continuity reasons to accept initial query values. The spec explicitly allows that. What needs to change is ongoing ownership of page-body state. After first mount, filter state must live in native page or component state rather than continuing to be reconstructed from `request()` on every interaction.
|
||||||
|
|
||||||
|
This preserves existing deeplink behavior without letting query values become a shadow state system.
|
||||||
|
|
||||||
|
### Alternatives considered
|
||||||
|
|
||||||
|
- Remove all query seeding entirely: rejected because the current product does rely on deeplink and continuity behavior.
|
||||||
|
- Keep query parameters as the main contract forever: rejected because that is the bypass pattern the spec exists to remove.
|
||||||
|
|
||||||
|
## Decision: Preserve custom read-only presentation where it carries domain value, but make control state native
|
||||||
|
|
||||||
|
### Rationale
|
||||||
|
|
||||||
|
The spec is not a repo-wide custom Blade purge. Some read-only rendering still carries useful domain formatting, especially for dependency target badges, missing-target hints, permission guidance blocks, and evidence explanation text. The actual harm sits in fake controls, manual GET submission, and hand-built primary table contracts.
|
||||||
|
|
||||||
|
The narrowest implementation therefore replaces the primary control and table contracts while allowing domain-specific read-only cells or layout blocks to remain when they do not create a second state system.
|
||||||
|
|
||||||
|
### Alternatives considered
|
||||||
|
|
||||||
|
- Force every touched surface into generic Filament markup only: rejected because it risks over-correction and would expand scope into broader micro-UI standardization.
|
||||||
|
- Leave custom presentation and custom control markup mixed together: rejected because it would keep the core nativity problem alive.
|
||||||
|
|
||||||
|
## Decision: No additional same-class low-risk hit is confirmed during planning
|
||||||
|
|
||||||
|
### Rationale
|
||||||
|
|
||||||
|
The planning audit found the three target surfaces clearly. It did not identify a fourth candidate that is both obviously the same problem class and clearly small enough to include without opening shared-family or shell questions. That means the safe default is to keep the implementation scope locked to the three named surfaces and only admit an extra hit if implementation discovers a truly trivial match.
|
||||||
|
|
||||||
|
### Alternatives considered
|
||||||
|
|
||||||
|
- Expand planning scope now to include visually similar custom Blade surfaces elsewhere in monitoring or verification: rejected because those families carry broader architecture and product-semantics questions already marked out of scope.
|
||||||
|
|
||||||
|
## Decision: Extend existing focused tests and guardrails rather than introducing a new browser-centric verification layer
|
||||||
|
|
||||||
|
### Rationale
|
||||||
|
|
||||||
|
The repo already has meaningful coverage for all three areas: dependency rendering and tenant isolation, required-permissions trusted-state behavior and view-model derivation, and evidence overview authorization and DB-only rendering. The cleanup should lean on that existing coverage, then add only the missing surface-level native-table or component assertions.
|
||||||
|
|
||||||
|
This keeps the feature aligned with `TEST-TRUTH-001` and avoids creating a heavier verification framework than the change requires.
|
||||||
|
|
||||||
|
### Alternatives considered
|
||||||
|
|
||||||
|
- Add a new browser suite for all three surfaces as the primary proof: rejected because most required outcomes are already testable with feature and Livewire tests.
|
||||||
|
- Rely only on manual smoke checks: rejected because the repo rules require automated coverage for changed behavior.
|
||||||
250
specs/196-hard-filament-nativity-cleanup/spec.md
Normal file
250
specs/196-hard-filament-nativity-cleanup/spec.md
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
# Feature Specification: Hard Filament Nativity Cleanup
|
||||||
|
|
||||||
|
**Feature Branch**: `[196-hard-filament-nativity-cleanup]`
|
||||||
|
**Created**: 2026-04-13
|
||||||
|
**Status**: Proposed
|
||||||
|
**Input**: User description: "Spec 196 - Hard Filament Nativity Cleanup"
|
||||||
|
|
||||||
|
## Spec Candidate Check *(mandatory - SPEC-GATE-001)*
|
||||||
|
|
||||||
|
- **Problem**: Three active admin surfaces signal native Filament behavior but still run on separate UI contracts: a GET-form dependency filter inside inventory detail, a plain-HTML filter bar on required permissions, and a hand-built evidence report table.
|
||||||
|
- **Today's failure**: Operators hit inconsistent filter behavior, apply-and-reload interaction, request-driven body state, and bespoke empty-state or navigation semantics inside surfaces that otherwise live in Filament and Livewire.
|
||||||
|
- **User-visible improvement**: Dependency review, permission follow-up, and evidence review feel like the rest of the admin product, with fewer foreign workflows and less hidden state drift.
|
||||||
|
- **Smallest enterprise-capable version**: Clean only the three confirmed bypass surfaces and only the parts that create the non-native contract; keep larger shell, monitoring-state, verification-report, and shared micro-UI families out of scope.
|
||||||
|
- **Explicit non-goals**: No global context-shell redesign, no monitoring page-state architecture rewrite, no repo-wide custom Blade purge, no special visualization rework, no badge-only polish sweep, and no new CI guardrail, review-enforcement, or constitution framework in this spec.
|
||||||
|
- **Permanent complexity imported**: Focused surface refactors, targeted regression coverage, and one close-out note. No new models, tables, enums, abstractions, or cross-surface UI framework are introduced.
|
||||||
|
- **Why now**: These are already active operator surfaces with real maintenance and consistency cost, and they are the clearest low-dispute cleanup targets before later specs touch larger UI families.
|
||||||
|
- **Why not local**: The harm comes from the same problem class repeating across multiple live surfaces. One-off cosmetic edits would leave the same parallel contracts and drift pattern intact.
|
||||||
|
- **Approval class**: Cleanup
|
||||||
|
- **Red flags triggered**: One mild red flag: multiple surfaces are touched in one spec. This is justified because all included surfaces share the same unnecessary nativity bypass and remain bounded to three concrete entry points plus optional same-class low-risk extras.
|
||||||
|
- **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexitat: 1 | Produktnahe: 2 | Wiederverwendung: 2 | **Gesamt: 11/12**
|
||||||
|
- **Decision**: approve
|
||||||
|
|
||||||
|
## Spec Scope Fields *(mandatory)*
|
||||||
|
|
||||||
|
- **Scope**: tenant + workspace canonical-view cleanup
|
||||||
|
- **Primary Routes**:
|
||||||
|
- `/admin/t/{tenant}/inventory/inventory-items/{record}`
|
||||||
|
- `/admin/tenants/{tenant:external_id}/required-permissions`
|
||||||
|
- `/admin/evidence/overview`
|
||||||
|
- **Data Ownership**: Inventory dependencies continue to read tenant-owned inventory items and dependency edges in tenant context. Tenant required permissions continues to read tenant-owned permission verification truth and provider guidance for a single tenant. Evidence overview continues to read tenant-owned evidence snapshots inside a workspace-context route. This spec adds no new persistence and does not move ownership boundaries.
|
||||||
|
- **RBAC**: Inventory dependencies stays under tenant-context inventory detail and keeps existing tenant membership plus tenant entitlement requirements. Tenant required permissions keeps workspace and tenant entitlement, preserves route-tenant authority, and remains deny-as-not-found for non-members. Evidence overview remains workspace-context, still requires workspace membership, and must only reveal entitled tenant rows and drilldowns.
|
||||||
|
|
||||||
|
For canonical-view specs, the spec MUST define:
|
||||||
|
|
||||||
|
- **Default filter behavior when tenant-context is active**: Evidence overview may honor an entitled tenant prefilter for deeplink or workflow continuity, but it remains a workspace-context page and must not silently redefine scope from unrelated tenant-like query values.
|
||||||
|
- **Explicit entitlement checks preventing cross-tenant leakage**: Evidence overview rows, filters, and row drilldowns must resolve only within the current workspace and the viewer's entitled tenant set. Unauthorized tenant ids must not reveal rows, row counts, or drilldown targets.
|
||||||
|
|
||||||
|
## Decision-First Surface Role *(mandatory when operator-facing surfaces are changed)*
|
||||||
|
|
||||||
|
| Surface | Decision Role | Human-in-the-loop Moment | Immediately Visible for First Decision | On-Demand Detail / Evidence | Why This Is Primary or Why Not | Workflow Alignment | Attention-load Reduction |
|
||||||
|
|---|---|---|---|---|---|---|---|
|
||||||
|
| Inventory item dependencies section | Secondary Context Surface | While inspecting one inventory item, decide whether a related object explains impact or follow-up | Current inventory item context, dependency direction scope, relationship family, matching edges, missing-target markers | Linked target pages, raw references, last-known-name hints | Not primary because the operator's main decision remains about the current inventory item detail | Follows inspect-one-record workflow instead of creating a side workflow | Removes apply-and-reload detours inside detail view |
|
||||||
|
| Tenant required permissions | Primary Decision Surface | Decide whether tenant consent or verification follow-up is required and what action to take next | Overall state, freshness, missing application vs delegated counts, active filters, matching permission rows | Copy payloads, consent guidance, provider-connection destination | Primary because the page itself answers what permission action is next for this tenant | Follows tenant permission follow-up workflow instead of request-parameter reconstruction | Keeps filter state and guidance in one page-owned contract |
|
||||||
|
| Evidence overview | Primary Decision Surface | Decide which tenant's evidence needs refresh or review next | Tenant, artifact truth, freshness, burden, next step, inspect affordance | Tenant evidence detail, deeper snapshot explanation, row-specific follow-up context | Primary because it is the workspace evidence review list where operators choose the next follow-up target | Follows workspace evidence-review workflow instead of bespoke report markup | Native table behavior reduces bespoke scanning, empty-state, and drilldown rules |
|
||||||
|
|
||||||
|
## UI/UX Surface Classification *(mandatory when operator-facing surfaces are changed)*
|
||||||
|
|
||||||
|
| Surface | Action Surface Class | Surface Type | Likely Next Operator Action | Primary Inspect/Open Model | Row Click | Secondary Actions Placement | Destructive Actions Placement | Canonical Collection Route | Canonical Detail Route | Scope Signals | Canonical Noun | Critical Truth Visible by Default | Exception Type / Justification |
|
||||||
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
||||||
|
| Inventory item dependencies section | Detail / Inspect | Detail-first resource sub-surface | Open a dependency target or change dependency scope | Current inventory item detail with linked dependency targets | forbidden | Inline non-destructive section controls only | none | `/admin/t/{tenant}/inventory/inventory-items/{record}` | Same route plus linked target destinations | Active tenant, current inventory item, dependency direction, relationship scope | Inventory item dependencies / dependency edge | Current record context, relationship family, missing-target state | Embedded detail micro-surface remains custom for domain-specific read-only edge rendering, but not for primary controls |
|
||||||
|
| Tenant required permissions | List / Guidance / Diagnostic | List-only read-first workflow page | Grant consent, rerun verification, or narrow the current filter state | Inline page itself | forbidden | Safe guidance and copy actions remain secondary in page sections or header | none | `/admin/tenants/{tenant:external_id}/required-permissions` | Same page | Current workspace, current tenant, freshness, active filters | Required permissions / permission row | Overall readiness, freshness, missing counts, active filter state | Permission rows remain an inline review matrix rather than a separate inspect route |
|
||||||
|
| Evidence overview | List / Table / Report | Read-only registry report | Open tenant evidence for the row that needs attention | Full-row inspect into tenant evidence detail | required | Header clear-filter action only; any safe secondary action stays clearly secondary | none | `/admin/evidence/overview` | Tenant evidence snapshot view for the selected row | Current workspace, entitled-tenant filter, artifact truth, freshness | Evidence overview / evidence snapshot | Artifact truth, freshness, burden, next step | none |
|
||||||
|
|
||||||
|
## Operator Surface Contract *(mandatory when operator-facing surfaces are changed)*
|
||||||
|
|
||||||
|
| Surface | Primary Persona | Decision / Operator Action Supported | Surface Type | Primary Operator Question | Default-visible Information | Diagnostics-only Information | Status Dimensions Used | Mutation Scope | Primary Actions | Dangerous Actions |
|
||||||
|
|---|---|---|---|---|---|---|---|---|---|---|
|
||||||
|
| Inventory item dependencies section | Tenant operator reviewing one inventory item | Decide whether related objects explain the current item and which target to inspect next | Detail micro-surface | Which dependencies matter for this item right now? | Current direction and relationship scope, grouped edges, missing-target markers, target badges | Raw references, last-known names, deeper target detail | relationship direction, relationship type, target availability | none; read-only inspect flow | Change direction scope, change relationship scope, open target | none |
|
||||||
|
| Tenant required permissions | Tenant operator or tenant manager | Decide whether consent, delegated follow-up, or verification rerun is needed | Read-first workflow page | What permission gap blocks this tenant right now and what should happen next? | Overall state, freshness, counts, active filters, matching permission rows | Copy payload detail, consent guidance, provider-connection management destination | overall readiness, freshness, permission status, permission type | read-only page with outbound follow-up links; no new mutation starts on this page | Adjust filters, open consent guidance, rerun verification, manage provider connection | none introduced by this spec |
|
||||||
|
| Evidence overview | Workspace operator | Decide which tenant evidence snapshot needs review or refresh next | Workspace report table | Which tenant needs evidence follow-up right now? | Tenant row, artifact truth, freshness, burden, next step, inspect affordance | Deeper snapshot explanation inside tenant evidence detail | artifact truth, freshness, evidence burden | none; read-only drilldown | Change filters, open tenant evidence row | none |
|
||||||
|
|
||||||
|
## Proportionality Review *(mandatory when structural complexity is introduced)*
|
||||||
|
|
||||||
|
- **New source of truth?**: no
|
||||||
|
- **New persisted entity/table/artifact?**: no
|
||||||
|
- **New abstraction?**: no
|
||||||
|
- **New enum/state/reason family?**: no
|
||||||
|
- **New cross-domain UI framework/taxonomy?**: no
|
||||||
|
- **Current operator problem**: Active admin surfaces inside existing Filament and Livewire context still bypass native primitives, forcing operators and maintainers to juggle extra contracts for simple filters and tables.
|
||||||
|
- **Existing structure is insufficient because**: The current harm comes from the mismatch itself. These surfaces already live in Filament and Livewire, so keeping plain HTML control contracts, request-driven state, or hand-built report tables preserves avoidable drift rather than solving a domain gap.
|
||||||
|
- **Narrowest correct implementation**: Convert only the three clear bypasses and only the parts that create the non-native contract. Keep legitimate custom read-only presentation and larger shell, monitoring-state, and shared-family questions out of scope.
|
||||||
|
- **Ownership cost**: Bounded surface refactors, focused tests, and one close-out note. No new domain model, state family, or UI framework is introduced.
|
||||||
|
- **Alternative intentionally rejected**: A repo-wide Filament purity sweep, a global shell or state redesign, or wrapper abstractions that merely hide the same non-native contract.
|
||||||
|
- **Release truth**: current-release cleanup that removes existing drift before later specs tackle larger UI families
|
||||||
|
|
||||||
|
## User Scenarios & Testing *(mandatory)*
|
||||||
|
|
||||||
|
### User Story 1 - Review Dependencies Without A Foreign Workflow (Priority: P1)
|
||||||
|
|
||||||
|
While inspecting an inventory item, an operator can change dependency scope and understand the resulting edges without submitting a separate GET form or feeling like the detail page has switched into a different mini app.
|
||||||
|
|
||||||
|
**Why this priority**: The inventory detail page already owns the current record context. A foreign interaction model inside that detail page directly harms comprehension and confidence.
|
||||||
|
|
||||||
|
**Independent Test**: Can be tested by opening an inventory item detail page, changing dependency direction and relationship scope, and verifying that the same matching edges, missing-target markers, and empty states appear without a manual apply-and-reload contract.
|
||||||
|
|
||||||
|
**Acceptance Scenarios**:
|
||||||
|
|
||||||
|
1. **Given** an inventory item with inbound and outbound edges, **When** the operator changes dependency direction, **Then** the visible edge set updates within the current detail surface without a separate GET apply workflow.
|
||||||
|
2. **Given** an inventory item with multiple relationship families, **When** the operator narrows relationship scope, **Then** only matching edges remain and the current record context stays intact.
|
||||||
|
3. **Given** an inventory item with no edges for the selected scope, **When** the operator applies that scope, **Then** the surface shows the same no-results meaning as today without losing tenant or record context.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### User Story 2 - Filter Required Permissions In One Native Page Contract (Priority: P1)
|
||||||
|
|
||||||
|
On the tenant required-permissions page, an operator can adjust status, type, feature, and search state through one native interaction contract while preserving the current tenant, guidance, copy flows, and verification follow-up paths.
|
||||||
|
|
||||||
|
**Why this priority**: This page is already a live operator decision surface. If its primary controls remain pseudo-native, the page keeps teaching a separate contract for a core admin workflow.
|
||||||
|
|
||||||
|
**Independent Test**: Can be tested by loading the required-permissions page with and without deeplink query values, adjusting filters live, and verifying that the route tenant stays authoritative while results, counts, and copy payloads remain correct.
|
||||||
|
|
||||||
|
**Acceptance Scenarios**:
|
||||||
|
|
||||||
|
1. **Given** a tenant required-permissions page with stored verification data, **When** the operator changes status, type, feature, or search state, **Then** the matching permission rows, counts, and related guidance update without a separate plain-HTML filter bar contract.
|
||||||
|
2. **Given** deeplink query values for status, type, or search, **When** the page first loads, **Then** the page may seed initial state from the deeplink while keeping the route tenant authoritative.
|
||||||
|
3. **Given** tenant-like query values that point at a different tenant, **When** the page loads for the current tenant route, **Then** the current route tenant remains the only authoritative tenant scope.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### User Story 3 - Review Evidence Through A Native Workspace Table (Priority: P2)
|
||||||
|
|
||||||
|
On the evidence overview, a workspace operator can scan, filter, and open the next tenant evidence item through a native table surface with consistent empty-state and row-inspect behavior.
|
||||||
|
|
||||||
|
**Why this priority**: The page is clearly a tabular workspace review surface. Keeping it as a hand-built report table preserves bespoke behavior where native table semantics are a better fit.
|
||||||
|
|
||||||
|
**Independent Test**: Can be tested by loading the workspace evidence overview with multiple entitled tenants, applying an entitled tenant prefilter, and verifying that rows, empty state, and drilldown behavior remain workspace-safe while the page behaves like a native table surface.
|
||||||
|
|
||||||
|
**Acceptance Scenarios**:
|
||||||
|
|
||||||
|
1. **Given** multiple entitled tenant evidence rows, **When** the operator opens the overview, **Then** the page renders them through one native table contract with the expected columns, inspect model, and empty-state rules.
|
||||||
|
2. **Given** an entitled tenant prefilter, **When** the operator applies or clears it, **Then** only the authorized rows remain in scope and row drilldown stays workspace-safe.
|
||||||
|
3. **Given** a user without workspace membership, **When** that user requests the evidence overview, **Then** the route remains deny-as-not-found.
|
||||||
|
|
||||||
|
### Edge Cases
|
||||||
|
|
||||||
|
- Dependency edges may resolve to missing targets; fallback labels, missing-target markers, and helpful hints must remain intact after the control contract changes.
|
||||||
|
- Tenant required permissions may open from a deeplink with initial filter state; the deeplink may seed state, but it must not redefine authoritative tenant scope or remain the page's ongoing state source.
|
||||||
|
- Evidence overview may receive an unauthorized tenant prefilter; the page must not leak that tenant's existence through rows, counts, or drilldown affordances.
|
||||||
|
- Evidence overview may have no rows in the current scope; the replacement table surface must preserve a clear empty state and a single safe recovery action.
|
||||||
|
- If an apparently similar surface expands into shared detail micro-UI, monitoring-state, context-shell, diff viewer, or verification-report architecture, that work must stop and be deferred instead of being half-cleaned here.
|
||||||
|
|
||||||
|
## Requirements *(mandatory)*
|
||||||
|
|
||||||
|
**Constitution alignment (required):** This feature changes three existing operator-facing admin surfaces only. It introduces no new Microsoft Graph endpoint family, no new write workflow, and no new queued or scheduled run. Existing audit, preview, confirmation, and run-observability rules remain authoritative for the destinations these pages may already link to.
|
||||||
|
|
||||||
|
**Constitution alignment (PROP-001 / ABSTR-001 / PERSIST-001 / STATE-001 / BLOAT-001):** No new persistence, abstraction, or state family is introduced. The bias is replacement before layering: remove pseudo-native contracts and use native existing primitives rather than adding wrapper infrastructure.
|
||||||
|
|
||||||
|
**Constitution alignment (OPS-UX):** Not applicable. This cleanup does not create or repurpose an `OperationRun`.
|
||||||
|
|
||||||
|
**Constitution alignment (RBAC-UX):** The feature spans tenant-context admin routes under `/admin/t/{tenant}/...`, a tenant-specific admin route under `/admin/tenants/{tenant:external_id}/required-permissions`, and the workspace-context canonical route `/admin/evidence/overview`. Non-members remain `404`. In-scope members keep current capability and entitlement rules. Tenant required permissions must keep the route tenant authoritative. Evidence overview must continue to suppress unauthorized tenant rows and remain deny-as-not-found when workspace membership is absent. No new destructive action is introduced.
|
||||||
|
|
||||||
|
**Constitution alignment (OPS-EX-AUTH-001):** Not applicable. Authentication handshake behavior is unchanged.
|
||||||
|
|
||||||
|
**Constitution alignment (BADGE-001):** Existing badge semantics remain centralized. The cleanup must not introduce page-local status languages or bespoke badge mappings for dependency state, permission state, or evidence state.
|
||||||
|
|
||||||
|
**Constitution alignment (UI-FIL-001):** Native Filament forms, filters, tables, actions, and existing shared UI primitives must replace pseudo-native primary controls and table contracts where they are an appropriate fit. Local markup may remain only for domain-specific read-only content cells and must not recreate fake controls or a second state contract.
|
||||||
|
|
||||||
|
**Constitution alignment (UI-NAMING-001):** Operator-facing vocabulary remains consistent across labels, empty states, actions, and follow-up copy: `Dependencies`, `Direction`, `Relationship`, `Required permissions`, `Status`, `Type`, `Search`, `Evidence overview`, `Artifact truth`, `Freshness`, and `Next step` stay stable and are not replaced by implementation-first terms.
|
||||||
|
|
||||||
|
**Constitution alignment (DECIDE-001):** Inventory dependencies remains a secondary context surface attached to inventory detail. Tenant required permissions and evidence overview remain primary decision surfaces. Each must keep the first decision visible without cross-page reconstruction and avoid making the default experience larger or noisier than it is today.
|
||||||
|
|
||||||
|
**Constitution alignment (UI-CONST-001 / UI-SURF-001 / ACTSURF-001 / UI-HARD-001 / UI-EX-001 / UI-REVIEW-001 / HDR-001):** The affected surfaces remain one embedded detail micro-surface, one read-first workflow page, and one read-only workspace report. Each keeps one primary inspect model, keeps safe secondary actions clearly secondary, and does not open a hidden shell or cross-page-state refactor in this spec.
|
||||||
|
|
||||||
|
**Constitution alignment (ACTSURF-001 - action hierarchy):** No destructive actions are added. Evidence overview keeps clear filters separate from inspect. Tenant required permissions keeps filter controls separate from copy and external-guidance actions. Inventory dependencies keeps scope controls separate from target inspection.
|
||||||
|
|
||||||
|
**Constitution alignment (OPSURF-001):** Default-visible content remains operator-first: dependency scope and edges on inventory detail, permission counts and matching rows on required permissions, and truth, freshness, burden, and next step on evidence overview. Diagnostics remain explicitly secondary.
|
||||||
|
|
||||||
|
**Constitution alignment (UI-SEM-001 / LAYER-001 / TEST-TRUTH-001):** Direct mapping from existing domain truth to UI remains sufficient. The cleanup must not introduce a presenter framework, wrapper layer, or second semantics system just to hide raw HTML controls or a custom table contract. Tests focus on user-visible behavior, scope safety, and contract removal.
|
||||||
|
|
||||||
|
**Constitution alignment (Filament Action Surfaces):** The Action Surface Contract remains satisfied. A UI Action Matrix is included below. Each affected surface keeps one primary inspect or open model, redundant `View` actions are absent, empty placeholder action groups are absent, and destructive action placement rules remain satisfied because no destructive actions are introduced. UI-FIL-001 is satisfied, with limited exceptions only for custom read-only content rendering inside inventory dependencies and the required-permissions matrix.
|
||||||
|
|
||||||
|
**Constitution alignment (UX-001 - Layout & Information Architecture):** Tenant required permissions and inventory detail remain section-based, view-first surfaces; their cleanup must remove naked pseudo-controls without forcing a broader page redesign. Evidence overview must provide native table search, filters, row inspection, and a clear empty state. No wider layout re-architecture is in scope.
|
||||||
|
|
||||||
|
### Functional Requirements
|
||||||
|
|
||||||
|
- **FR-196-001**: The inventory dependencies surface on inventory item detail MUST NOT use a GET form with raw HTML select and button elements as its primary interaction surface.
|
||||||
|
- **FR-196-002**: Inventory dependency direction and relationship scope MUST live in a native page-owned or component-owned state model within the current detail page and MUST update the result set without a separate apply-and-reload workflow.
|
||||||
|
- **FR-196-003**: The inventory dependency fragment MUST NOT derive its primary interaction state from `request()` or manual query parsing inside the Blade fragment.
|
||||||
|
- **FR-196-004**: Inventory dependency cleanup MUST preserve the current functional outcome: direction options, relationship narrowing, edge resolution, missing-target handling, empty-state meaning, and current-record context stay equivalent.
|
||||||
|
- **FR-196-005**: Inventory dependency cleanup MUST preserve tenant scoping, record scoping, linked-target safety, and existing authorization behavior.
|
||||||
|
- **FR-196-006**: The tenant required-permissions page MUST NOT use plain HTML controls styled as fake native inputs for its primary status, type, feature, or search controls.
|
||||||
|
- **FR-196-007**: Tenant required-permissions filter state MUST be expressed through one native page-owned form or filter contract that matches the surrounding admin experience.
|
||||||
|
- **FR-196-008**: Query parameters on tenant required permissions MAY seed deeplink or initial state, but they MUST NOT redefine the authoritative route tenant or remain the page's primary body-state contract after initial load.
|
||||||
|
- **FR-196-009**: Tenant required permissions MUST preserve current functional depth, including overview counts, freshness messaging, feature narrowing, copy payload support, guidance links, and permission-row filtering.
|
||||||
|
- **FR-196-010**: Tenant required-permissions cleanup MUST NOT introduce a replacement wrapper pattern that merely restyles raw controls or recreates a second mini contract outside native page state.
|
||||||
|
- **FR-196-011**: Evidence overview MUST replace the hand-built primary report table with a native table surface that expresses columns, filters, empty state, and row inspection using native table semantics.
|
||||||
|
- **FR-196-012**: Evidence overview MUST provide one consistent inspect or open model for authorized rows and MUST preserve the current workspace-safe drilldown into tenant evidence.
|
||||||
|
- **FR-196-013**: Evidence overview MUST remove manual page-body query and Blade wiring that exists only because the report table is hand-built, while preserving entitled tenant prefilter behavior.
|
||||||
|
- **FR-196-014**: Evidence overview MUST preserve workspace boundary enforcement, entitled-tenant filtering, and deny-as-not-found behavior for users outside the workspace boundary.
|
||||||
|
- **FR-196-015**: Any additional cleanup hit included under this spec MUST share the same unnecessary nativity bypass, remain low to medium complexity, add no new product semantics, and avoid shared-family, shell, monitoring-state, and special-visualization work.
|
||||||
|
- **FR-196-016**: Any discovered related surface that crosses into shared detail micro-UI, monitoring state, context shell, verification report, diff or settings viewer, restore preview or result layouts, or other declared non-goal families MUST be documented and deferred instead of partially refactored here.
|
||||||
|
- **FR-196-017**: This cleanup MUST NOT introduce a new wrapper microframework, presenter layer, or cross-page UI abstraction whose main purpose is to hide the same non-native contract.
|
||||||
|
- **FR-196-018**: Each cleaned surface MUST remain operatorically at least as clear as before, with no loss of empty-state meaning, next-step clarity, scope signals, or inspect navigation.
|
||||||
|
- **FR-196-019**: Release close-out MUST list which surfaces were actually cleaned, which optional same-class low-risk hits were included, which related themes remained out of scope, and which follow-up specs were touched.
|
||||||
|
|
||||||
|
## UI Action Matrix *(mandatory when Filament is changed)*
|
||||||
|
|
||||||
|
| Surface | Location | Header Actions | Inspect Affordance (List/Table) | Row Actions (max 2 visible) | Bulk Actions (grouped) | Empty-State CTA(s) | View Header Actions | Create/Edit Save+Cancel | Audit log? | Notes / Exemptions |
|
||||||
|
|---|---|---|---|---|---|---|---|---|---|---|
|
||||||
|
| Inventory item dependencies section | `/admin/t/{tenant}/inventory/inventory-items/{record}` | none added by this spec | Linked dependency target inside the section; no separate row menu | Open dependency target | none | none | Existing inventory item view header actions remain unchanged | n/a | no new audit event | Embedded detail sub-surface. Action Surface Contract remains satisfied because one inspect model exists for linked targets and no destructive actions are added. Native controls replace the GET/apply contract. |
|
||||||
|
| Tenant required permissions | `/admin/tenants/{tenant:external_id}/required-permissions` | none required; one safe native reset action is allowed if needed | Inline review matrix; no per-row inspect destination | none | none | State-specific reset or re-run verification CTA as appropriate | n/a | n/a | no new audit event | Inline workflow exemption remains legitimate. Copy payload and guidance actions stay secondary and non-destructive. Native filter contract replaces pseudo controls. |
|
||||||
|
| Evidence overview | `/admin/evidence/overview` | `Clear filters` when a prefilter is active | Full-row inspect into tenant evidence detail | none | none | `Clear filters` | n/a | n/a | no new audit event | Action Surface Contract remains satisfied with one primary inspect model, no redundant `View` row action, and no destructive action. Native table semantics replace the bespoke report table. |
|
||||||
|
|
||||||
|
### Key Entities *(include if feature involves data)*
|
||||||
|
|
||||||
|
- **Dependency edge filter state**: The current direction and relationship scope bound to one inventory item detail context.
|
||||||
|
- **Required permissions filter state**: The current status, type, selected features, and search state for one tenant's required-permissions workflow page.
|
||||||
|
- **Evidence overview row projection**: The workspace-scoped summary row for one entitled tenant, including artifact truth, freshness, burden, next step, and inspect destination.
|
||||||
|
- **Cleanup admission candidate**: A discovered extra surface that may only be included when it matches the same low-risk nativity-bypass problem class.
|
||||||
|
|
||||||
|
## Success Criteria *(mandatory)*
|
||||||
|
|
||||||
|
### Measurable Outcomes
|
||||||
|
|
||||||
|
- **SC-196-001**: Focused release validation and regression coverage pass for all three core surfaces with preserved scope safety, empty-state meaning, and result logic.
|
||||||
|
- **SC-196-002**: On all three core surfaces, operators can change the primary in-scope controls or inspect targets without relying on a separate GET apply workflow or a request-driven page-body contract.
|
||||||
|
- **SC-196-003**: Evidence overview presents 100% of authorized rows through one native table inspect model, and zero hand-built primary report tables remain within the boundaries of this spec.
|
||||||
|
- **SC-196-004**: Release validation finds zero primary plain HTML control surfaces on the three core pages whose only purpose is to imitate native admin controls.
|
||||||
|
- **SC-196-005**: Deeplink and prefilter behaviors continue to work for the targeted routes without allowing unauthorized tenant scope changes or cross-tenant row leakage.
|
||||||
|
- **SC-196-006**: Final close-out documentation explicitly records completed surfaces, deferred related themes, and any optional extra hits that were admitted under the shared rule.
|
||||||
|
|
||||||
|
## Assumptions
|
||||||
|
|
||||||
|
- Current domain semantics for dependency direction, relationship type, permission status, freshness, artifact truth, and evidence drilldown remain authoritative; this spec changes interaction contracts, not domain meaning.
|
||||||
|
- Inventory dependencies may keep domain-specific read-only edge rendering as long as primary controls and state ownership become native.
|
||||||
|
- Tenant required permissions may keep inline diagnostic content and guidance blocks as long as the primary filter contract becomes native.
|
||||||
|
- Evidence overview can adopt native table semantics without reopening broader monitoring information architecture questions.
|
||||||
|
- Optional extra hits are not required for success and may be omitted entirely if no low-risk candidate qualifies.
|
||||||
|
|
||||||
|
## Non-Goals
|
||||||
|
|
||||||
|
- Global context bar or workspace or tenant shell redesign
|
||||||
|
- Monitoring operations tab or page-state contract redesign
|
||||||
|
- Audit log selected-record or inspect duality cleanup
|
||||||
|
- Finding exceptions queue dual-inspect cleanup
|
||||||
|
- Baseline compare matrix or other special visualization surfaces
|
||||||
|
- Verification report viewer family or onboarding verification report variants
|
||||||
|
- Normalized diff, normalized settings, or other large detail micro-UI families
|
||||||
|
- Restore preview, restore results, or enterprise-detail read-only layout rework
|
||||||
|
- Raw anchor-to-component link consistency sweeps
|
||||||
|
- Badge-only, banner-only, or style-only polish work
|
||||||
|
- New constitution rules, new CI guardrail frameworks, or broad review-enforcement programs
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- Existing inventory dependency resolution and rendered-target services remain the authoritative source for dependency result logic.
|
||||||
|
- Existing tenant required-permissions view-model building remains the authoritative source for counts, row filtering, copy payloads, and guidance content.
|
||||||
|
- Existing evidence snapshot truth and row drilldown destinations remain the authoritative domain truth for evidence overview rows.
|
||||||
|
- Existing workspace-selection, tenant entitlement, and route-boundary rules remain authoritative and must be preserved by the cleanup.
|
||||||
|
- Follow-up specs for shared detail micro-UI, monitoring page-state, global context shell, UI constitution extension, and enforcement guardrails remain separate work and are not absorbed here.
|
||||||
|
|
||||||
|
## Definition of Done
|
||||||
|
|
||||||
|
- Inventory dependencies, tenant required permissions, and evidence overview are cleaned within the scope defined above.
|
||||||
|
- None of the three core surfaces relies primarily on fake native controls or a request-driven page-body contract.
|
||||||
|
- Evidence overview is no longer a hand-built primary report table.
|
||||||
|
- Tests covering the targeted functional and authorization behavior pass.
|
||||||
|
- Manual smoke checks confirm that dependency review, permission follow-up, and evidence review still feel clear and correct.
|
||||||
|
- No out-of-scope shell, monitoring-state, shared-family, or special-visualization topic is half-solved under this spec.
|
||||||
|
- Close-out documentation records completed work, deliberate deferrals, and any admitted same-class extra hits.
|
||||||
166
specs/196-hard-filament-nativity-cleanup/tasks.md
Normal file
166
specs/196-hard-filament-nativity-cleanup/tasks.md
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
---
|
||||||
|
description: "Task list for Spec 196 hard Filament nativity cleanup implementation"
|
||||||
|
---
|
||||||
|
|
||||||
|
# Tasks: Hard Filament Nativity Cleanup
|
||||||
|
|
||||||
|
**Input**: Design documents from `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/196-hard-filament-nativity-cleanup/`
|
||||||
|
**Prerequisites**: `plan.md`, `spec.md`, `research.md`, `data-model.md`, `quickstart.md`, `contracts/filament-nativity-cleanup.logical.openapi.yaml`
|
||||||
|
|
||||||
|
**Tests**: Runtime behavior changes on existing Filament v5 / Livewire v4 operator surfaces require Pest feature, Livewire, RBAC, unit, and guard coverage. This task list adds or extends only the focused tests needed for the three in-scope surfaces.
|
||||||
|
**Operations**: This cleanup does not introduce new queued work or `OperationRun` flows. Existing linked follow-up paths remain unchanged.
|
||||||
|
**RBAC**: Tenant-context, route-tenant, workspace-membership, and entitled-tenant boundaries remain authoritative. Non-members stay `404`, and no new destructive action is added.
|
||||||
|
**UI Naming**: Keep existing operator terms stable: `Dependencies`, `Direction`, `Relationship`, `Required permissions`, `Status`, `Type`, `Search`, `Evidence overview`, `Artifact truth`, `Freshness`, and `Next step`.
|
||||||
|
**Filament UI Action Surfaces**: The feature replaces pseudo-native controls and a hand-built report table with native Filament or Livewire contracts without changing the current inspect destinations or adding new actions.
|
||||||
|
**Proportionality / Anti-Bloat**: Stay inside the three named surfaces plus one embedded `TableComponent`. Do not add new persistence, enums, presenters, or shared UI frameworks.
|
||||||
|
|
||||||
|
## Phase 1: Setup (Shared Review Inputs)
|
||||||
|
|
||||||
|
**Purpose**: Confirm the exact implementation entry points, native reference patterns, and focused regression baselines before editing the three in-scope surfaces.
|
||||||
|
|
||||||
|
- [ ] T001 Audit the current nativity-bypass entry points and native reference implementations in `apps/platform/app/Filament/Resources/InventoryItemResource.php`, `apps/platform/resources/views/filament/components/dependency-edges.blade.php`, `apps/platform/app/Filament/Pages/TenantRequiredPermissions.php`, `apps/platform/resources/views/filament/pages/tenant-required-permissions.blade.php`, `apps/platform/app/Filament/Pages/Monitoring/EvidenceOverview.php`, `apps/platform/resources/views/filament/pages/monitoring/evidence-overview.blade.php`, `apps/platform/app/Filament/Pages/Reviews/ReviewRegister.php`, `apps/platform/app/Filament/Pages/InventoryCoverage.php`, and `apps/platform/app/Livewire/BackupSetPolicyPickerTable.php`
|
||||||
|
- [ ] T002 [P] Audit the focused regression baselines in `apps/platform/tests/Feature/InventoryItemDependenciesTest.php`, `apps/platform/tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php`, `apps/platform/tests/Feature/Evidence/EvidenceOverviewPageTest.php`, `apps/platform/tests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php`, `apps/platform/tests/Unit/TenantRequiredPermissionsFilteringTest.php`, `apps/platform/tests/Unit/TenantRequiredPermissionsOverallStatusTest.php`, `apps/platform/tests/Unit/TenantRequiredPermissionsFeatureImpactTest.php`, `apps/platform/tests/Unit/TenantRequiredPermissionsFreshnessTest.php`, `apps/platform/tests/Unit/TenantRequiredPermissionsCopyPayloadTest.php`, and `apps/platform/tests/Feature/Guards/FilamentTableStandardsGuardTest.php`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 2: Foundational (Blocking Prerequisites)
|
||||||
|
|
||||||
|
**Purpose**: Create the shared Spec 196 test and guard scaffolding that all three surface refactors depend on.
|
||||||
|
|
||||||
|
**CRITICAL**: No user story work should begin until this phase is complete.
|
||||||
|
|
||||||
|
- [ ] T003 [P] Create the new Spec 196 surface-test entry points in `apps/platform/tests/Feature/Filament/InventoryItemDependencyEdgesTableTest.php` and `apps/platform/tests/Feature/Filament/TenantRequiredPermissionsPageTest.php`
|
||||||
|
- [ ] T004 [P] Review and, if newly applicable, extend shared native-table guard coverage for Spec 196 page-owned tables and faux-control regressions in `apps/platform/tests/Feature/Guards/FilamentTableStandardsGuardTest.php`
|
||||||
|
- [ ] T005 [P] Add shared regression coverage for mount-only query seeding versus authoritative scope in `apps/platform/tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php` and `apps/platform/tests/Feature/Evidence/EvidenceOverviewPageTest.php`
|
||||||
|
|
||||||
|
**Checkpoint**: The shared Spec 196 test harness is in place, and later surface work can prove native state ownership without reopening scope or guard assumptions.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 3: User Story 1 - Review Dependencies Without A Foreign Workflow (Priority: P1) MVP
|
||||||
|
|
||||||
|
**Goal**: Keep inventory dependencies embedded on inventory item detail while replacing the GET apply contract with native component-owned state.
|
||||||
|
|
||||||
|
**Independent Test**: Open an inventory item detail page, change dependency direction and relationship scope, and verify that the same matching edges, missing-target markers, and empty states appear without a manual GET apply workflow.
|
||||||
|
|
||||||
|
### Tests for User Story 1
|
||||||
|
|
||||||
|
> **NOTE**: Write these tests first and confirm they fail before implementation.
|
||||||
|
|
||||||
|
- [ ] T006 [P] [US1] Extend `apps/platform/tests/Feature/InventoryItemDependenciesTest.php` with native component-state expectations for direction changes, relationship narrowing, empty states, and preserved target safety
|
||||||
|
- [ ] T007 [P] [US1] Add Livewire table-component coverage in `apps/platform/tests/Feature/Filament/InventoryItemDependencyEdgesTableTest.php` for mount state, filter updates, missing-target rendering, and tenant isolation
|
||||||
|
|
||||||
|
### Implementation for User Story 1
|
||||||
|
|
||||||
|
- [ ] T008 [US1] Create `apps/platform/app/Livewire/InventoryItemDependencyEdgesTable.php` as an embedded Filament `TableComponent` that owns direction and relationship state and queries rows through the current dependency services
|
||||||
|
- [ ] T009 [US1] Update `apps/platform/app/Filament/Resources/InventoryItemResource.php` and `apps/platform/resources/views/filament/components/dependency-edges.blade.php` to mount the embedded table component and remove the GET-form / `request()`-driven control contract while preserving target links, badges, and missing-target hints
|
||||||
|
|
||||||
|
**Checkpoint**: User Story 1 is complete when inventory detail keeps the same dependency meaning and target safety without switching operators into a foreign apply-and-reload workflow.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 4: User Story 2 - Filter Required Permissions In One Native Page Contract (Priority: P1)
|
||||||
|
|
||||||
|
**Goal**: Make tenant required permissions use one native page-owned filter and table contract while preserving route-tenant authority, summaries, guidance, and copy payloads.
|
||||||
|
|
||||||
|
**Independent Test**: Load the required-permissions page with and without deeplink query values, adjust filters live, and verify that the route tenant stays authoritative while rows, counts, guidance, and copy payloads remain correct.
|
||||||
|
|
||||||
|
### Tests for User Story 2
|
||||||
|
|
||||||
|
> **NOTE**: Write these tests first and confirm they fail before implementation.
|
||||||
|
|
||||||
|
- [ ] T010 [P] [US2] Extend `apps/platform/tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php` for route-tenant authority, query-seeded status/type/search/features state, and ignored foreign-tenant query values
|
||||||
|
- [ ] T011 [P] [US2] Add native page-table coverage in `apps/platform/tests/Feature/Filament/TenantRequiredPermissionsPageTest.php` for filter updates, search, summary consistency, guidance visibility, copy payload continuity, and no-results states
|
||||||
|
- [ ] T012 [P] [US2] Keep filter-normalization, overall-status, feature-impact, freshness, and copy-payload invariants aligned in `apps/platform/tests/Unit/TenantRequiredPermissionsFilteringTest.php`, `apps/platform/tests/Unit/TenantRequiredPermissionsOverallStatusTest.php`, `apps/platform/tests/Unit/TenantRequiredPermissionsFeatureImpactTest.php`, `apps/platform/tests/Unit/TenantRequiredPermissionsFreshnessTest.php`, and `apps/platform/tests/Unit/TenantRequiredPermissionsCopyPayloadTest.php`
|
||||||
|
|
||||||
|
### Implementation for User Story 2
|
||||||
|
|
||||||
|
- [ ] T013 [US2] Convert `apps/platform/app/Filament/Pages/TenantRequiredPermissions.php` to `HasTable` / `InteractsWithTable` with native filters, native search, and mount-only query seeding
|
||||||
|
- [ ] T014 [US2] Align `apps/platform/resources/views/filament/pages/tenant-required-permissions.blade.php` and, if needed, `apps/platform/app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php` so summary counts, freshness, feature impacts, guidance, and copy payloads are derived from the same normalized native table state
|
||||||
|
|
||||||
|
**Checkpoint**: User Story 2 is complete when required permissions behaves like one native Filament page without losing tenant authority, summary clarity, or follow-up guidance.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 5: User Story 3 - Review Evidence Through A Native Workspace Table (Priority: P2)
|
||||||
|
|
||||||
|
**Goal**: Replace the hand-built evidence report table with a native workspace table that preserves entitled-tenant filtering, clear empty states, and one inspect model.
|
||||||
|
|
||||||
|
**Independent Test**: Load the workspace evidence overview with multiple entitled tenants, apply and clear an entitled tenant prefilter, and verify that rows, empty state, and drilldown behavior remain workspace-safe while the page behaves like a native table surface.
|
||||||
|
|
||||||
|
### Tests for User Story 3
|
||||||
|
|
||||||
|
> **NOTE**: Write these tests first and confirm they fail before implementation.
|
||||||
|
|
||||||
|
- [ ] T015 [P] [US3] Extend `apps/platform/tests/Feature/Evidence/EvidenceOverviewPageTest.php` for native table rendering, native search behavior, entitled-tenant seed and clear behavior, workspace-safe row drilldown, empty states, and deny-as-not-found enforcement
|
||||||
|
- [ ] T016 [P] [US3] Extend `apps/platform/tests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php` and, if newly applicable, `apps/platform/tests/Feature/Guards/FilamentTableStandardsGuardTest.php` for DB-only derived-row rendering and the new page-owned native table contract
|
||||||
|
|
||||||
|
### Implementation for User Story 3
|
||||||
|
|
||||||
|
- [ ] T017 [US3] Convert `apps/platform/app/Filament/Pages/Monitoring/EvidenceOverview.php` to `HasTable` / `InteractsWithTable` with derived row callbacks, native filter and search state, entitled-tenant query seeding, and one inspect model
|
||||||
|
- [ ] T018 [US3] Replace the hand-built report table in `apps/platform/resources/views/filament/pages/monitoring/evidence-overview.blade.php` with a native table wrapper that preserves the clear-filter affordance and current drilldown copy
|
||||||
|
|
||||||
|
**Checkpoint**: User Story 3 is complete when evidence overview reads like one native workspace review table without leaking unauthorized tenant scope or losing the current drilldown path.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Phase 6: Polish & Cross-Cutting Verification
|
||||||
|
|
||||||
|
**Purpose**: Run the focused verification pack, format the touched files, and record the final bounded scope outcome for Spec 196.
|
||||||
|
|
||||||
|
- [ ] T019 Run the focused Spec 196 Sail verification pack from `specs/196-hard-filament-nativity-cleanup/quickstart.md` against `apps/platform/tests/Feature/InventoryItemDependenciesTest.php`, `apps/platform/tests/Feature/Filament/InventoryItemDependencyEdgesTableTest.php`, `apps/platform/tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php`, `apps/platform/tests/Feature/Filament/TenantRequiredPermissionsPageTest.php`, `apps/platform/tests/Feature/Evidence/EvidenceOverviewPageTest.php`, `apps/platform/tests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php`, `apps/platform/tests/Feature/Guards/FilamentTableStandardsGuardTest.php`, `apps/platform/tests/Unit/TenantRequiredPermissionsFilteringTest.php`, `apps/platform/tests/Unit/TenantRequiredPermissionsOverallStatusTest.php`, `apps/platform/tests/Unit/TenantRequiredPermissionsFeatureImpactTest.php`, `apps/platform/tests/Unit/TenantRequiredPermissionsFreshnessTest.php`, and `apps/platform/tests/Unit/TenantRequiredPermissionsCopyPayloadTest.php`
|
||||||
|
- [ ] T020 Run `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` and resolve formatting issues in the changed files under `apps/platform/app/`, `apps/platform/resources/views/filament/`, and `apps/platform/tests/`
|
||||||
|
- [ ] T021 Execute the manual smoke checklist in `specs/196-hard-filament-nativity-cleanup/quickstart.md` across the three cleaned surfaces and capture any sign-off notes needed for release close-out
|
||||||
|
- [ ] T022 Record the Spec 196 release close-out in `specs/196-hard-filament-nativity-cleanup/quickstart.md` with the final cleaned surfaces, any optional same-class extra hit decision, deferred themes, and touched follow-up specs
|
||||||
|
- [ ] T023 Verify the final close-out note in `specs/196-hard-filament-nativity-cleanup/quickstart.md` and the contract-modeled consumers, invariants, and non-goals in `specs/196-hard-filament-nativity-cleanup/contracts/filament-nativity-cleanup.logical.openapi.yaml` remain aligned with the implemented scope
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
- Setup tasks T001-T002 precede all implementation work.
|
||||||
|
- Foundational tasks T003-T005 block all user stories.
|
||||||
|
- User Story 1 depends on Phase 2 and is the recommended MVP cut.
|
||||||
|
- User Story 2 depends on Phase 2 and can proceed after User Story 1 or in parallel once the shared guard and seed-state scaffolding are stable.
|
||||||
|
- User Story 3 depends on Phase 2 and should land after the shared guard scaffolding is stable so the new page-owned table contract is enforced consistently.
|
||||||
|
- Polish tasks T019-T023 depend on all selected user stories being complete.
|
||||||
|
|
||||||
|
## Parallel Execution Examples
|
||||||
|
|
||||||
|
- After T001, run T002 in parallel with any remaining setup review.
|
||||||
|
- In Phase 2, T003, T004, and T005 can run in parallel.
|
||||||
|
- In User Story 1, T006 and T007 can run in parallel.
|
||||||
|
- In User Story 2, T010, T011, and T012 can run in parallel.
|
||||||
|
- In User Story 3, T015 and T016 can run in parallel.
|
||||||
|
|
||||||
|
## Parallel Example: User Story 1
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Parallel test pass for US1
|
||||||
|
T006 Extend inventory dependency regression coverage
|
||||||
|
T007 Add Livewire table-component coverage
|
||||||
|
```
|
||||||
|
|
||||||
|
## Parallel Example: User Story 2
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Parallel test pass for US2
|
||||||
|
T010 Extend trusted-state authority coverage
|
||||||
|
T011 Add native required-permissions page-table coverage
|
||||||
|
T012 Keep required-permissions unit invariants aligned
|
||||||
|
```
|
||||||
|
|
||||||
|
## Parallel Example: User Story 3
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Parallel test pass for US3
|
||||||
|
T015 Extend evidence overview page coverage
|
||||||
|
T016 Extend memoization and guard coverage
|
||||||
|
```
|
||||||
|
|
||||||
|
## Implementation Strategy
|
||||||
|
|
||||||
|
- Start with Phase 1 and Phase 2 so the native-table guard and new surface-test entry points are ready before any refactor lands.
|
||||||
|
- Deliver User Story 1 first as the MVP because it removes the most obvious foreign workflow inside an existing detail page with the least scope spill.
|
||||||
|
- Deliver User Story 2 next to normalize the second P1 surface and prove route-tenant authority still wins over deeplink state.
|
||||||
|
- Finish with User Story 3 once the shared table guard is stable, then run the focused Sail pack and Pint formatting from Phase 6.
|
||||||
Loading…
Reference in New Issue
Block a user