## Summary - add a shared diff presentation layer under `app/Support/Diff` with deterministic row classification, summary derivation, and value stringification - centralize diff-state badge semantics through `BadgeCatalog` with a dedicated `DiffRowStatusBadge` - add reusable Filament diff partials, focused Pest coverage, and the full SpecKit artifact set for spec 141 ## Testing - `vendor/bin/sail artisan test --compact tests/Unit/Support/Diff/DiffRowStatusTest.php tests/Unit/Support/Diff/DiffRowTest.php tests/Unit/Support/Diff/DiffPresenterTest.php tests/Unit/Support/Diff/ValueStringifierTest.php tests/Unit/Badges/DiffRowStatusBadgeTest.php tests/Feature/Support/Diff/SharedDiffSummaryPartialTest.php tests/Feature/Support/Diff/SharedDiffRowPartialTest.php tests/Feature/Support/Diff/SharedInlineListDiffPartialTest.php` - `vendor/bin/sail bin pint --dirty --format agent` ## Filament / Livewire Contract - Livewire v4.0+ compliance: unchanged and respected; this feature adds presentation support only within the existing Filament v5 / Livewire v4 stack - Provider registration: unchanged; no panel/provider changes were required, so `bootstrap/providers.php` remains the correct registration location - Global search: unchanged; no Resource or global-search behavior was added or modified - Destructive actions: none introduced in this feature - Asset strategy: no new registered Filament assets; shared Blade partials rely on the existing asset pipeline and standard deploy step for `php artisan filament:assets` when assets change generally - Testing coverage: presenter, DTOs, stringifier, badge semantics, summary partial, row partial, and inline-list partial are covered by focused Pest unit and feature tests ## Notes - Spec checklist status is complete for `specs/141-shared-diff-presentation-foundation/checklists/requirements.md` - This PR preserves specialized diff renderers and documents incremental adoption rather than forcing migration in the same change Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #170
14 KiB
Tasks: Shared Diff Presentation Foundation
Input: Design documents from /specs/141-shared-diff-presentation-foundation/
Prerequisites: plan.md, spec.md, research.md, data-model.md, contracts/shared-diff-presentation.openapi.yaml, quickstart.md
Tests: Tests are REQUIRED for this feature because it adds runtime presentation behavior, shared Blade partials, centralized badge semantics, and reusable PHP support logic.
Operations: No new OperationRun, queued workflow, remote call, or audit-log mutation flow is introduced.
RBAC: Existing workspace and tenant authorization remain unchanged. The foundation must render only data already authorized by consuming surfaces and must not add any new scope behavior.
Filament UI: The feature adds shared Blade partials only. It does not modify a specific Filament Resource, RelationManager, or Page action surface in this spec.
Badges: Shared diff-state summary and row badges must use centralized semantics through BadgeCatalog and BadgeRenderer rather than inline mappings.
Phase 1: Setup (Shared Infrastructure)
Purpose: Create the scaffolding for shared support classes, partials, and Pest coverage.
- T001 Create unit-test scaffolds in tests/Unit/Support/Diff/DiffRowStatusTest.php, tests/Unit/Support/Diff/DiffRowTest.php, tests/Unit/Support/Diff/DiffPresenterTest.php, and tests/Unit/Support/Diff/ValueStringifierTest.php
- T002 [P] Create badge and feature-test scaffolds in tests/Unit/Badges/DiffRowStatusBadgeTest.php, tests/Feature/Support/Diff/SharedDiffSummaryPartialTest.php, tests/Feature/Support/Diff/SharedDiffRowPartialTest.php, and tests/Feature/Support/Diff/SharedInlineListDiffPartialTest.php
- T003 [P] Create shared partial stubs in resources/views/filament/partials/diff/summary-badges.blade.php, resources/views/filament/partials/diff/row.blade.php, resources/views/filament/partials/diff/row-changed.blade.php, resources/views/filament/partials/diff/row-unchanged.blade.php, resources/views/filament/partials/diff/row-added.blade.php, resources/views/filament/partials/diff/row-removed.blade.php, and resources/views/filament/partials/diff/inline-list.blade.php
Phase 2: Foundational (Blocking Prerequisites)
Purpose: Establish the shared namespace, DTO shells, and badge plumbing every user story depends on.
⚠️ CRITICAL: No user story work should begin until this phase is complete.
- T004 Create support-layer skeletons in app/Support/Diff/DiffRowStatus.php, app/Support/Diff/DiffRow.php, app/Support/Diff/DiffSummary.php, app/Support/Diff/DiffPresentation.php, app/Support/Diff/DiffPresenter.php, and app/Support/Diff/ValueStringifier.php
- T005 [P] Register shared diff badge scaffolding in app/Support/Badges/BadgeDomain.php, app/Support/Badges/BadgeCatalog.php, and app/Support/Badges/Domains/DiffRowStatusBadge.php
Checkpoint: Shared diff infrastructure exists and user-story work can begin.
Phase 3: User Story 1 - Review Changes Consistently (Priority: P1) 🎯 MVP
Goal: Give all simple diff consumers one shared state vocabulary, deterministic row model, summary counts, and row rendering primitives.
Independent Test: Render a representative compare payload with added, removed, changed, and unchanged values and verify the presenter output plus summary and row partials use one consistent vocabulary and matching counts.
Tests for User Story 1
- T006 [P] [US1] Add enum and DTO invariant coverage in tests/Unit/Support/Diff/DiffRowStatusTest.php and tests/Unit/Support/Diff/DiffRowTest.php
- T007 [P] [US1] Add row-classification and summary-derivation coverage in tests/Unit/Support/Diff/DiffPresenterTest.php
- T008 [P] [US1] Add summary and row partial rendering coverage in tests/Feature/Support/Diff/SharedDiffSummaryPartialTest.php and tests/Feature/Support/Diff/SharedDiffRowPartialTest.php
Implementation for User Story 1
- T009 [US1] Implement immutable row, summary, and presentation value objects in app/Support/Diff/DiffRow.php, app/Support/Diff/DiffSummary.php, and app/Support/Diff/DiffPresentation.php
- T010 [US1] Implement the canonical diff-state enum and centralized badge mapping in app/Support/Diff/DiffRowStatus.php, app/Support/Badges/BadgeDomain.php, app/Support/Badges/BadgeCatalog.php, and app/Support/Badges/Domains/DiffRowStatusBadge.php
- T011 [US1] Implement baseline/current row classification and summary derivation in app/Support/Diff/DiffPresenter.php
- T012 [US1] Implement shared summary and state-specific row partials in resources/views/filament/partials/diff/summary-badges.blade.php, resources/views/filament/partials/diff/row.blade.php, resources/views/filament/partials/diff/row-changed.blade.php, resources/views/filament/partials/diff/row-unchanged.blade.php, resources/views/filament/partials/diff/row-added.blade.php, and resources/views/filament/partials/diff/row-removed.blade.php
Checkpoint: The shared diff foundation can render consistent change states and summaries for simple compare data.
Phase 4: User Story 2 - Scan Diff Details Efficiently (Priority: P2)
Goal: Make row details easier to scan by standardizing value formatting, inline list rendering, quieter unchanged content, and accessible state cues.
Independent Test: Render mixed scalar and list-based compare rows and verify nulls, booleans, and simple arrays format consistently, list adds or removes are readable inline, unchanged content is quieter, and state remains understandable without color alone.
Tests for User Story 2
- T013 [P] [US2] Add value-formatting coverage for null, boolean, scalar, empty-list, non-empty-list, and associative-array cases in tests/Unit/Support/Diff/ValueStringifierTest.php
- T014 [P] [US2] Add list-fragment and metadata-fallback presenter coverage in tests/Unit/Support/Diff/DiffPresenterTest.php
- T015 [P] [US2] Add inline-list rendering coverage with a representative 25-item fixture plus muted-unchanged, semantic-label, and logical-reading-order assertions in tests/Feature/Support/Diff/SharedInlineListDiffPartialTest.php and tests/Feature/Support/Diff/SharedDiffRowPartialTest.php
Implementation for User Story 2
- T016 [US2] Implement shared display formatting in app/Support/Diff/ValueStringifier.php
- T017 [US2] Implement list-like fragment preparation and metadata-safe fallbacks in app/Support/Diff/DiffPresenter.php and app/Support/Diff/DiffRow.php
- T018 [US2] Implement the inline list diff partial and row-level list delegation in resources/views/filament/partials/diff/inline-list.blade.php and resources/views/filament/partials/diff/row.blade.php
- T019 [US2] Add compact display, dimmed unchanged styling, semantic labels or icons, explicit reading-order-safe markup, and dark-mode-safe classes in resources/views/filament/partials/diff/summary-badges.blade.php, resources/views/filament/partials/diff/row-changed.blade.php, resources/views/filament/partials/diff/row-unchanged.blade.php, resources/views/filament/partials/diff/row-added.blade.php, and resources/views/filament/partials/diff/row-removed.blade.php
Checkpoint: Shared rows are readable, accessible, and efficient to scan for both scalar and simple list diffs.
Phase 5: User Story 3 - Adopt the Foundation Incrementally (Priority: P3)
Goal: Make the foundation safe for future consumer specs by documenting how to adopt it, preserving specialized views, and proving no-data and fallback behavior stay consumer-safe.
Independent Test: Validate that the presenter and partials handle empty or sparse compare inputs cleanly, diff-state badge fallback remains safe, and the developer guidance explains when to use the shared foundation versus a specialized renderer.
Tests for User Story 3
- T020 [P] [US3] Add no-data and sparse-input fallback coverage in tests/Unit/Support/Diff/DiffPresenterTest.php and tests/Feature/Support/Diff/SharedDiffSummaryPartialTest.php
- T021 [P] [US3] Add diff-state badge fallback coverage in tests/Unit/Badges/DiffRowStatusBadgeTest.php
Implementation for User Story 3
- T022 [US3] Finalize consumer-safe fallback behavior in app/Support/Diff/DiffPresentation.php, app/Support/Diff/DiffSummary.php, and resources/views/filament/partials/diff/summary-badges.blade.php for empty or missing compare data
- T023 [US3] Add developer adoption guidance in docs/ui/shared-diff-presentation-foundation.md covering presenter usage, standalone stringifier usage, shared partial usage, and non-adoption cases
- T024 [US3] Align the developer guidance with specs/141-shared-diff-presentation-foundation/quickstart.md and preserve non-adoption boundaries for resources/views/filament/infolists/entries/normalized-diff.blade.php, resources/views/filament/infolists/entries/rbac-role-definition-diff.blade.php, resources/views/filament/infolists/entries/assignments-diff.blade.php, and resources/views/filament/infolists/entries/scope-tags-diff.blade.php
Checkpoint: The foundation is documented, consumer-safe, and ready for follow-up adoption specs without forcing current specialized views to migrate.
Phase 6: Polish & Cross-Cutting Concerns
Purpose: Final verification and implementation hygiene across all stories.
- T025 [P] Run the focused shared diff foundation test pack with vendor/bin/sail artisan test --compact tests/Unit/Support/Diff/DiffRowStatusTest.php tests/Unit/Support/Diff/DiffRowTest.php tests/Unit/Support/Diff/DiffPresenterTest.php tests/Unit/Support/Diff/ValueStringifierTest.php tests/Unit/Badges/DiffRowStatusBadgeTest.php tests/Feature/Support/Diff/SharedDiffSummaryPartialTest.php tests/Feature/Support/Diff/SharedDiffRowPartialTest.php tests/Feature/Support/Diff/SharedInlineListDiffPartialTest.php
- T026 [P] Run formatting on changed files with vendor/bin/sail bin pint --dirty --format agent
- T027 [P] Validate the implementation examples against specs/141-shared-diff-presentation-foundation/quickstart.md and docs/ui/shared-diff-presentation-foundation.md
Dependencies & Execution Order
Phase Dependencies
- Setup (Phase 1): No dependencies; start immediately.
- Foundational (Phase 2): Depends on Setup completion; blocks all user stories.
- User Story 1 (Phase 3): Depends on Foundational completion and is the MVP slice.
- User Story 2 (Phase 4): Depends on User Story 1 because it extends the same presenter and row partials with formatting and list behavior.
- User Story 3 (Phase 5): Depends on User Stories 1 and 2 because the documentation and fallback guarantees should reflect the final shared API and rendering behavior.
- Polish (Phase 6): Depends on all selected user stories being complete.
User Story Dependencies
- User Story 1 (P1): No dependency on other stories after Foundational.
- User Story 2 (P2): Builds directly on the shared presenter and row partials from US1.
- User Story 3 (P3): Builds on the completed presenter, badge semantics, and partial behavior from US1 and US2.
Within Each User Story
- Write or update tests first and confirm they fail before implementing behavior.
- Implement PHP support logic before wiring Blade partial behavior.
- Finish shared view behavior before documenting or validating consumer adoption guidance.
Parallel Opportunities
T002andT003can run in parallel afterT001starts.T006,T007, andT008can run in parallel inside US1.T013,T014, andT015can run in parallel inside US2.T020andT021can run in parallel inside US3.T025,T026, andT027can run in parallel in the polish phase.
Parallel Example: User Story 1
# Launch the core shared-diff test work together:
Task: "Add enum and DTO invariant coverage in tests/Unit/Support/Diff/DiffRowStatusTest.php and tests/Unit/Support/Diff/DiffRowTest.php"
Task: "Add row-classification and summary-derivation coverage in tests/Unit/Support/Diff/DiffPresenterTest.php"
Task: "Add summary and row partial rendering coverage in tests/Feature/Support/Diff/SharedDiffSummaryPartialTest.php and tests/Feature/Support/Diff/SharedDiffRowPartialTest.php"
Parallel Example: User Story 2
# Launch the formatting and list-diff test work together:
Task: "Add value-formatting coverage for null, boolean, scalar, empty-list, non-empty-list, and associative-array cases in tests/Unit/Support/Diff/ValueStringifierTest.php"
Task: "Add list-fragment and metadata-fallback presenter coverage in tests/Unit/Support/Diff/DiffPresenterTest.php"
Task: "Add inline-list rendering coverage with a representative 25-item fixture plus muted-unchanged, semantic-label, and logical-reading-order assertions in tests/Feature/Support/Diff/SharedInlineListDiffPartialTest.php and tests/Feature/Support/Diff/SharedDiffRowPartialTest.php"
Parallel Example: User Story 3
# Launch the fallback-safety test work together:
Task: "Add no-data and sparse-input fallback coverage in tests/Unit/Support/Diff/DiffPresenterTest.php and tests/Feature/Support/Diff/SharedDiffSummaryPartialTest.php"
Task: "Add diff-state badge fallback coverage in tests/Unit/Badges/DiffRowStatusBadgeTest.php"
Implementation Strategy
MVP First (User Story 1 Only)
- Complete Phase 1: Setup.
- Complete Phase 2: Foundational.
- Complete Phase 3: User Story 1.
- Validate that simple compare inputs now produce consistent shared states, summaries, and row rendering.
Incremental Delivery
- Deliver US1 to establish the shared state vocabulary, presenter contract, and base row or summary primitives.
- Deliver US2 to make the shared rendering efficient to scan through standardized formatting and inline list behavior.
- Deliver US3 to document adoption, lock in safe fallback behavior, and preserve specialized views until follow-up specs opt in.
Team Strategy
- One engineer can own the PHP support layer while another prepares Pest coverage and Blade partial scaffolding.
- After US1 lands, one engineer can focus on
ValueStringifierand presenter list fragments while another refines row and inline-list partial behavior. - Finish with a short pass on documentation, quickstart example validation, focused Sail tests, and Pint.