TenantAtlas/specs/082-action-surface-contract/data-model.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

2.7 KiB

Data Model — Action Surface Contract

This feature introduces a small, explicit model for declaring and validating action surfaces.

Entities

ActionSurfaceDeclaration

Represents the contract declaration attached to a Filament component.

Fields:

  • version (int): schema version for forward compatibility (start at 1).
  • componentType (enum): Resource | Page | RelationManager.
  • className (string): fully qualified class name (filled by validator when reporting).
  • panelScope (enum): Tenant | Admin (filled by validator based on discovery context).
  • profile (enum): contract profile (see below).
  • slots (map<ActionSurfaceSlot, SlotRequirement>): required and optional slots for this component.
  • exemptions (list): explicit exemptions with reason.
  • defaults (ActionSurfaceDefaults): shared UX defaults (e.g., moreGroupLabel).

ActionSurfaceSlot (enum)

Discrete UI locations that may contain actions.

Proposed baseline slots:

  • ListHeader
  • ListRowPrimary
  • ListRowMoreMenu
  • ListBulkMoreGroup
  • ListEmptyState
  • DetailHeader

(Profiles determine which slots are required.)

SlotRequirement

Requirement status for a single slot.

Fields:

  • status (enum): Satisfied | Exempt.
  • details (optional string): freeform explanation or expected actions.
  • requiresTypedConfirmation (bool, default false): indicates the actions in this slot require typed confirmation.

ActionSurfaceExemption

Represents a justified opt-out for a required slot.

Fields:

  • slot (ActionSurfaceSlot)
  • reason (string, required, non-empty)
  • trackingRef (optional string)

ActionSurfaceDefaults

Shared defaults enforced/checked by CI.

Fields:

  • moreGroupLabel (string, required): must be More.
  • exportIsDefaultBulkActionForReadOnly (bool): default expectation for ReadOnly + RunLog profiles.

Profiles (enum)

Profiles map component archetypes to required slots.

Proposed profiles (initial set):

  • CrudListAndEdit: list + edit page exists.
  • CrudListAndView: list + view page exists.
  • ListOnlyReadOnly: list-only, no edit/view.
  • RunLog: operational log list (read-only, expects Export bulk action by default).

Validation rules (CI)

For each in-scope class:

  • Must define an action surface declaration.
  • Must select a profile.
  • For every slot required by that profile:
    • slot must be present with Satisfied, OR
    • slot must be marked Exempt and there must be a matching exemption with non-empty reason.
  • Defaults must include moreGroupLabel = "More".

Note: The validator is intentionally declarative; it validates the presence and completeness of the declaration (and exemptions), not the exact runtime Filament action configuration.