- Replace view-only row buttons with clickable rows (recordUrl)\n- Update action-surface contract slot to InspectAffordance + validator support\n- Add golden guard tests + contract doc\n- Update SpecKit constitution/templates to include inspection affordance rule
128 lines
8.4 KiB
Markdown
128 lines
8.4 KiB
Markdown
---
|
||
|
||
description: "Task list for Spec 082 implementation"
|
||
---
|
||
|
||
# Tasks: Action Surface Contract + CI Enforcement
|
||
|
||
**Input**: Design documents from `/specs/082-action-surface-contract/`
|
||
**Prerequisites**: plan.md (required), spec.md (required), research.md, data-model.md, contracts/, quickstart.md
|
||
**Tests**: Required (Pest) — this feature adds/changes CI enforcement.
|
||
|
||
## Phase 1: Setup (Shared Infrastructure)
|
||
|
||
**Purpose**: Introduce the new support namespace and a guard-test entry point.
|
||
|
||
- [X] T001 Create ActionSurface namespaces in app/Support/Ui/ActionSurface/
|
||
- [X] T002 [P] Add guard test skeleton in tests/Feature/Guards/ActionSurfaceContractTest.php
|
||
- [X] T003 [P] Add validator test skeleton in tests/Feature/Guards/ActionSurfaceValidatorTest.php
|
||
|
||
---
|
||
|
||
## Phase 2: Foundational (Blocking Prerequisites)
|
||
|
||
**Purpose**: Core contract model + discovery + validation that all user stories rely on.
|
||
|
||
- [X] T004 Create enums for component/profile/slot in app/Support/Ui/ActionSurface/Enums/ActionSurfaceComponentType.php
|
||
- [X] T005 [P] Create slot + exemption value objects in app/Support/Ui/ActionSurface/ActionSurfaceExemption.php
|
||
- [X] T006 [P] Create declaration + defaults DTOs in app/Support/Ui/ActionSurface/ActionSurfaceDeclaration.php
|
||
- [X] T007 Implement profile definitions (required slots per profile) in app/Support/Ui/ActionSurface/ActionSurfaceProfileDefinition.php
|
||
- [X] T008 Implement in-scope discovery (tenant discovery roots + admin explicit registrations/routes; exclude Widgets and System panel) in app/Support/Ui/ActionSurface/ActionSurfaceDiscovery.php
|
||
- [X] T009 Implement declaration contract validation (declare-or-exempt; reason required; More label; Export default) in app/Support/Ui/ActionSurface/ActionSurfaceValidator.php
|
||
- [X] T010 Add fast unit-style tests for validator rules in tests/Feature/Guards/ActionSurfaceValidatorTest.php (pure validation logic, no DB or Filament boot)
|
||
|
||
**Checkpoint**: Validator can enumerate + validate in-scope components deterministically.
|
||
|
||
---
|
||
|
||
## Phase 3: User Story 1 — Prevent incomplete UI action surfaces (Priority: P1) 🎯 MVP
|
||
|
||
**Goal**: CI fails if an in-scope Filament component lacks a declaration (or an explicit exemption with a non-empty reason).
|
||
|
||
**Independent Test**: Add a new in-scope Filament component without a declaration; run the guard and confirm it fails with an actionable message; add a declaration/exemption and confirm it passes.
|
||
|
||
- [X] T011 [US1] Implement the CI guard that runs validation in tests/Feature/Guards/ActionSurfaceContractTest.php
|
||
- [X] T012 [US1] Add baseline exemptions registry in app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php (reason required, explicit class allowlist with shrink-over-time rule)
|
||
- [X] T013 [US1] Wire exemptions into validator output in app/Support/Ui/ActionSurface/ActionSurfaceValidator.php
|
||
- [X] T014 [US1] Make guard output actionable (class + slot + hint) in tests/Feature/Guards/ActionSurfaceContractTest.php
|
||
- [X] T015 [US1] Add tests proving widgets are excluded from scope in tests/Feature/Guards/ActionSurfaceContractTest.php
|
||
- [X] T031 [US1] Add tests proving unknown classes are not auto-exempted and every exemption reason is non-empty in tests/Feature/Guards/ActionSurfaceContractTest.php
|
||
|
||
**Checkpoint**: Guard passes on main branch state, but blocks missing declarations going forward.
|
||
|
||
---
|
||
|
||
## Phase 4: User Story 2 — Consistent, enterprise-grade actions and empty-state guidance (Priority: P2)
|
||
|
||
**Goal**: Provide consistent action-surface conventions (More grouping, Export default for RunLog/ReadOnly, empty-state CTA) and demonstrate them on representative surfaces.
|
||
|
||
**Independent Test**: Pick one CRUD-style list and one run-log style list; verify each has expected action areas (header/row/bulk/empty-state; detail header actions) and consistent ordering/grouping.
|
||
|
||
- [X] T016 [P] [US2] Define required slots for CRUD/ReadOnly/RunLog/RelationManager profiles in app/Support/Ui/ActionSurface/ActionSurfaceProfileDefinition.php
|
||
- [X] T017 [P] [US2] Enforce defaults: More label + Export expectation for ReadOnly/RunLog in app/Support/Ui/ActionSurface/ActionSurfaceValidator.php
|
||
- [X] T018 [US2] Add a declaration to a representative CRUD surface in app/Filament/Resources/PolicyResource.php
|
||
- [X] T019 [US2] Ensure list empty-state CTA exists for the CRUD surface in app/Filament/Resources/PolicyResource/Pages/ListPolicies.php
|
||
- [X] T020 [US2] Add a declaration to a representative RunLog surface in app/Filament/Resources/OperationRunResource.php
|
||
- [X] T021 [US2] Ensure Export bulk action is present (or exempted with reason) for the RunLog surface in app/Filament/Resources/OperationRunResource.php
|
||
- [X] T022 [US2] Add a declaration to one embedded relationship sub-list in app/Filament/Resources/PolicyResource/RelationManagers/VersionsRelationManager.php
|
||
- [X] T023 [US2] Add tests asserting the representative declarations satisfy required slots in tests/Feature/Guards/ActionSurfaceContractTest.php
|
||
- [X] T032 [US2] Add representative runtime test asserting PolicyResource row/bulk grouping uses “More” conventions in tests/Feature/Guards/ActionSurfaceContractTest.php
|
||
- [X] T033 [US2] Add representative runtime test asserting canonical tenantless “View run” link usage in tests/Feature/Guards/ActionSurfaceContractTest.php
|
||
- [X] T035 [US2] Add golden regression tests for “view-only lists use clickable rows without row actions” in tests/Feature/Guards/ActionSurfaceContractTest.php
|
||
- [X] T036 [US2] Document action-surface contract rules (including “no lone View button; prefer clickable rows”) in docs/ui/action-surface-contract.md
|
||
|
||
**Checkpoint**: At least one CRUD + one RunLog + one embedded sub-list visibly follow the conventions.
|
||
|
||
---
|
||
|
||
## Phase 5: User Story 3 — Predictable RBAC behavior for members vs non-members (Priority: P3)
|
||
|
||
**Goal**: Validate consistent 404 vs 403 semantics and disabled-UI behavior for capability-gated actions.
|
||
|
||
**Independent Test**: Use a representative surface and verify (a) non-member receives not-found, and (b) member without capability receives forbidden and sees disabled UI with a helpful explanation.
|
||
|
||
- [X] T024 [P] [US3] Add non-member 404 route test on representative operations detail route in tests/Feature/Rbac/ActionSurfaceRbacSemanticsTest.php
|
||
- [X] T025 [US3] Add member-without-capability 403 server-side test by attempting to execute ListEntraGroupSyncRuns::sync_groups as a readonly member in tests/Feature/Filament/EntraGroupSyncRunResourceTest.php
|
||
- [X] T026 [US3] In that 403 test, assert no EntraGroupSyncJob is pushed and no EntraGroupSyncRun is created for the tenant in tests/Feature/Filament/EntraGroupSyncRunResourceTest.php
|
||
- [X] T027 [US3] Ensure disabled-UI semantics are covered for the same action (visible + disabled + standard tooltip) in tests/Feature/Filament/EntraGroupSyncRunResourceTest.php
|
||
- [X] T034 [US3] Add representative observability/audit regression assertion for an operation-start action (OperationRun record present with scope + actor) in tests/Feature/Guards/ActionSurfaceContractTest.php
|
||
|
||
**Checkpoint**: One surface per profile has coverage for 404 vs 403 semantics.
|
||
|
||
---
|
||
|
||
## Phase 6: Polish & Cross-Cutting Concerns
|
||
|
||
- [X] T028 [P] Run formatter on changed files via vendor/bin/sail bin pint --dirty
|
||
- [X] T029 Run focused guard tests via vendor/bin/sail artisan test --compact tests/Feature/Guards/ActionSurfaceContractTest.php
|
||
- [X] T030 Run RBAC semantics test via vendor/bin/sail artisan test --compact tests/Feature/Rbac/ActionSurfaceRbacSemanticsTest.php
|
||
|
||
---
|
||
|
||
## Dependencies & Execution Order
|
||
|
||
- Setup (Phase 1) → Foundational (Phase 2) → US1 (Phase 3) → US2/US3 (Phases 4–5 can proceed in parallel) → Polish (Phase 6)
|
||
|
||
## Parallel Opportunities
|
||
|
||
- Phase 2: DTOs/enums (T004–T006) can be done in parallel.
|
||
- US2: Profile definition + validator rules (T016–T017) can be done in parallel.
|
||
- US3: Test scaffolding (T024) can be done in parallel with US2 retrofit tasks.
|
||
|
||
## Parallel Example: US2
|
||
|
||
- T018 (PolicyResource declaration) can be implemented in parallel with T020 (OperationRunResource declaration).
|
||
|
||
## Implementation Strategy
|
||
|
||
### MVP First (US1 only)
|
||
|
||
1. Complete Phase 1 + Phase 2.
|
||
2. Implement Phase 3 (US1) guard + exemptions.
|
||
3. Validate guard behavior by adding/removing a declaration locally.
|
||
|
||
### Incremental Delivery
|
||
|
||
- Add US2 representative surfaces next (PolicyResource + OperationRunResource + one RelationManager).
|
||
- Add US3 RBAC semantics tests last (keeps scope tight while contract infrastructure stabilizes).
|