fix(contracts): surface server-side end_date field errors inline #228
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/PMS-364-inline-cross-field-errors"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
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 theApiErrorthrough to the result match and routesfield_message("end_date")into the existing inlineend_errsignal, falling back to the top-of-form banner only for errors without a field target.Honest framing (important)
The canonical
end < startcase is already caught client-side on currentmainby the MAPPS-211 inline validation (contracts.rscross-field check setsend_errand 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_datefield 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)
end_datedue_datebilling.rsdue < invoice_date)first_response_hourspush_api_error->user_message(), now carrying the specific re-keyed messageThe issue allows an inline message OR a clearly-worded alert; the SLA toast and invoice/contract inline messages both satisfy that.
Verification
cargo fmt --allcargo clippy --target wasm32-unknown-unknown -- -D warningsclean🤖 Generated with Claude Code
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>