diff --git a/CHANGELOG.md b/CHANGELOG.md index 02a3ef0..fd2b1f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,13 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and ## [Unreleased] +## [0.6.0] — 2026-07-01 + +**Release-as-a-whole: backward-compatible MINOR** — one new optional PHPStan parameter (`formRequestToDtoExemptClasses`, default `[]`) on `EnforceFormRequestToDtoRule`. Default-empty ⇒ zero new errors in existing consumers; a consumer adopts on its own `^0.5 → ^0.6` pin bump. Seed: war-room enforcement queue #131 — a class-keyed exemption surface so a territory can retire a duplicate local `FormRequestsTest` arch test and consolidate its exempt list into package config. + ### Added -- `EnforceFormRequestToDtoRule` — new optional `formRequestToDtoExemptClasses` PHPStan parameter (default `[]`): a list of fully-qualified class names to exempt from the `toDto()` contract, matched by **exact FQCN**. This is the class-keyed alternative to the existing per-file `phpstan.neon` `ignoreErrors` suppression path (identifier + `path` keyed) — predictable across file moves and, crucially, it ports a retiring local FormRequest→DTO Pest arch test's FQCN exemption list into package config 1:1. Wired through `extension.neon` (`formRequestToDtoExemptClasses: []` parameter + `listOf(string())` schema + `exemptClasses: %formRequestToDtoExemptClasses%` on the rule's service registration), mirroring the `formRequestBaseClass` precedent. No class name is ever hardcoded in the rule body — a consumer-supplied FQCN list is *config*, not a rule-body literal, so the package's "never by name inside the rule" convention is preserved. Seed: war-room enforcement queue #131 — `EnforceFormRequestToDtoRule` now duplicates territory-local `FormRequestsTest` arch tests (entreezuil first live case, PR #274), enforcing the same invariant twice with two exemption ledgers to keep in sync; the class-keyed param lets a territory retire its local arch test and consolidate its exempt list into package config (that retirement is a separate follow-up, not this change). README documents the param + a "Retiring a local FormRequest→DTO arch test" migration recipe. **Versioning: backward-compatible MINOR** (new optional parameter, default empty ⇒ zero new errors in existing consumers — NOT a candidate-major; the default-empty list means no consumer sees behaviour change until it opts in). Proposed release: **v0.6.0**. +- `EnforceFormRequestToDtoRule` — new optional `formRequestToDtoExemptClasses` PHPStan parameter (default `[]`): a list of fully-qualified class names to exempt from the `toDto()` contract, matched by **exact FQCN**. This is the class-keyed alternative to the existing per-file `phpstan.neon` `ignoreErrors` suppression path (identifier + `path` keyed) — predictable across file moves and, crucially, it ports a retiring local FormRequest→DTO Pest arch test's FQCN exemption list into package config 1:1. Wired through `extension.neon` (`formRequestToDtoExemptClasses: []` parameter + `listOf(string())` schema + `exemptClasses: %formRequestToDtoExemptClasses%` on the rule's service registration), mirroring the `formRequestBaseClass` precedent. No class name is ever hardcoded in the rule body — a consumer-supplied FQCN list is *config*, not a rule-body literal, so the package's "never by name inside the rule" convention is preserved. Seed: war-room enforcement queue #131 — `EnforceFormRequestToDtoRule` now duplicates territory-local `FormRequestsTest` arch tests (entreezuil first live case, PR #274), enforcing the same invariant twice with two exemption ledgers to keep in sync; the class-keyed param lets a territory retire its local arch test and consolidate its exempt list into package config (that retirement is a separate follow-up, not this change). README documents the param + a "Retiring a local FormRequest→DTO arch test" migration recipe. **Versioning: backward-compatible MINOR** (new optional parameter, default empty ⇒ zero new errors in existing consumers — NOT a candidate-major; the default-empty list means no consumer sees behaviour change until it opts in). Released as **v0.6.0**. ## [0.5.0] — 2026-06-25 @@ -104,7 +108,8 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and - Test coverage is smoke-level for v0.1.0; full matrix for `EnforceActionTransactionsRule` (non-DB property exclusions, nested closure transaction detection, full 18-method write list) lands in a follow-up. - Action namespace assumption: rules that scope to Actions match `App\Actions\*`. Lift to a parameter when a non-conforming territory onboards. -[Unreleased]: https://github.com/script-development/phpstan-warroom-rules/compare/v0.5.0...HEAD +[Unreleased]: https://github.com/script-development/phpstan-warroom-rules/compare/v0.6.0...HEAD +[0.6.0]: https://github.com/script-development/phpstan-warroom-rules/releases/tag/v0.6.0 [0.5.0]: https://github.com/script-development/phpstan-warroom-rules/releases/tag/v0.5.0 [0.4.0]: https://github.com/script-development/phpstan-warroom-rules/releases/tag/v0.4.0 [0.3.0]: https://github.com/script-development/phpstan-warroom-rules/releases/tag/v0.3.0 diff --git a/README.md b/README.md index 06f339b..b0a6cd7 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ A consumer-supplied FQCN list is *config*, not a rule-body literal — the "neve #### Retiring a local FormRequest→DTO arch test -Where a territory already enforces "every concrete FormRequest exposes `toDto()`" via a local Pest arch test (e.g. entreezuil's `tests/Arch/FormRequestsTest.php`), this rule now duplicates that invariant. To retire the local test cleanly: +Where a territory already enforces "every concrete FormRequest exposes `toDto()`" via a local Pest arch test (e.g. entreezuil's `backend/tests/Architecture/FormRequestsTest.php`), this rule now duplicates that invariant. To retire the local test cleanly: 1. Move the arch test's exempt-class list into `formRequestToDtoExemptClasses` as FQCNs. For entreezuil that is: ```neon