fix(validation): re-key cross-field rules onto a named field so forms show inline messages #262

Merged
nrupard merged 1 commit from fix/pms-364-cross-field-validation-field-key into main 2026-06-16 17:37:37 +02:00
Owner

validator-crate keys every #[validate(schema(...))] (cross-field) error under its special __all__ bucket. The client cannot bind __all__ to a form field, so a cross-field failure such as a contract's end_date < start_date degraded to the generic "Validation failed: one or more fields are invalid" banner with no indication of which field or rule was at fault.

Add utils::validation::cross_field_error(code, field, message) which records the target form field as a field param on the ValidationError, and teach From<ValidationErrors> for AppError to re-key any __all__ error carrying that param onto the named field. The form then renders the message inline exactly like a single-field error. Ordinary single-field errors carry no such param and keep their own key, so the phone-validator pattern is unchanged.

Apply the helper to all three existing cross-field rules surfaced by the audit: contract date range (-> end_date), invoice date range (-> due_date), and SLA target range (-> first_response_hours).

#PMS-364

validator-crate keys every #[validate(schema(...))] (cross-field) error under its special `__all__` bucket. The client cannot bind `__all__` to a form field, so a cross-field failure such as a contract's end_date < start_date degraded to the generic "Validation failed: one or more fields are invalid" banner with no indication of which field or rule was at fault. Add `utils::validation::cross_field_error(code, field, message)` which records the target form field as a `field` param on the ValidationError, and teach `From<ValidationErrors> for AppError` to re-key any `__all__` error carrying that param onto the named field. The form then renders the message inline exactly like a single-field error. Ordinary single-field errors carry no such param and keep their own key, so the phone-validator pattern is unchanged. Apply the helper to all three existing cross-field rules surfaced by the audit: contract date range (-> end_date), invoice date range (-> due_date), and SLA target range (-> first_response_hours). #PMS-364
fix(validation): re-key cross-field rules onto a named field so forms show inline messages
All checks were successful
E2E / Playwright against staging (pull_request) Successful in 57s
Check / fmt + clippy + compile + unit/doc tests (pull_request) Successful in 1m4s
Integration / integration tests (pull_request) Successful in 5m26s
Create release / Create release from merged PR (pull_request) Has been skipped
064c8dfc62
validator-crate keys every #[validate(schema(...))] (cross-field) error under its special `__all__` bucket. The client cannot bind `__all__` to a form field, so a cross-field failure such as a contract's end_date < start_date degraded to the generic "Validation failed: one or more fields are invalid" banner with no indication of which field or rule was at fault.

Add `utils::validation::cross_field_error(code, field, message)` which records the target form field as a `field` param on the ValidationError, and teach `From<ValidationErrors> for AppError` to re-key any `__all__` error carrying that param onto the named field. The form then renders the message inline exactly like a single-field error. Ordinary single-field errors carry no such param and keep their own key, so the phone-validator pattern is unchanged.

Apply the helper to all three existing cross-field rules surfaced by the audit: contract date range (-> end_date), invoice date range (-> due_date), and SLA target range (-> first_response_hours).

#PMS-364
nrupard deleted branch fix/pms-364-cross-field-validation-field-key 2026-06-16 17:37:38 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
psa-systems/mokosh-server!262
No description provided.