TenantAtlas/specs/082-action-surface-contract/plan.md
ahmido a770b32e87 feat: action-surface contract inspect affordance + clickable rows (#100)
Implements Spec 082 updates to the Filament Action Surface Contract:

- New required list/table slot: InspectAffordance (clickable row via recordUrl preferred; also supports View action or primary link column)
- Retrofit view-only tables to remove lone View row action buttons and use clickable rows
- Update validator + guard tests, add golden regression assertions
- Add docs: docs/ui/action-surface-contract.md

Tests (local via Sail):
- vendor/bin/sail artisan test --compact tests/Feature/Guards/ActionSurfaceContractTest.php
- vendor/bin/sail artisan test --compact tests/Feature/Guards/ActionSurfaceValidatorTest.php
- vendor/bin/sail artisan test --compact tests/Feature/Rbac/ActionSurfaceRbacSemanticsTest.php
- vendor/bin/sail artisan test --compact tests/Feature/Filament/EntraGroupSyncRunResourceTest.php

Notes:
- Filament v5 / Livewire v4 compatible.
- No destructive-action behavior changed in this PR.

Co-authored-by: Ahmed Darrazi <ahmeddarrazi@MacBookPro.fritz.box>
Reviewed-on: #100
2026-02-08 20:31:36 +00:00

109 lines
4.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Implementation Plan: Action Surface Contract + CI Enforcement
**Branch**: `082-action-surface-contract` | **Date**: 2026-02-08 | **Spec**: specs/082-action-surface-contract/spec.md
**Input**: Feature specification from specs/082-action-surface-contract/spec.md
## Summary
Introduce a declarative “Action Surface Declaration” for every in-scope admin UI component (Resources, Pages, embedded relationship sub-lists), enforce it via a deterministic Pest guard in CI, and add representative runtime tests for constitution-critical action behavior.
Key behavior:
- Contract profiles define minimum required action slots (list header/row/bulk/empty-state, detail header).
- Declarations must satisfy each required slot or explicitly exempt it with a reason.
- CI fails on missing declarations, missing required slots, or empty exemption reasons.
- Representative runtime tests verify grouping/confirmation/RBAC/canonical-run-link behavior on selected surfaces.
## Technical Context
**Language/Version**: PHP 8.4.x
**Primary Dependencies**: Laravel 12, Filament v5, Livewire v4
**Storage**: PostgreSQL (Sail)
**Testing**: Pest v4 (PHPUnit 12 runner)
**Target Platform**: Web application (Laravel Sail for local; Dokploy for deploy)
**Project Type**: Laravel monolith (admin console via Filament panels)
**Performance Goals**: Contract validation completes in < 1s locally/CI (pure PHP, no network)
**Constraints**:
- Deterministic CI enforcement (no Livewire browser interactions)
- No new external calls introduced
- Must preserve RBAC semantics (non-member 404; member missing capability 403)
- Must not change panel architecture (tenant/admin/system panels remain)
- No deep runtime introspection of every Filament action in CI for this iteration
**Scale/Scope**: ~100 Filament classes (Resources/Pages/RelationManagers); enforcement is repo-wide within scope
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
- Inventory-first: N/A (this feature is UI governance; no inventory model changes)
- Read/write separation: N/A (no new domain writes introduced by the validator)
- Graph contract path: PASS (no new Graph calls)
- Deterministic capabilities: PASS (capability rules stay registry-driven)
- RBAC-UX: PASS (enforcement continues to use central UI helpers; server-side remains authoritative)
- Run observability: PASS (validator runs in CI only; no operations started)
- Data minimization: PASS (no new storage)
- Badge semantics (BADGE-001): N/A
- Filament UI Action Surface Contract: PASS (this feature implements the CI gate itself)
## Plan Phases
### Phase 0 — Research (output: research.md)
Decide and document:
- How to enumerate in-scope classes for tenant + admin panels (excluding widgets)
- How declarations are attached (static method vs attributes vs config)
- What slots exist and how exemptions are represented (reason required; tracking optional)
- How the Pest guard reports actionable failures
### Phase 1 — Design (outputs: data-model.md, contracts/*, quickstart.md)
Design artifacts:
- Data model for declarations, slots, exemptions, and profiles
- JSON schema contract for the declaration payload (for future tooling)
- Quickstart explaining how to add a declaration + how to run the guard
### Phase 2 — Planning (output: tasks.md later via /speckit.tasks)
Implementation plan will include:
- New support classes under `app/Support/Ui/ActionSurface/**`
- Pest guard test under `tests/Feature/Guards/**`
- Minimal retrofit for existing bulk none surfaces via declarations + targeted exemptions (repo-green first)
- Representative runtime assertions for action grouping, confirmation, and canonical run links
## Project Structure
### Documentation (this feature)
```text
specs/082-action-surface-contract/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
└── tasks.md
```
### Source Code (repository root)
```text
app/
├── Filament/
│ ├── Resources/
│ ├── Pages/
│ └── System/ # out-of-scope for this features validator
├── Providers/Filament/ # panel providers (tenant/admin/system)
└── Support/
├── Rbac/ # UiEnforcement + WorkspaceUiEnforcement (existing)
└── Ui/ActionSurface/ # NEW: profiles, slots, declarations, validator
tests/
└── Feature/
└── Guards/ # NEW: Action surface contract CI gate
```
**Structure Decision**: Laravel monolith. Action-surface enforcement ships as support-domain classes + a Pest guard.
## Complexity Tracking
No constitution violations required.