All updates
QAFrontend

Grid filter input hardening and async bulk document updates (QA)

PR #1070pixbox-supportJun 19, 2026 · 18:14 UTC
QAJun 19, 2026

Executive summary

This release promotes two frontend changes to QA: numeric grid-filter inputs (mail and admin) now reject characters that produced confusing or wrong filter values, and the document grid now correctly recognizes when a bulk update is processed in the background instead of treating it as instantly finished. No new end-user features; this is a quality and correctness pass on existing grid filtering and bulk-edit flows.

Why this was needed

QA reported that the Batches Overview "Total Mails" filter accepted invalid input. A native numeric input allows scientific notation (e/E) and signs (+/-): typing a lone e left a stray character visible while the value read empty (looked broken), and 12e5 was silently treated as 1,200,000 — a value the user never intended. Separately, the backend moved document bulk updates to a set-based engine that can return 202 Accepted and finish the work in a background job; the frontend was treating that as a completed synchronous update, so grids could refresh before the job actually finished.

Client / user impact

  • Count/numeric column filters in the mail and admin grids only accept valid digits (and a single decimal for float columns), so filtered results match what the user typed.
  • The broken-looking "stray character" state on filter inputs is eliminated.
  • Bulk document edits that the backend runs asynchronously no longer trigger a premature grid refresh; results are picked up when the job completes, reducing stale or empty views after a large edit.

Technical scope

Batch promotes devqa (9 commits across 2 PRs).

#1069 — Numeric grid-filter input guards

  • New shared module packages/ui/src/grid-filters/numeric-input-guards.ts exporting isDisallowedNumericKey, handleNumericKeyDown, handleNumericPaste (re-exported from grid-filters/index.ts).
  • Keydown blocks e/E/+/- (and . on integer columns) while leaving editing/navigation keys and Ctrl/Cmd/Alt shortcuts intact; float columns reject a second decimal via a selection-aware check wrapped in try/catch for the Chrome type="number" selection DOMException.
  • Paste is whitelist-validated (INTEGER_PASTE_PATTERN/FLOAT_PASTE_PATTERN).
  • Guards wired (memoized) into both apps/mail and apps/admin column-filter-popover.tsx; existing sanitizeNumericFilterBound clamping unchanged.

#1068 — Async document bulk updates

  • isBulkJobAccepted moved to types/bulk-operations.types.ts (re-exported from mail.services.ts for back-compat); BulkMailJobAcceptedResponse renamed to BulkJobAcceptedResponse (legacy alias kept) with new queued_count/async/operation fields.
  • Document mutation onSuccess handlers now skip query invalidation when the response is an accepted async job.
  • document.services.ts update methods now return a sync-or-async union type; added DocumentBulkUpdatePhase and nullable failed_details to websocket.types.ts.
  • Hardened document-type list updates in two metadata views with Array.isArray + type-guard filter before mapping.

Risk & mitigation

Low to moderate, scoped to grids and bulk edits. The filter guards are additive and could in theory block a legitimate keystroke, but named/navigation keys and clipboard shortcuts are explicitly preserved and value clamping is unchanged. The async-update change depends on the backend's 202/queued contract; if the backend returns an unexpected shape, the type guard's fallbacks (status optional, count fallbacks) reduce the chance of misclassification. Mitigation: validate against the live QA backend and confirm grid refresh on job completion. Note: Batches Overview column sorting is a separate backend issue (DSM_Backend#202) and is not addressed here.

QA validation focus

  • Mail and admin grid numeric filters: confirm e, E, +, - are rejected by typing and by paste; integer columns reject ., float columns allow exactly one ..
  • Select-all then type/paste a new decimal in a float filter should be accepted; pasting letters/symbols/scientific notation should be rejected.
  • Verify filtered results match the entered value (no silent 12e5 -> 1,200,000).
  • Bulk document update / status change on a large selection: confirm the success toast, that the grid does not refresh prematurely, and that it updates once the background job completes.
  • Test in Chrome specifically (selection DOMException path) and at least one other browser.