fix(contracts): surface server-side end_date field errors inline #228

Merged
nrupard merged 1 commit from fix/PMS-364-inline-cross-field-errors into main 2026-06-16 17:39:54 +02:00
Owner

What

Companion to the PMS-364 server change (which re-keyed cross-field validation errors off validator-crate's __all__ bucket onto a named field). This wires the contract form to consume that named field: the submit handler keeps the ApiError through to the result match and routes field_message("end_date") into the existing inline end_err signal, falling back to the top-of-form banner only for errors without a field target.

Honest framing (important)

The canonical end < start case is already caught client-side on current main by the MAPPS-211 inline validation (contracts.rs cross-field check sets end_err and blocks submit), so it never reaches the server today. The external review that filed PMS-364 (2026-06-14) predates MAPPS-211.

This change is therefore defense-in-depth, not a fix for a currently-reproducing bug. It completes the PMS-364 server/client contract: any server-origin end_date field error (a future cross-field rule, or a case where client and server validation diverge) now renders inline under the field instead of degrading to a generic banner.

No regression

Errors not keyed end_date, and all single-field errors, still route to the banner exactly as before. The form's client-side validation continues to handle the common cases pre-submit.

Companion-form audit (server diff re-keyed three rules)

Rule Field Surface today After
Contract date range end_date already inline via MAPPS-211 client validation inline + server fallback inline (this PR)
Invoice date range due_date already inline via client validation (billing.rs due < invoice_date) unchanged; server error normally unreachable
SLA target range first_response_hours toast via push_api_error -> user_message(), now carrying the specific re-keyed message unchanged; compact row editor has no per-field inline slot, toast is the alert surface

The issue allows an inline message OR a clearly-worded alert; the SLA toast and invoice/contract inline messages both satisfy that.

Verification

  • cargo fmt --all
  • cargo clippy --target wasm32-unknown-unknown -- -D warnings clean
  • Compiles to wasm32-unknown-unknown

🤖 Generated with Claude Code

## What Companion to the PMS-364 server change (which re-keyed cross-field validation errors off validator-crate's `__all__` bucket onto a named field). This wires the contract form to consume that named field: the submit handler keeps the `ApiError` through to the result match and routes `field_message("end_date")` into the existing inline `end_err` signal, falling back to the top-of-form banner only for errors without a field target. ## Honest framing (important) The canonical `end < start` case is **already caught client-side** on current `main` by the MAPPS-211 inline validation (`contracts.rs` cross-field check sets `end_err` and blocks submit), so it never reaches the server today. The external review that filed PMS-364 (2026-06-14) predates MAPPS-211. This change is therefore **defense-in-depth**, not a fix for a currently-reproducing bug. It completes the PMS-364 server/client contract: any server-origin `end_date` field error (a future cross-field rule, or a case where client and server validation diverge) now renders inline under the field instead of degrading to a generic banner. ## No regression Errors not keyed `end_date`, and all single-field errors, still route to the banner exactly as before. The form's client-side validation continues to handle the common cases pre-submit. ## Companion-form audit (server diff re-keyed three rules) | Rule | Field | Surface today | After | |---|---|---|---| | Contract date range | `end_date` | already inline via MAPPS-211 client validation | inline + server fallback inline (this PR) | | Invoice date range | `due_date` | already inline via client validation (`billing.rs` due < invoice_date) | unchanged; server error normally unreachable | | SLA target range | `first_response_hours` | toast via `push_api_error` -> `user_message()`, now carrying the specific re-keyed message | unchanged; compact row editor has no per-field inline slot, toast is the alert surface | The issue allows an inline message OR a clearly-worded alert; the SLA toast and invoice/contract inline messages both satisfy that. ## Verification - `cargo fmt --all` - `cargo clippy --target wasm32-unknown-unknown -- -D warnings` clean - Compiles to wasm32-unknown-unknown 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(contracts): surface server-side end_date field errors inline
All checks were successful
Create release / Create release from merged PR (pull_request) Has been skipped
Check / clippy + fmt + tests (pull_request) Successful in 1m2s
a83b5abba0
PMS-364 re-keyed the server's cross-field date rule onto a named field (`end_date`) so forms can render it inline instead of as a generic banner. This wires the contract form to consume that: the submit handler now keeps the `ApiError` through to the result match and routes `field_message("end_date")` into the existing inline `end_err` signal, falling back to the top-of-form banner only for errors without a field target.

Scope and honest framing:

- The canonical end < start case is already caught client-side by the MAPPS-211 inline validation (`contracts.rs` cross-field check sets `end_err` and blocks submit), so on current `main` it never reaches the server. The external review that filed PMS-364 predates MAPPS-211.
- This change is defense-in-depth that completes the PMS-364 server/client contract: any server-origin `end_date` field error (a future cross-field rule, or a case where client and server validation diverge) now lands inline under the field instead of degrading to a generic banner. It is robustness, not a fix for a currently-reproducing bug.
- No regression: errors not keyed `end_date` (and all single-field errors) still route to the banner exactly as before; the form's client-side validation handles the common cases pre-submit.

Companion-form audit (server diff re-keyed three rules):

- Contract `end_date`: handled here; also already inline via MAPPS-211 client validation.
- Invoice `due_date`: already shows a specific inline message via client-side validation (`billing.rs` due < invoice_date check), so the server error is normally unreachable and already satisfied.
- SLA target `first_response_hours`: the row editor surfaces server errors as a toast via `push_api_error` -> `user_message()`, which now carries the specific re-keyed message. The compact table-row form has no per-field inline slot, so the toast is the alert surface (the issue allows an inline message OR a clearly-worded alert).

#PMS-364

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
nrupard deleted branch fix/PMS-364-inline-cross-field-errors 2026-06-16 17:39:54 +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-apps!228
No description provided.