Skip to content

Commit cb62621

Browse files
committed
docs(roadmap): document open path encoding decision before v1.0
Record the lossy dotted-string path tradeoffs and two acceptable resolutions (segment storage vs documented limitation) so the contract is decided before freeze
1 parent 6c52965 commit cb62621

1 file changed

Lines changed: 1 addition & 0 deletions

File tree

ROADMAP.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ One unified design covering three things that share the same error object. The s
2525
- **Full error paths** for nested structures (`user.address.street`) instead of bare leaf keys.
2626
- **Message placeholders** (`{value}`, `{index}`, `{min}`, …) for custom messages and localization; pair with global/default message templates for consistent branding.
2727
- Expose the errors through a single accessor, `ValidationException::getErrors(?string $path = null)`, returning the `ValidationError` value objects (a flat list; an optional path filters to one field and its subtree). The legacy nested-message view and the separate flattened helpers were dropped in favor of this one method. _(Landed; `ValidationError` is `JsonSerializable`.)_
28+
- **Open decision — path encoding (revisit before v1.0).** `ValidationError` stores the path as a dotted string, built by string concatenation in `withPathPrefix()`. That encoding is lossy: a literal key containing a dot (`'user.name'`) is indistinguishable from nesting, an empty-string schema key composes a leading-dot path (`.hidden`, special-cased in the `getErrors('')` guard), and `items.0.name` cannot distinguish array index `0` from string key `'0'`. Zod keeps a segment array (`['user', 'name']`) as the source of truth and derives the string view; we do the inverse, so segments are unrecoverable and a future `getSegments()` could never be correct for dotted keys. Two acceptable resolutions, decide one before freezing the contract: (a) store `array $segments` internally, prepend segments in `withPathPrefix()`, keep `getPath()` returning the dot-joined string unchanged — public API identical, filtering becomes exact, leaves room for an additive `getSegments()` post-1.0; or (b) declare literal dotted keys out of scope for a form/API validator and document the limitation (`llms.txt`). The dotted-string _view_ stays the primary API either way (it maps onto HTML input names, Laravel/Symfony error keys, and JS property access); the decision is only about what is stored underneath.
2829

2930
### 2. Deprecation cleanup
3031

0 commit comments

Comments
 (0)