bd-attribute
better-data: Adding a new attribute
For library maintainers introducing a new declarative hint that DTO authors will place on constructor parameters / properties — #[ArrayOf], #[Default], #[ListOf]-style markers, domain-specific decorators. The attribute itself is just a data carrier; the work is wiring it into every engine that reads attributes, because partial wiring silently degrades.
Misconception this skill corrects
"I'll add
src/Attribute/Foo.phpand read it inPostSink— done."
Attributes are read by multiple engines, and missing one leaves a feature that works on a happy path and fails subtly elsewhere. The original encrypt flag was meta-only; when options needed the same semantics, the partial wiring left a footgun until #[Encrypted] replaced it across OptionSink, PostSink, AttributeDrivenHydrator, RestSchemaBuilder, and Presenter — all in one go.
The engines that read attributes today, all need to know about a new attribute relevant to their concern:
- Read-side hydration:
AttributeDrivenHydrator(src/Internal/AttributeDrivenHydrator.php) andDataObject::coerceParameter(src/DataObject.php:168). - Write-side projection:
SinkProjection::prepareValue(src/Internal/SinkProjection.php:193) andOptionSink::projectForStorage(src/Sink/OptionSink.php:119). - REST / OpenAPI schema:
RestSchemaBuilder::buildProperty(src/Internal/RestSchemaBuilder.php). - Output / display:
Presenter::sensitiveFieldNamesand friends in src/Presenter/Presenter.php.
If your attribute is a write-time concern (encryption, formatting, slashing), all four still need to coordinate — read-side has to invert what write-side did.